V4L2拍照程序

本文介绍了如何使用V4L2接口在ZC301P摄像头进行拍照,拍照的图片以JPEG格式保存,并以当前时间命名。通过交叉编译后的cam.c程序在开发板上运行,展示了摄像头支持的格式和参数,拍照后的图片能通过tftp命令传输到电脑查看。
摘要由CSDN通过智能技术生成

由于毕设中用到了摄像头拍照功能,然后网上查了一下,最后自己稍微修改,以当前时间保存为.jpeg格式的图片,最后稍微添加了自己的一些小理解,与大家分享一下。

-----------------------------------------------------------------------------------------------------------------------------------

用的摄像头是ZC301P,已经加载进内核,输出格式是JPEG,大小是640*480,所以后面的图片大小计算的时候是640*480*3。


cam.c:

#include <fcntl.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <linux/videodev2.h>
#include <time.h>
#include <stdio.h>
#include <string.h>

int main(){
  //add by liuzj
  time_t t;
  struct tm *tmp;
  t = time(NULL);
  tmp = localtime(&t);
  char buffer1[30];
  char path[30];
  /end
  int fd = open("/dev/video0",O_RDWR);
  printf("lzj------->>>fd is %d\n",fd);
  //
  struct v4l2_capability cap;
  ioctl(fd,VIDIOC_QUERYCAP,&cap);
  printf("lzj---------->>>>>Driver Name:%s\nCard Name:%s\nBus info:%s\n",cap.driver,cap.card,cap.bus_info);
  //
  struct v4l2_fmtdesc fmtdesc;
  fmtdesc.index = 0; 
  fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  while(ioctl(fd,VIDIOC_ENUM_FMT,&fmtdesc) != -1){
   printf("lzj-------->>>>>fmtdesc.description is %s\n",fmtdesc.description);
   fmtdesc.index ++;
  }
  //
  struct v4l2_format fmt;
  fmt.type = V4L2_BUF_TYPE_VIDEO
下面是一个简单的 C 语言程序,用于调用 V4L2 接口打开摄像头并拍照。您可以根据自己的需要进行修改和扩展。 ```c #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <unistd.h> #include <sys/ioctl.h> #include <sys/mman.h> #include <linux/videodev2.h> #define CAMERA_DEVICE "/dev/video0" #define CAPTURE_FILE "capture.jpg" #define IMAGE_WIDTH 640 #define IMAGE_HEIGHT 480 int main(int argc, char *argv[]) { int fd; struct v4l2_capability cap; struct v4l2_format fmt; struct v4l2_requestbuffers req; struct v4l2_buffer buf; void *buffer; int i; // 打开摄像头设备 fd = open(CAMERA_DEVICE, O_RDWR); if (fd < 0) { perror("open"); return 1; } // 查询设备能力 if (ioctl(fd, VIDIOC_QUERYCAP, &cap) < 0) { perror("VIDIOC_QUERYCAP"); return 1; } printf("Driver: %s\n", cap.driver); printf("Card: %s\n", cap.card); printf("Bus: %s\n", cap.bus_info); // 设置视频格式 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; fmt.fmt.pix.width = IMAGE_WIDTH; fmt.fmt.pix.height = IMAGE_HEIGHT; fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_JPEG; fmt.fmt.pix.field = V4L2_FIELD_INTERLACED; if (ioctl(fd, VIDIOC_S_FMT, &fmt) < 0) { perror("VIDIOC_S_FMT"); return 1; } // 请求帧缓冲 req.count = 1; req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; req.memory = V4L2_MEMORY_MMAP; if (ioctl(fd, VIDIOC_REQBUFS, &req) < 0) { perror("VIDIOC_REQBUFS"); return 1; } // 映射帧缓冲 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_MMAP; buf.index = 0; if (ioctl(fd, VIDIOC_QUERYBUF, &buf) < 0) { perror("VIDIOC_QUERYBUF"); return 1; } buffer = mmap(NULL, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, buf.m.offset); if (buffer == MAP_FAILED) { perror("mmap"); return 1; } // 开始视频采集 if (ioctl(fd, VIDIOC_STREAMON, &buf.type) < 0) { perror("VIDIOC_STREAMON"); return 1; } // 捕获视频帧 if (ioctl(fd, VIDIOC_QBUF, &buf) < 0) { perror("VIDIOC_QBUF"); return 1; } if (ioctl(fd, VIDIOC_DQBUF, &buf) < 0) { perror("VIDIOC_DQBUF"); return 1; } // 写入 JPEG 文件 FILE *fp = fopen(CAPTURE_FILE, "wb"); fwrite(buffer, buf.bytesused, 1, fp); fclose(fp); // 停止视频采集 if (ioctl(fd, VIDIOC_STREAMOFF, &buf.type) < 0) { perror("VIDIOC_STREAMOFF"); return 1; } // 解除帧缓冲映射 munmap(buffer, buf.length); // 关闭摄像头设备 close(fd); return 0; } ``` 该程序使用了 V4L2 API 中的 VIDIOC_* 命令来控制摄像头设备的各种属性和功能,例如 VIDIOC_QUERYCAP、VIDIOC_S_FMT、VIDIOC_REQBUFS、VIDIOC_STREAMON 等。它还使用了 mmap 函数将摄像头设备的帧缓冲映射到内存中,并使用 fwrite 函数将 JPEG 数据写入文件中。 该程序编译后生成可执行文件,您可以在 Linux 系统上直接运行它来打开摄像头并拍照。请注意,该程序可能需要 root 权限才能访问摄像头设备。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值