历史上的今天
今天是:2024年12月29日(星期日)
2021年12月29日 | 4412 使用usb摄像头拍照YUYV格式
2021-12-29 来源:eefocus
一、内核设置
Linux内核中已经带有很完善的USB摄像头驱动,支持几乎所有的USB摄像头,我们只需要配置内核,选择上相应的Sensor型号即可。
配置内核,支持USB摄像头:
Device Drivers --->
<*> Multimedia support --->
<*> Video For Linux
[*] Enable Video For Linux API 1 (DEPRECATED)
[*] Video capture adapters --->
[*] V4L USB devices --->
<*> USB Video Class (UVC)
[*] UVC input events device support
[*] GSPCA based webcams --->
到这里,我们就可以选择所需要的USB摄像头驱动,当然也可以选择所有的USB摄像头驱动支持(这样编译出的内核会比较大)
GSPCA是一个万能摄像头驱动程序,进入GSPCA based webcams进行选择。
插入USB摄像头(我使用的UVC摄像头),会提示:
usb 1-1.1: new full speed USB device using s3c2410-ohci and address 3
usb 1-1.1: New USB device found, idVendor=0ac8, idProduct=3450
usb 1-1.1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
usb 1-1.1: Product: Deasy USB2.0 Camera
usb 1-1.1: Manufacturer: Vimicro Corp.
uvcvideo: Found UVC 1.00 device Deasy USB2.0 Camera (0ac8:3450)
input: Deasy USB2.0 Camera as
/devices/platform/s3c2410-ohci/usb1/1-1/1-1.1/1-1.1:1.0/input/input3
它的设备名称是:/dev/video0
USB摄像头一般都是基于V4L2架构的,需要编写V4L2架构的程序来操作摄像头
二、编写V4L2的应用程序
#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define CAMERA_DEVICE "/dev/video0" #define CAPTURE_FILE "frame.jpg?imageView2/2/w/550" #define VIDEO_WIDTH 640 #define VIDEO_HEIGHT 480 #define VIDEO_FORMAT V4L2_PIX_FMT_YUYV #define BUFFER_COUNT 4 typedef struct VideoBuffer { void *start; size_t length; }VideoBuffer; int fd; //摄像头文件描述符 void open_camera(char *path); void get_camera_info(); void get_vedio_info(); //打开设备 void open_camera(char *path) { fd = open(CAMERA_DEVICE, O_RDWR, 0); if(fd < 0) { printf("Open %s failedn", CAMERA_DEVICE); exit(EXIT_FAILURE); } } //获取驱动信息 void get_camera_info() { struct v4l2_capability cap; ret = ioctl(fd, VIDIOC_QUERYCAP, &cap); if(ret < 0) { printf("VIDIOC_QUERYCAP failed (%d)n", ret); return ret; } // Print capability informations printf("Capbility Informations:n"); printf("*tdriver: %sn", cap.driver); printf("*tcard: %sn", cap.card); printf("*tbus_info: %sn", cap.bus_info); printf("*tversion: %08Xn", cap.version); printf("*tcapabilities: %08Xn", cap.capabilities); } //获取视频格式 void get_vedio_info() { struct v4l2_format fmt; memset(&fmt, 0, sizeof(fmt)); fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; ret = ioctl(fd, VIDIOC_G_FMT, &fmt); if(ret < 0) { printf("VIDIOC_G_FMT failed (%d)n", ret); return ret; } // Print Stream Format printf("Stream Format Informations:n"); printf("*ttype: %dn", fmt.type); printf("*twidth: %dn", fmt.fmt.pix.width); printf("*theight: %dn", fmt.fmt.pix.height); char fmtstr[8]; memset(fmtstr, 0, 8); memcpy(fmtstr, &fmt.fmt.pix.pixelformat, 4); printf("*tpixelformat: %sn", fmtstr); printf("*tfield: %dn", fmt.fmt.pix.field); printf("*tbytesperline: %dn", fmt.fmt.pix.bytesperline); printf("*tsizeimage: %dn", fmt.fmt.pix.sizeimage); printf("*tcolorspace: %dn", fmt.fmt.pix.colorspace); printf("*tpriv: %dn", fmt.fmt.pix.priv); // printf("*traw_data: %sn", fmt.fmt.raw_data); /* 显示所有支持的格式 */ struct v4l2_fmtdesc fmtdesc; fmtdesc.index = 0; fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; printf("Support format:n"); while(ioctl(fd, VIDIOC_ENUM_FMT, &fmtdesc) != -1) { printf("t%d.%sn", fmtdesc.index+1, fmtdesc.description); fmtdesc.index++; } } int main() { int i, ret; open_camera(CAMERA_DEVICE); get_camera_info(); get_vedio_info(); //请求分配内存 struct v4l2_requestbuffers reqbuf; reqbuf.count = BUFFER_COUNT; reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; reqbuf.memory = V4L2_MEMORY_MMAP; ret = ioctl(fd, VIDIOC_REQBUFS, &reqbuf); if(ret < 0) { printf("VIDIOC_REQBUFS failed (%d)n", ret); return ret; } //获取空间 VideoBuffer *buffers = calloc(reqbuf.count, sizeof(*buffers)); if(!buffers) { //映射 fprintf(stderr, "Out of memoryn"); exit(EXIT_FAILURE); } for(i=0;i memset(&buf, 0, sizeof(buf)); buf.index = i; buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_MMAP; ret = ioctl(fd, VIDIOC_QUERYBUF, &buf); if(ret < 0) { printf("VIDIOC_QUERYBUF (%d) failed (%d)n", i, ret); return ret; } // mmap buffer buffers[i].length = buf.length; buffers[i].start = (char *)mmap(0, buf.length, PROT_READ|PROT_WRITE, MAP_SHARED, fd, buf.m.offset); if(buffers[i].start == MAP_FAILED) { printf("mmap (%d) failed: %sn", i, strerror(errno)); return -1; } // Queen buffer ret = ioctl(fd, VIDIOC_QBUF, &buf); if(ret < 0) { printf("VIDIOC_QBUF (%d) failed (%d)n", i, ret); return -1; } printf("Frame buffer: %d: address=0x%x, length=%dn", i, (unsigned int)buffers[i].start, buffers[i].length); } // 开始录制 struct v4l2_buffer buf; enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.index = 0; buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_MMAP; ret = ioctl(fd, VIDIOC_STREAMON, &type); if (ret < 0) { printf("VIDIOC_STREAMON failed (%d)n", ret); return ret; } // Get frame ret = ioctl(fd, VIDIOC_DQBUF, &buf); if (ret < 0) { printf("VIDIOC_DQBUF failed (%d)n", ret); return ret; } // Process the frame FILE *fp = fopen(CAPTURE_FILE, "wb"); if (fp < 0) { printf("open frame data file failedn"); return -1; } fwrite(buffers[buf.index].start, 1, buf.length, fp); fclose(fp); printf("Capture one frame saved in %sn", CAPTURE_FILE); // Re-queen buffer ret = ioctl(fd, VIDIOC_QBUF, &buf); if (ret < 0) { printf("VIDIOC_QBUF failed (%d)n", ret); return ret; } // Release the resource for(i=0;i<4;i++) { munmap(buffers[i].start, buffers[i].length); } close(fd); printf("Camera test Done.n"); return 0; } 三、使用软件打开 不过要选择对应的格式:

