orangepi吧 关注:341贴子:551
  • 8回复贴,共1

OrangePI PC2 CSI摄像头使用、编程踩坑手册

只看楼主收藏回复

OrangePIPC2不知不觉就买回来快3年,在这段时间里Opi主要用作开爬虫程序和程序测试。最近买嵌入式摄像头的时候,发现店家有售卖Opi摄像头(当然是200万像素的gc2035),于是18元买个回来玩玩,在摸索的过程中发现,在Opi上使用其CSI摄像头坑还真不少。
3年过去了,其官方的Linux驱动还是BUG满天飞,于是写此帖让大家在Opi上用摄像头时有个参考,而本帖内的程序可到个人的github下载,一个带有Gtk界面的摄像头测试程序和一个用摄像头拍照的参考程序,也可以用于常规的Usb摄像头或v4l2驱动的摄像设备。
以下内容都是在官方的linux镜像下进行,若你是使用Armbian或其它常规发行版的Linux可以略过本文。

MyCamera:https://github.com/macos2/MyCamera
https://gitee.com/macos2/MyCamera

OrangePi-CSI-Camera-Demo:https://github.com/macos2/OrangePi-CSI-Camera-Demo
https://gitee.com/macos2/OrangePi-CSI-Camera-Demo


1楼2020-01-18 12:02回复
    首先OrangePi的官方Linux镜像很久没有更新了,我选择了其Debian(Ubuntu也可以,设置多一点)的桌面镜像,镜像还停留在Debian8jessie时代,还好Debian跨代升级还挺方便,只要修改/etc/apt/sources.list,将其“jessie”的版号替换要升级的版号就可以了(如当前Debian10 版号是buster),如下图(本人选择163的国内源),然后执行”sudoapt update”,”sudo apt upgrade”,按提示操作,便可完成跨代升级。


    可不可以不更新?当然可以,但你要找到可用可靠apt软件源,Debian8的可靠的软件源在国内基本上已经没有了,只能到国外官网找,而且速度慢,若遇GFW还无法访问。


    2楼2020-01-18 12:05
    回复
      广告
      立即查看
      开始的使用摄像头时候,我使用GStreamer和Cheese茄子摄像测试摄像头的,发现其不能工作。在打算放弃之际,奇迹地发现OrangePiPC2使用手册内介绍motion却能正常使用摄像头。
      在GitHub上研究其代码,究其原因是其内核驱动Sunxi-vfe默认的设置摄像头V4L2接口的input通道为”-1”,所有无法使用。
      所以使用GStreamer开发的软件,在OrangePi官方镜像里是无法直接使用其CSI摄像头,因为其打开V4L2设备时,没有枚举、选择V4L2input通道这个环节(“gst-inspect-1.0v4l2src”内也没有相关设置)。
      但你可以通过v4l2loopback和vidcopy把摄像头数据重定向某个虚拟设备,从而可以让GStreamer等软件通过该虚拟设备正常工作,但不能切换工作的分辨率,具体步骤参考:https://diyprojects.io/orange-pi-armbian-control-camera-python-opencv/#.XhQBdaZS-uV。


      3楼2020-01-18 12:06
      回复
        V4L2程序编写踩坑
        在官镜像下用v4l2库开发摄像头软件时要主要以下几点。
        1、只单独安装V4L2的开发包(如:libv4l-dev),你会发现程序怎么写都无法使用摄像头。如果你安装motion(及依赖),程序便工作正常了,这是因为安装motion时,Debian才会把V4L2其余依赖包安装好,所以安装V4L2的开发包还要装上motion,不管你用不用motion,至少V4L2这样才会正常工作(或安装好所有运行依赖,x86架构没有这个问题)。
        2、V4L2头文件内的v4l2_open、v4l2_ioctl...等函数,不能与系统的open、ioctl...混用,单独使用系统的open、ioctl...兼容性更好。例如用v4l2_open打开设备,用系统ioctl设置摄像头参数等,不信的可以自己试试会有什么后果(可能会出现写坏系统分区的情况)。
        3、在枚举设备的输出格式(pix_format)时会发现其可以输出很多格式,其实gc2035的输出格式能用的只有YU12、YV12、UYVY(某歪果仁测试过)。即便是个人用VIDIOC_S_FMT设置了422P,其输出的格式依旧默认是YU12,其原因在于枚举输出格式时,枚举的是sunxi-vfe设备支持的格式,枚举的过程只在sunxi-vfe内部进行,并没有跟摄像头进行实际访问操作,不是摄像头输出的格式。
        4、V4L2请求内存有V4L2_MEMORY_MMAP和V4L2_MEMORY_USERPTR(另一个V4L2_MEMORY_DMABUF用于下一级设备使用,如图像转换设备等,个人还没有用过)。
        但V4L2_MEMORY_USERPTR虽然VIDIOC_REQBUFS成功,但不论怎样malloc、calloc分配内存都无法VIDIOC_QBUF入队,这是因为内核Sunxi-vfe是使用Sunxi-ion管理内存(android的内存管理机制,要知道全志H5是面向Android电视盒开发出来的),如果要用V4L2_MEMORY_USERPTR,你可能要用Sunxi-ion相关用户层函数分配的内存才能VIDIOC_QBUF入队使用。
        而V4L2_MEMORY_MMAP稍微好一点,摄像头拍800x600的图像还没有问题(但reqbus时count数量不能太多),但拍1600x1200就不行了,当你设置1600x1200规格后再VIDIOC_REQBUFS时,不论怎样设置都只会返回“无效参数”等错误,但你通过在终端“dmesg”查看内核日志,你会发现Sunxi-ion驱动提示无法分配内存。这是因为官方内核预留contimuousallocation内存(连续性分配内存)较小的原因,解决也很简单,只要在启动的内核的参数上加上“cma=xxxM”就可以了,把预留contimuousallocation分配多点问题就解决了,详细可到http://linux-sunxi.org/Kernel_arguments了解。
        在V4L2_MEMORY_MMAP需增大预留的连续性分配内存,才能使用1600x1200分辨率进行拍摄,即修改boot的分区下uEnv.txt文件,”console=tty0console=ttyS0,115200n8 no_console_suspend“字段后加上cma=xxxM,设置连续性分配内存为xxxM,增大预留的连续性内存(系统默认预留96M,128M基本满足需求,图中本人分配了160M)。

        图示 :把预留连续性内存加大
        5、VIDIOC_DQBUF出队的v4l2_buffer,v4l2_buffer.m.offset所映射的内容只能用memcpy复制到其它地方(或用fwrite全部写进文件),且一次性访问。多次访问或把它传递到其它函数处理会引发不可料的问题,尤其在系统刚刚启动,Sunxi-vfe还没有初始化的时候问题更为突出。
        6、在V4L2_MEMORY_MMAP模式下要munmap解除内存映射时,要先VIDIOC_STREAMOFF,后munmap,否则程序结束后,系统运行会出现奇怪的运行问题。


        4楼2020-01-18 12:09
        回复
          在OrangePiPC2用摄像头拍摄的画面,800x600还算不错,但到了1600x1200就非常暗了(白天几乎变成了黑夜),这是摄像头gc2035的驱动作者有意为之,究竟为什么我也不清楚,但可以通过软件图像叠加等算法获取质量高点的图像。
          本人拍摄的fps一直都比较低(10~8fps),查看gc2035的驱动,可看到800x600可以上30fps,而1600x1200则8fps,可能原因是程序没有硬解所致吧。

          800x600

          1600x1200


          5楼2020-01-18 12:09
          回复
            最后究竟用OrangePi的CSI摄像头干什么呢?如果用800x600拍个照、录制视频还可以,而在1600x1200下基本没有什么可以之处了,除非你有时间搞叠加算法。
            用来学习使用还是不错的,18元的摄像头你还强求什么单反画质,至少可以满足opencv图像分析的需求。
            如果你不想受这种那种折磨,花多一点钱买个USB摄像头吧,使用范围更广,其次驱动更加完善稳健,可在主线的Linux内核使用,只是响应稍慢,毕竟中间是通过usb传输,而不是通过CSI直接读入系统内部。


            6楼2020-01-18 12:13
            回复
              这个帖子有干货!回头试试看


              IP属地:海南7楼2020-03-15 22:09
              收起回复
                mark


                IP属地:广东8楼2020-11-25 13:12
                回复