前段时间做了一个项目,用到了linux环境下gec6818开发板驱动usb摄像头,在这里给大家分享一下。
摄像头的操作步骤
1)打开设备 2)配置设备(采集的频率、图像宽高、图像格式) 3)在内核空间申请缓冲区队列 4)把申请好的缓冲列表----映射到用户空间 5)开始采集 6)从队列中拿出一个缓冲区 7)从用户空间中把缓冲区的数据取走 8)把缓冲区放回队列 9)停止采集 10)释放资源设备节点文件:/dev/video7视频捕捉库:libapi_v4l2_arm.so相关函数://初始化摄像头设备int linux_v4l2_device_init(const char *dev);->打开文件,查找属性参数: const char *dev -》 文件名返回值: 失败-1//启动摄像头int linux_v4l2_start_capturing();//停止摄像头int linux_v4l2_stop_capturing();//卸载摄像头设备int linux_v4l2_device_uinit();//获取摄像头数据(存放jpg文件流:存放到freambuf)int linux_v4l2_get_fream(FrameBuffer *freambuf);//jpg文件流结构体 typedef struct Frame_Buffer{char buf[1843200]; //图片数据缓冲区int length; //图片数据长度(字节)}FrameBuffer;
下面是代码示例
#include "main.h"//设置摄像头启动变量 int video_show_flag = 0; //设置抓拍变量 int take_photo_flag = 0; //声明函数pthread_create extern int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);int photo_num = 0;void *real_time_video() {//定义存储摄像头数据的jpg缓冲区struct jpg_data video_buf;//1.初始化摄像头设备linux_v4l2_yuyv_init("/dev/video7");//2.启动摄像头linux_v4l2_start_yuyv_capturing();char photo_name[20] = {0};//循环采集数据与输出while(1){//3.获取摄像头数据(存放jpg文件流:存放到video_buf)linux_v4l2_get_yuyv_data(&video_buf);//4.把摄像头数据显示到LCD上lcd_draw_camera(0, 0, 700, 480, video_buf.jpg_data, video_buf.jpg_size);sprintf(photo_name,"photo%d.jpg",photo_num);if(take_photo_flag == 1) //进行抓拍{//创建一个新的文件//spritf();int fd = open(photo_name,O_RDWR|O_CREAT,0777);if(fd == -1){perror("拍照失败");continue;}//将图片数据写入文件中write(fd,video_buf.jpg_data,video_buf.jpg_size);//关闭文件保存close(fd);//清空抓拍的标志位take_photo_flag = 0;photo_num++;if(photo_num > 4)photo_num = 0;}if(video_show_flag == 0)break;}//4.停止摄像头linux_v4l2_yuyv_quit();return NULL; }int cam(void) {//打开lcd屏幕lcd_open();lcd_clear();//创建一条线程实时监控pthread_t pid;int album_falg=0;int cam_flag=0;int x,y;int yanshi_flag=1;char yanshi_buff[20];cam_flag=1;printf("打开摄像头\n");pthread_create(&pid,NULL,real_time_video,NULL);video_show_flag = 1;while(1){sprintf(yanshi_buff,"/cam%d.bmp",yanshi_flag);show_location_bmp(yanshi_buff,700,0,100,480,FB);get_xy(&x,&y);if(x > 718 && x < 800 && y > 5 && y < 70 && cam_flag==0 && yanshi_flag == 1){ cam_flag=1;printf("打开摄像头\n");pthread_create(&pid,NULL,real_time_video,NULL);video_show_flag = 1;}else if(x > 718 && x < 800 && y > 100 && y < 170 && cam_flag==0&& yanshi_flag == 1){cam_flag=1;printf("打开摄像头\n");pthread_create(&pid,NULL,real_time_video,NULL);video_show_flag = 1;}else if(x > 718 && x < 800 && y > 209 && y < 264&& yanshi_flag == 1){take_photo_flag = 1; printf("抓拍\n");}else if(x > 718 && x < 800 && y > 311 && y < 367&& yanshi_flag == 1){video_show_flag = 0;printf("相册\n");album_falg=album_cam(0);if(album_falg==2) break;if(album_falg==1){printf("打开摄像头\n");pthread_create(&pid,NULL,real_time_video,NULL);video_show_flag = 1;cam_flag=1;}}else if(x > 718 && x < 800 && y > 404 && y < 473 && yanshi_flag == 1){printf("关闭摄像头\n");video_show_flag = 0;break;}else if(x > 0 && x < 700 && y > 0 && y < 480){yanshi_flag++;if(yanshi_flag ==2)yanshi_flag = 0;}if(yanshi_flag==0){if(x > 714 && x < 798 && y > 16 && y < 116)//延时{}if(x > 714 && x < 798 && y > 168 && y < 212)//开始{sleep(3);take_photo_flag = 1; printf("抓拍\n");}if(x > 714 && x < 798 && y > 264 && y < 312)//相册{yanshi_flag=1;sprintf(yanshi_buff,"/cam%d.bmp",yanshi_flag);show_location_bmp(yanshi_buff,700,0,100,480,FB);video_show_flag = 0;printf("相册\n");album_falg=album_cam(0);if(album_falg==2) break;if(album_falg==1){printf("打开摄像头\n");pthread_create(&pid,NULL,real_time_video,NULL);video_show_flag = 1;cam_flag=1;}}if(x > 714 && x < 798 && y > 365 && y < 410)//关闭{printf("关闭摄像头\n");video_show_flag = 0;break;}}printf("x=%d,y=%d\n",x,y);}// //关闭lcd屏幕// lcd_close();return 0; }int cam_touch(void) {//打开lcd屏幕lcd_open();lcd_clear();//创建一条线程实时监控pthread_t pid;int touch_flag=0;int album_falg=0;int cam_flag=0;cam_flag=1;printf("打开摄像头\n");pthread_create(&pid,NULL,real_time_video,NULL);video_show_flag = 1;while(1){show_location_bmp("/cam1.bmp",700,0,100,480,FB);touch_flag = iic();if(touch_flag == 5){take_photo_flag = 1; printf("抓拍\n");}else if((touch_flag == 3 ||touch_flag==4) && video_show_flag ==0){cam_flag=1;printf("打开摄像头\n");pthread_create(&pid,NULL,real_time_video,NULL);video_show_flag = 1;}else if(touch_flag == 9){printf("关闭摄像头\n");video_show_flag = 0;usleep(100000);break;}else if(touch_flag == 7){video_show_flag = 0;printf("相册\n");album_falg=album_cam(1);if(album_falg==2) break;if(album_falg==1){printf("打开摄像头\n");pthread_create(&pid,NULL,real_time_video,NULL);video_show_flag = 1;cam_flag=1;}}}// //关闭lcd屏幕// lcd_close();return 0; }