本文经过拜读师兄一路调bug的实验过程,深知入门不易,在这接着总结一些嵌入式配置opencv等的大致思路。同时对摄像头读取操作和QT中opencv处理作详细的记录。
附上其文章,建议常读:i.MX6开发板 嵌入式linux开发
上面笔记记录一些嵌入式内核配置opencv的过程,同时简述opencv+qt在嵌入式内核中运行的配置;
一、思路
1. ARM+Qte的配置
本次实验的ARM板子是IMX6开发板,烧写uboot及linux内核加qt4.7的系统,具体的烧写过程这里不阐述。配置见相关文档,当然也可以自己编译。
用usb烧写完上述系统之后配置相关显示模式即可。当然为了便于显示自己编写的qt程序,可以修改相关的启动文件,使得默认开机启动的程序是特定的程序或者不自启动。
vi /etc/init.d/rcS
配置完成之后可以随时用超级终端复制相应的qt程序到开发板中运行。
2. Ubuntu虚拟机上qt程序的编写编译
需要在Ubuntu上配置好和开发板相同的编译器arm-linux-gcc-4.3.2,同时在qtcreator上配置相应的编译器arm-linux-gcc-4.3.2(直接在终端make也行),这样生成的可执行文件才能够复制到ARM开发板中运行。需要注意的是,在开发板中运行的qte系统是qt4.7,所以在qtcreator中编译时也需要选择qt4.7。
3. opencv的源码编译以及环境配置
在Ubuntu虚拟机中编译opencv2源码并复制到ARM中:
想要在ARM开发板上运行opencv开源库相关的程序,需要先在Ubuntu虚拟机上用与ARM相同的编译器arm-linux-gcc-4.3.2编译opencv源码,得到的.so文件复制到开发板上的/lib目录。具体的编译过程和对make需要设置的东西在其他博客中有提及,需要对makefile文件做一定的修改。opencv的版本不能过高,否则编译器无法完成编译。
关于ARM开发板那种的opencv编译完成之后的.so文件存放的目录,这一点需要根据对opencv编译时的设置有关,如果配置生成了相应的pkgconfig环境变量,则可以根据所填写的目录将lib中的.so文件复制到相应的目录,如果嫌麻烦,直接复制到./lib即可运行。
由于前面师兄的工作,只需要:
1.将opencv库编译后的文件(包含include、lib/*.so文件等)复制到Ubuntu虚拟机的usr/local...相关目录
2.将opencv库编译后的lib文件中的.so复制到arm开发板的lib目录
3.在Ubuntu虚拟机上编写qt程序时将相关的库路径以及lib路径写入.pro文件中
即可完成在Ubuntu虚拟机的Qtcreator中编写opencv相关的qt程序,然后用arm-linux-gcc-4.3.2+qt4.7编译得到的可执行文件(无法在Ubuntu虚拟机中运行),然后将debug中的可执行文件复制到arm开发板中运行,即可完成在arm开发板中运行opencv相关的qt程序。
4. ARM中实现opencv调用问题
调用opencv会遇到两个问题
1. Linux中无法直接调用摄像头
2. 无法使用opencv的img.show()函数
解决思路:
1. opencv无法直接调用摄像头时,需要调用linux内核中摄像头V4L2驱动,进行一定图像格式转换之后才能够被opencv调用,具体的调用和转换细节参考师兄的博客(太大佬了),在这个过程中需要读取和配置摄像头的一些参数。
2. show()函数无法调用和其实现方式有关,简单来讲是ARM中的linux内核无法提供相关的KDE桌面环境,这里有两种解决思路,配置KDE相关的环境或者将图像转换成qt中img显示相关的格式并且用其控件显示。既然已经用了qt,显然在qt中作迂回会比较低风险。
二、ARM中v4l2配置
1. v4l2处理过程--获取设备信息
v4l2的命令码:v4l2 编程接口(一) — ioctl
定义的一些格式结构的解释
struct v4l2_buffer enqueue , dequeue ; //定义出入队的操作结构体成员 v4l2_capability cap; /* 查询打开的设备是否属于摄像头:设备video不一定是摄像头*/ format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE ;//定义v4l2的处理格式 format.fmt.pix.width = Width; format.fmt.pix.height = Hight; format.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV ; //摄像头支持的格式
打开并获取设备信息
fd= open(videodevname , O_RDWR);//打开摄像头,将文件描述符传给fd ret = ioctl(fd, VIDIOC_QUERYCAP, &cap);//获取设备信息
VIDIOC_QUERYCAP定义
VIDIOC_QUERYCAP 命令通过结构 v4l2_capability 获取设备支持的操作模式:
struct v4l2_capability {
__u8 driver[16]; /* i.e. "bttv" */
__u8 card[32]; /* i.e. "Hauppauge WinTV" */
__u8 bus_info[