(原创)基于ZedBoard的Webcam设计(一):USB摄像头(V4L2接口)的图片采集
2012-12-19 15:45
639 查看
一直想把USB摄像头接到Zedboard上,搭建一个简易视频监控系统方便后续做视频处理。Xilinx官方给出了一个Webcam摄像头监控的例子,跑的是linaro,不知道是我的SD卡问题还是摄像头的问题,播放视频的时候总是会很卡,而且突然系统就死掉了。还是很喜欢自己动手,能学到新东西。Digilent官方给的OOB设计,那个精简的linux足够做简单的linux开发了,而且OOB设计中USB驱动和V4L(Video for Linux)都提供好了。这几天找了一些的V4L的资料,完成了摄像头的单帧图片采集,接下来要做的是QT界面显示和视频流的显示了,最终的计划是完成视频采集、编码、存储和以太网传输。希望能有时间和精力完成这么多。先把这几天的做的东西整理出来和大家分享。为了方便大家对程序的理解,先简单介绍一下linux下的V4L2的一些知识,然后再详细介绍V4L2编程。
更多更新请关注我的博客:@超群天晴 http://www.cnblogs.com/surpassal/
相关阅读 :
(原创)基于ZedBoard的Webcam设计(一):USB摄像头(V4L2接口)的图片采集
(原创)基于ZedBoard的Webcam设计(二):USB摄像头图片采集+QT显示
(原创)基于ZedBoard的Webcam设计(三):视频的采集和动态显示
(原创)基于ZedBoard的Webcam设计(四):MJPG编码和AVI封装
(原创)基于ZedBoard的Webcam设计(五):x264编码在zedboard上的实现(软编码)
硬件平台:Digilent ZedBoard + USB 摄像头
开发环境:Windows XP 32 bit + Wmare 8.0 + Ubuntu 10.04 + arm-linux-xilinx-gnueabi交叉编译环境
Zedboard linux: Digilent OOB Design
一、一些知识
1、V4L和V4L2。
V4L是Linux环境下开发视频采集设备驱动程序的一套规范(API),它为驱动程序的编写提供统一的接口,并将所有的视频采集设备的驱动程序都纳入其的管理之中。V4L不仅给驱动程序编写者带来极大的方便,同时也方便了应用程序的编写和移植。V4L2是V4L的升级版,由于我们使用的OOB是3.3的内核,不再支持V4L,因而编程不再考虑V4L的api和参数定义。
2、YUYV与RGB24
RGB是一种颜色的表示法,计算机中一般采用24位来存储,每个颜色占8位。YUV也是一种颜色空间,为什么要出现YUV,主要有两个原因,一个是为了让彩色信号兼容黑白电视机,另外一个原因是为了减少传输的带宽。YUV中,Y表示亮度,U和V表示色度,总之它是将RGB信号进行了一种处理,根据人对亮度更敏感些,增加亮度的信号,减少颜色的信号,以这样“欺骗”人的眼睛的手段来节省空间。YUV到RGB颜色空间转换关系是:
YUV的格式也很多,不过常见的就是422、420等。YUYV就是422形式,简单来说就是,两个像素点P1、P2本应该有Y1、U1、V1和Y2、U2、V2这六个分量,但是实际只保留Y1、U1、Y2、V2。
View Code
4、停止采集和关闭设备
使用命令VIDIOC_STREAMOFF停止视频采集,并关闭设备。
5、主函数
需要把我们采集到图像数据存储成图片,为了方便调试,先将原始的数据存储为yuv格式文件,再将转换成RGB后的数据存储为BMP。定义BMP头结构体
完整的主函数
三、PC测试
程序编写完后,可以先在PC上做测试(实际整个调试过程都是在PC上,直道最后PC上能实现功能再挪到ZedBoard上的)。PC上测试的结果
在/usr目录下可以查看到采集到的图片
四、Zedboard测试
PC上测试OK后,可以“挪”到ZedBoard上了。使用arm-xilinx-linux交叉编译环境对源文件进行交叉编译,将生成的可执行文件拷贝到ZedBoard上运行即可。
使用命令
对程序进行编译,编译通过后将生成的可执行文件zed-camera拷贝到到ZedBoard上,并将USB摄像头连接到ZedBoard上,通过命令
查看dev目录下的是否有video0设备。如果有,可以运行可执行文件了。在运行前我比较习惯获得可执行文件的权限,使用命令
参数+x的意思是这个文件对于当前用户是可执行的。也可以使用
这样所有用户都有读写执行的权限。使用命令
执行可执行程序,程序运行,并输出以下信息:
可以看到我使用的USB摄像支持YUYV和MJPEG两种格式。我也试过其他USB摄像头,大部分都只支持YUYV而不支持MJPEG或者RGB24。
采集到的图片默认是在/usr目录下的,将其拷贝出来
再PC上查看,效果还不错
=============================
完整工程和代码:lab_v4l2_yuyv.zip
可以指定任意分辨率摄像头的代码:v4l2grab_Anysize.rar 《感谢@jiaquwang分享》
更多更新请关注我的博客:@超群天晴 http://www.cnblogs.com/surpassal/
相关阅读 :
(原创)基于ZedBoard的Webcam设计(一):USB摄像头(V4L2接口)的图片采集
(原创)基于ZedBoard的Webcam设计(二):USB摄像头图片采集+QT显示
(原创)基于ZedBoard的Webcam设计(三):视频的采集和动态显示
(原创)基于ZedBoard的Webcam设计(四):MJPG编码和AVI封装
(原创)基于ZedBoard的Webcam设计(五):x264编码在zedboard上的实现(软编码)
硬件平台:Digilent ZedBoard + USB 摄像头
开发环境:Windows XP 32 bit + Wmare 8.0 + Ubuntu 10.04 + arm-linux-xilinx-gnueabi交叉编译环境
Zedboard linux: Digilent OOB Design
一、一些知识
1、V4L和V4L2。
V4L是Linux环境下开发视频采集设备驱动程序的一套规范(API),它为驱动程序的编写提供统一的接口,并将所有的视频采集设备的驱动程序都纳入其的管理之中。V4L不仅给驱动程序编写者带来极大的方便,同时也方便了应用程序的编写和移植。V4L2是V4L的升级版,由于我们使用的OOB是3.3的内核,不再支持V4L,因而编程不再考虑V4L的api和参数定义。
2、YUYV与RGB24
RGB是一种颜色的表示法,计算机中一般采用24位来存储,每个颜色占8位。YUV也是一种颜色空间,为什么要出现YUV,主要有两个原因,一个是为了让彩色信号兼容黑白电视机,另外一个原因是为了减少传输的带宽。YUV中,Y表示亮度,U和V表示色度,总之它是将RGB信号进行了一种处理,根据人对亮度更敏感些,增加亮度的信号,减少颜色的信号,以这样“欺骗”人的眼睛的手段来节省空间。YUV到RGB颜色空间转换关系是:
R = Y + 1.042*(V-128); G = Y - 0.34414*(U-128) - 0.71414*(V-128); B = Y + 1.772*(U-128);
YUV的格式也很多,不过常见的就是422、420等。YUYV就是422形式,简单来说就是,两个像素点P1、P2本应该有Y1、U1、V1和Y2、U2、V2这六个分量,但是实际只保留Y1、U1、Y2、V2。
View Code
int yuyv_2_rgb888(void) { int i,j; unsigned char y1,y2,u,v; int r1,g1,b1,r2,g2,b2; char * pointer; pointer = buffers[0].start; for(i=0;i<480;i++) { for(j=0;j<320;j++) { y1 = *( pointer + (i*320+j)*4); u = *( pointer + (i*320+j)*4 + 1); y2 = *( pointer + (i*320+j)*4 + 2); v = *( pointer + (i*320+j)*4 + 3); r1 = y1 + 1.042*(v-128); g1 = y1 - 0.34414*(u-128) - 0.71414*(v-128); b1 = y1 + 1.772*(u-128); r2 = y2 + 1.042*(v-128); g2 = y2 - 0.34414*(u-128) - 0.71414*(v-128); b2 = y2 + 1.772*(u-128); if(r1>255) r1 = 255; else if(r1<0) r1 = 0; if(b1>255) b1 = 255; else if(b1<0) b1 = 0; if(g1>255) g1 = 255; else if(g1<0) g1 = 0; if(r2>255) r2 = 255; else if(r2<0) r2 = 0; if(b2>255) b2 = 255; else if(b2<0) b2 = 0; if(g2>255) g2 = 255; else if(g2<0) g2 = 0; *(frame_buffer + ((480-1-i)*320+j)*6 ) = (unsigned char)b1; *(frame_buffer + ((480-1-i)*320+j)*6 + 1) = (unsigned char)g1; *(frame_buffer + ((480-1-i)*320+j)*6 + 2) = (unsigned char)r1; *(frame_buffer + ((480-1-i)*320+j)*6 + 3) = (unsigned char)b2; *(frame_buffer + ((480-1-i)*320+j)*6 + 4) = (unsigned char)g2; *(frame_buffer + ((480-1-i)*320+j)*6 + 5) = (unsigned char)r2; } } printf("change to RGB OK \n"); }
4、停止采集和关闭设备
使用命令VIDIOC_STREAMOFF停止视频采集,并关闭设备。
int close_v4l2(void) { ioctl(fd, VIDIOC_STREAMOFF, &buf_type); if(fd != -1) { close(fd); return (TRUE); } return (FALSE); }
5、主函数
需要把我们采集到图像数据存储成图片,为了方便调试,先将原始的数据存储为yuv格式文件,再将转换成RGB后的数据存储为BMP。定义BMP头结构体
typedef struct tagBITMAPFILEHEADER{ WORD bfType; // the flag of bmp, value is "BM" DWORD bfSize; // size BMP file ,unit is bytes DWORD bfReserved; // 0 DWORD bfOffBits; // must be 54 }BITMAPFILEHEADER; typedef struct tagBITMAPINFOHEADER{ DWORD biSize; // must be 0x28 DWORD biWidth; // DWORD biHeight; // WORD biPlanes; // must be 1 WORD biBitCount; // DWORD biCompression; // DWORD biSizeImage; // DWORD biXPelsPerMeter; // DWORD biYPelsPerMeter; // DWORD biClrUsed; // DWORD biClrImportant; // }BITMAPINFOHEADER;
完整的主函数
//@超群天晴 //http://www.cnblogs.com/surpassal/ int main(void) { FILE * fp1,* fp2; BITMAPFILEHEADER bf; BITMAPINFOHEADER bi; fp1 = fopen(BMP, "wb"); if(!fp1) { printf("open "BMP"error\n"); return(FALSE); } fp2 = fopen(YUV, "wb"); if(!fp2) { printf("open "YUV"error\n"); return(FALSE); } if(init_v4l2() == FALSE) { return(FALSE); } //Set BITMAPINFOHEADER bi.biSize = 40; bi.biWidth = IMAGEWIDTH; bi.biHeight = IMAGEHEIGHT; bi.biPlanes = 1; bi.biBitCount = 24; bi.biCompression = 0; bi.biSizeImage = IMAGEWIDTH*IMAGEHEIGHT*3; bi.biXPelsPerMeter = 0; bi.biYPelsPerMeter = 0; bi.biClrUsed = 0; bi.biClrImportant = 0; //Set BITMAPFILEHEADER bf.bfType = 0x4d42; bf.bfSize = 54 + bi.biSizeImage; bf.bfReserved = 0; bf.bfOffBits = 54; v4l2_grab(); fwrite(buffers[0].start, 640*480*2, 1, fp2); printf("save "YUV"OK\n"); yuyv_2_rgb888(); fwrite(&bf, 14, 1, fp1); fwrite(&bi, 40, 1, fp1); fwrite(frame_buffer, bi.biSizeImage, 1, fp1); printf("save "BMP"OK\n"); fclose(fp1); fclose(fp2); close_v4l2(); return(TRUE); }
三、PC测试
程序编写完后,可以先在PC上做测试(实际整个调试过程都是在PC上,直道最后PC上能实现功能再挪到ZedBoard上的)。PC上测试的结果
在/usr目录下可以查看到采集到的图片
四、Zedboard测试
PC上测试OK后,可以“挪”到ZedBoard上了。使用arm-xilinx-linux交叉编译环境对源文件进行交叉编译,将生成的可执行文件拷贝到ZedBoard上运行即可。
使用命令
arm-xilinx-linux-gnueabi-gcc v4l2grab.c -o zed-camera
对程序进行编译,编译通过后将生成的可执行文件zed-camera拷贝到到ZedBoard上,并将USB摄像头连接到ZedBoard上,通过命令
ls /dev
查看dev目录下的是否有video0设备。如果有,可以运行可执行文件了。在运行前我比较习惯获得可执行文件的权限,使用命令
chmod +x zed-camera
参数+x的意思是这个文件对于当前用户是可执行的。也可以使用
chmod 777 zed-camera
这样所有用户都有读写执行的权限。使用命令
./zed-camera
执行可执行程序,程序运行,并输出以下信息:
zynq> ./zed-camera [ 318.290000] usb 1-1.3: reset high-speed USB device number 3 using xusbps-ehci driver: uvcvideo card: UVC Camera (046d:0825) bus_info: usb-xusbps-ehci.0-1.3 version: 197376 capabilities: 4000001 Device /dev/video0: supports capture. Device /dev/video0: supports streaming. Support format: 1.YUV 4:2:2 (YUYV) 2.MJPEG fmt.type: 1 pix.pixelformat: YUYV pix.height: 480 pix.width: 640 pix.field: 1 init /dev/video0 [OK] grab yuyv OK save /usr/image_yuv.yuv OK change to RGB OK save /usr/image_bmp.bmp OK
可以看到我使用的USB摄像支持YUYV和MJPEG两种格式。我也试过其他USB摄像头,大部分都只支持YUYV而不支持MJPEG或者RGB24。
采集到的图片默认是在/usr目录下的,将其拷贝出来
cp /usr/image* /mnt
再PC上查看,效果还不错
=============================
完整工程和代码:lab_v4l2_yuyv.zip
可以指定任意分辨率摄像头的代码:v4l2grab_Anysize.rar 《感谢@jiaquwang分享》
相关文章推荐
- (原创)基于ZedBoard的Webcam设计(一):USB摄像头(V4L2接口)的图片采集(非常好)
- 基于ZedBoard的Webcam设计(一):USB摄像头(V4L2接口)的图片采集
- 基于ZedBoard的Webcam设计(一):USB摄像头(V4L2接口)的图片采集
- 基于ZedBoard的Webcam设计(一):USB摄像头(V4L2接口)的图片采集
- (原创)基于ZedBoard的Webcam设计(二):USB摄像头图片采集+QT显示
- 基于ZedBoard的Webcam设计(二):USB摄像头图片采集+QT显示
- 基于ZedBoard的Webcam设计(二):USB摄像头图片采集+QT显示
- 基于ZedBoard的Webcam设计(二):USB摄像头图片采集+QT显示
- zedboard--USB摄像头(V4L2接口)的图片采集(十二)
- 基于ZedBoard的Webcam设计(三):视频的采集和动态显示-----学习心得---zed上用v4l2做cam显示视频
- (原创)基于ZedBoard的Webcam设计(三):视频的采集和动态显示
- USB摄像头(V4L2接口)的图片采集 (一)
- (原创)基于ZedBoard的Webcam设计(四):MJPG编码和AVI封装
- (原创)基于ZedBoard的Webcam设计(五):x264编码在zedboard上的实现(软编码)
- 基于V4L2摄像头采集图片程序设计
- 基于ZedBoard的Webcam设计(三):视频的采集和动态显示
- 基于V4L2摄像头采集图片程序设计
- 基于ZedBoard的Webcam设计(三):视频的采集和动态显示
- 基于V4L2摄像头采集图片程序设计
- V4L2通过摄像头采集图片