史海拾趣
|
搞了一段时间ISE,几乎就要崩溃了 最近做个东西,要用到xilinx的ISe开发软件,找了很久,也下载了几个 但都是没法安装,把我搞惨了,哪位朋友能给我发一个不?版本不要太高, ise6.2等级别的,万分感谢了 我的邮箱是317930100@qq ...… 查看全部问答> |
|
LED是T型和N型半导体,三价有电洞,五价提供电子,两者结合中间有空乏区,能够产生能量,光就发出来。由于它是半导体,有能隙,随著参杂元素的不同而产生不同能隙,从氮化镓的3.4eV到磷化铟的1.35eV,波长亦随著改变,而产生出不同的颜色,从紫外光 ...… 查看全部问答> |
|
用51 + PDIUSBD12 ,实现和 PC通信,固件程序写好了,可是找不到PC winxp的驱动, 求菲利浦的 PDIUSBD12 的驱动,和使用方法。 如果谁知道哪里可以下载麻烦告知一下。也可发我邮箱 yuexianhanshu@yahoo.com.cn 谢了… 查看全部问答> |
|
wince5.0,已经把media player相关的组件都加入了,格式支持都加入了,基本上multimedia里面的都加上了。 启动后看到.mpg,.wmv的文件图标改了,.avi的图标没变。 打开.wmv,提示缺少一个解码器,然后只有声音没有图像。 .mpg的都不能打开。试过 ...… 查看全部问答> |
|
本人用了89C51写了一个时钟显示程序,硬件电路共有4个单独的数码管显示,P1.1G至P1.7接了数码管的A、B、C、D、E、F、G P2.3接了显示时的个位数码管DP脚,P2.7、P2.6、P2.5、P2.4分别接了时的十位数码管、时的个位数码管、分的十位数码管、 ...… 查看全部问答> |




