camera.zip

  • 菜鸡1011
    了解作者
  • C/C++
    开发工具
  • 8KB
    文件大小
  • zip
    文件格式
  • 0
    收藏次数
  • 1 积分
    下载积分
  • 0
    下载次数
  • 2021-04-19 16:16
    上传日期
采集图像,可以一直到ARM平台,采用V4L2,
camera.zip
  • camera
  • main.c
    463B
  • camera.c
    5.7KB
  • main
    11KB
  • myhead.h
    436B
  • mycamera
    0B
  • camera.h
    799B
内容介绍
#include "camera.h" //封装yuv转换成rgb的函数 int yuvtorgb(int y,int u,int v) { int point; //YUYV-->两组RGB int r,g,b; //定义了rgb三个分量 b = 1164*(y - 16)/1000 + 2018*(u - 128)/1000; g = 1164*(y - 16)/1000 - 813*(v - 128)/1000 - 391*(u - 128)/1000; r = 1164*(y - 16)/1000 + 1596*(v - 128)/1000; //处理值越界的情况 if(r>255) r=255; if(g>255) g=255; if(b>255) b=255; if(r<0) r=0; if(g<0) g=0; if(b<0) b=0; //将rgb转换成ARGB返回 point=0x00<<24|r<<16|g<<8|b; return point; } //封装将一整个画面yuv数据--》rgb数据的函数 int yuvbuftorgbbuf(char *yuvbuf,int *rgbbuf)// 10 { int i,j; for(i=0,j=0; j<640*480; i+=4,j+=2) { rgbbuf[j]=yuvtorgb(yuvbuf[i],yuvbuf[i+1],yuvbuf[i+3]); rgbbuf[j+1]=yuvtorgb(yuvbuf[i+2],yuvbuf[i+1],yuvbuf[i+3]); } /* yuvtorgb(yuvbuf[0],yuvbuf[1],yuvbuf[3]) yuvtorgb(yuvbuf[2],yuvbuf[1],yuvbuf[3]) yuvtorgb(yuvbuf[4],yuvbuf[5],yuvbuf[7]) yuvtorgb(yuvbuf[6],yuvbuf[5],yuvbuf[7]) */ } int camera_show(void) { //打开lcd lcdfd=open("/dev/fb0",O_RDWR); if(lcdfd==-1) { perror("打开液晶屏失败!\n"); return -1; } //映射lcd首地址 lcdmem=mmap(NULL,800*480*4,PROT_READ|PROT_WRITE,MAP_SHARED,lcdfd,0); if(lcdmem==NULL) { perror("映射lcd失败!\n"); return -1; } printf("1111\n"); //1-打开摄像头的驱动 camerafd=open("/dev/video7",O_RDWR); if(camerafd==-1) { perror("打开摄像头的驱动失败!\n"); return -1; } //2-设置摄像头的采集格式 struct v4l2_format myfmt; bzero(&myfmt,sizeof(myfmt)); myfmt.type=V4L2_BUF_TYPE_VIDEO_CAPTURE; myfmt.fmt.pix.width=640; myfmt.fmt.pix.height=480; myfmt.fmt.pix.pixelformat=V4L2_PIX_FMT_YUYV; //yuv格式 myfmt.fmt.pix.field =V4L2_FIELD_NONE; printf("222\n"); ret=ioctl(camerafd,VIDIOC_S_FMT,&myfmt); if(ret==-1) { perror("设置采集格式失败!\n"); return -1; } //3-申请缓存 struct v4l2_requestbuffers req; bzero(&req,sizeof(req)); req.count=4; //缓冲块数量,一般1---5之间,一个缓冲块存放一帧画面 req.type=V4L2_BUF_TYPE_VIDEO_CAPTURE; req.memory=V4L2_MEMORY_MMAP; ret=ioctl(camerafd,VIDIOC_REQBUFS,&req); if(ret==-1) { perror("申请缓存失败!\n"); return -1; } printf("3333\n"); //定义指针分配堆空间存放每个缓存块的信息 struct usraddr *alladdr=calloc(4,sizeof(struct usraddr)); //分配你刚才申请的缓存 for(i=0; i<4; i++) { struct v4l2_buffer buf; bzero(&buf,sizeof(buf)); buf.type=V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory=V4L2_MEMORY_MMAP; buf.index=i; //你申请的缓冲块的索引,从0开始 ret=ioctl(camerafd,VIDIOC_QUERYBUF,&buf); if(ret==-1) { perror("分配缓存失败!\n"); return -1; } //趁热打铁,马上映射分配得到的某一块缓存 alladdr[i].someaddr=mmap(NULL,buf.length,PROT_READ|PROT_WRITE,MAP_SHARED,camerafd,buf.m.offset); if(alladdr[i].someaddr==NULL) { perror("映射首地址失败!\n"); return -1; } alladdr[i].somelength=buf.length; printf("4444\n"); } //将申请到的缓存入队 for(i=0; i<4; i++) { struct v4l2_buffer buf; bzero(&buf,sizeof(buf)); buf.type=V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory=V4L2_MEMORY_MMAP; buf.index=i; //你申请的缓冲块的索引,从0开始 ret=ioctl(camerafd,VIDIOC_QBUF,&buf); if(ret==-1) { perror("入队失败!\n"); return -1; } } printf("5555\n"); //开始采集 enum v4l2_buf_type mytype; mytype=V4L2_BUF_TYPE_VIDEO_CAPTURE; ret=ioctl(camerafd,VIDIOC_STREAMON,&mytype); if(ret==-1) { perror("开始采集失败!\n"); return -1; } //定义指针存放yuv转换得到的完整rgb int *rgbbuf=malloc(640*480*4); //定义超时时间1秒 struct timeval mytime; bzero(&mytime,sizeof(mytime)); mytime.tv_sec=1; //循环入队出队显示视频流,顺便用多路复用检测是否真的开始采集有数据了 while(1) //fd1 fd2 fd3 --》FD_ISSET() { fd_set myset;//读就绪 FD_ZERO(&myset); FD_SET(camerafd,&myset); printf("6666\n"); select(camerafd+1,&myset,NULL,NULL,&mytime); //如果视频监控有数据,select就不会阻塞 //检测到有数据了,就立马出队并显示出来 for(i=0; i<4; i++) { struct v4l2_buffer buf; bzero(&buf,sizeof(buf)); buf.type=V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory=V4L2_MEMORY_MMAP; buf.index=i; //你申请的缓冲块的索引,从0开始 ret=ioctl(camerafd,VIDIOC_DQBUF,&buf); if(ret==-1) { perror("出队失败!\n"); return -1; } ret=ioctl(camerafd,VIDIOC_QBUF,&buf); if(ret==-1) { perror("入队失败!\n"); return -1; } //将出队的画面数据显示在开发板的液晶屏上 yuv格式-->rgb格式显示 yuvbuftorgbbuf(alladdr[i].someaddr,rgbbuf); //将转换得到的ARGB显示在开发板的液晶屏上 for(j=0; j<480; j++) { memcpy(lcdmem+j*800,&rgbbuf[j*640],640*4);//内存拷贝函数 } } } } int camera_stop(void) { enum v4l2_buf_type mytype; mytype = V4L2_BUF_TYPE_VIDEO_CAPTURE; ret = ioctl(camerafd, VIDIOC_STREAMOFF, &mytype); if(-1 == ret ) { perror("停止监控失败!\n"); return -1; } } int Get_Ts() { //1,打开触摸屏文件 open /dev/input/event0 int ts_fd = open("/dev/input/event0", O_RDWR); if(-1 == ts_fd) { perror("open ts failed"); return -1; } //2,读取触摸屏文件数据 read struct input_event xy; int flag = 0; //标志位 :表示当前获取的坐标值的数量 while(1) //1024*600 || 800*480 { read(ts_fd, &xy, sizeof(xy)); //printf("type:%d, code:%d, value:%d\n", xy.type, xy.code, xy.value); if(xy.type == EV_ABS && xy.code == ABS_X && flag == 0) { flag = 1; ts_x = xy.value * 800 / 1024 ; //获取x轴坐标 } //获取y轴坐标 if(xy.type == EV_ABS && xy.code == ABS_Y && flag == 1) { flag = 2; ts_y = xy.value * 480 / 600; //获取y轴坐标 } if(flag == 2) { flag = 0; printf("(%d,%d)\n", ts_x, ts_y); break; //获取一次坐标之后结束循环 } } //3,关闭触摸屏文件 close close(ts_fd); }
评论
    相关推荐
    • imx6 V4L2视频采集和播放.rar
      基于飞思卡尔 imx6 android平台的V4L2分析。
    • v4l2display.zip
      llinux 摄像头通过v4l2进行图像采集和显示
    • V4L2视频采集.zip
      v4L2框架的视频采集代码,测试可用,程序运行后会得到一个test.yuyv文件,通过samba服务器从虚拟机拷贝到Windows,用YUVViewer.exe软件打开
    • V4L2.zip
      V4L2框架的图片采集,及相关结构体的详细介绍
    • linux下v4l2视频采集
      linux下使用v4l2对音视频的采集,获取一帧数据
    • linux下v4l2
      V4l2 UVC 视频采集不含压缩,直接存储为yuv422格式的图片文件或者是视频流文件,各位请自行添加压缩V4l2 UVC 视频采集不含压缩,直接存储为yuv422格式的图片文件或者是视频流文件,各位请自行添加压缩
    • c语言 v4l2 采集图片 拍照
      linux系统下 使用C语言, 使用v4l2 支持YUYV (YUV420格式) 保存为bmp图像,无需额外库。
    • 基于linux的V4L2图像采集代码
      基于linux的图像采集程序, 有yvyv转rgb源码,yuyv转jpeg源码
    • Linux下V4L2视频图像采集
      在linux系统下,用ARM11实现摄像头视频图像采集
    • V4L2视屏采集资料.zip
      基于单片机的图像获取功能。以及图像的实时传输。