这几天在做小车的过程中,需要用到图像采集。我想现在用的摄像头是UVC免驱的。根据国嵌的教程中有一个gspca摄像头的程序。我发现把gspca的采集程序用到uvc上时,在显示图像的时候提示没有huffman表。但是在显示gspca的摄像头时却没有问题。为此特别找了以下的程序来获取uvc摄像头的数据。

程序代码:

/** capturing from UVC cam* requires: libjpeg-dev* build: gcc -std=c99 capture.c -ljpeg -o capture*/#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <asm/types.h>
#include <linux/videodev2.h>#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>#include <jpeglib.h>void quit(const char * msg)
{fprintf(stderr, "[%s] %d: %s\n", msg, errno, strerror(errno));exit(EXIT_FAILURE);
}int xioctl(int fd, int request, void* arg)
{for (int i = 0; i < 100; i++) {int r = ioctl(fd, request, arg);if (r != -1 || errno != EINTR) return r;}return -1;
}typedef struct {uint8_t* start;size_t length;
} buffer_t;typedef struct {int fd;uint32_t width;uint32_t height;size_t buffer_count;buffer_t* buffers;buffer_t head;
} camera_t;camera_t* camera_open(const char * device, uint32_t width, uint32_t height)
{int fd = open(device, O_RDWR | O_NONBLOCK, 0);if (fd == -1) quit("open");camera_t* camera = malloc(sizeof (camera_t));camera->fd = fd;camera->width = width;camera->height = height;camera->buffer_count = 0;camera->buffers = NULL;camera->head.length = 0;camera->head.start = NULL;return camera;
}void camera_init(camera_t* camera) {struct v4l2_capability cap;if (xioctl(camera->fd, VIDIOC_QUERYCAP, &cap) == -1) quit("VIDIOC_QUERYCAP");if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) quit("no capture");if (!(cap.capabilities & V4L2_CAP_STREAMING)) quit("no streaming");struct v4l2_cropcap cropcap;memset(&cropcap, 0, sizeof cropcap);cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;if (xioctl(camera->fd, VIDIOC_CROPCAP, &cropcap) == 0) {struct v4l2_crop crop;crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;crop.c = cropcap.defrect;if (xioctl(camera->fd, VIDIOC_S_CROP, &crop) == -1) {// cropping not supported
    }}struct v4l2_format format;memset(&format, 0, sizeof format);format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;format.fmt.pix.width = camera->width;format.fmt.pix.height = camera->height;format.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;format.fmt.pix.field = V4L2_FIELD_NONE;if (xioctl(camera->fd, VIDIOC_S_FMT, &format) == -1) quit("VIDIOC_S_FMT");struct v4l2_requestbuffers req;memset(&req, 0, sizeof req);req.count = 4;req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;req.memory = V4L2_MEMORY_MMAP;if (xioctl(camera->fd, VIDIOC_REQBUFS, &req) == -1) quit("VIDIOC_REQBUFS");camera->buffer_count = req.count;camera->buffers = calloc(req.count, sizeof (buffer_t));size_t buf_max = 0;for (size_t i = 0; i < camera->buffer_count; i++) {struct v4l2_buffer buf;memset(&buf, 0, sizeof buf);buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;buf.memory = V4L2_MEMORY_MMAP;buf.index = i;if (xioctl(camera->fd, VIDIOC_QUERYBUF, &buf) == -1)quit("VIDIOC_QUERYBUF");if (buf.length > buf_max) buf_max = buf.length;camera->buffers[i].length = buf.length;camera->buffers[i].start =mmap(NULL, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED,camera->fd, buf.m.offset);if (camera->buffers[i].start == MAP_FAILED) quit("mmap");}camera->head.start = malloc(buf_max);
}void camera_start(camera_t* camera)
{for (size_t i = 0; i < camera->buffer_count; i++) {struct v4l2_buffer buf;memset(&buf, 0, sizeof buf);buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;buf.memory = V4L2_MEMORY_MMAP;buf.index = i;if (xioctl(camera->fd, VIDIOC_QBUF, &buf) == -1) quit("VIDIOC_QBUF");}enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;if (xioctl(camera->fd, VIDIOC_STREAMON, &type) == -1)quit("VIDIOC_STREAMON");
}void camera_stop(camera_t* camera)
{enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;if (xioctl(camera->fd, VIDIOC_STREAMOFF, &type) == -1)quit("VIDIOC_STREAMOFF");
}void camera_finish(camera_t* camera)
{for (size_t i = 0; i < camera->buffer_count; i++) {munmap(camera->buffers[i].start, camera->buffers[i].length);}free(camera->buffers);camera->buffer_count = 0;camera->buffers = NULL;free(camera->head.start);camera->head.length = 0;camera->head.start = NULL;
}void camera_close(camera_t* camera)
{if (close(camera->fd) == -1) quit("close");free(camera);
}int camera_capture(camera_t* camera)
{struct v4l2_buffer buf;memset(&buf, 0, sizeof buf);buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;buf.memory = V4L2_MEMORY_MMAP;if (xioctl(camera->fd, VIDIOC_DQBUF, &buf) == -1) return FALSE;memcpy(camera->head.start, camera->buffers[buf.index].start, buf.bytesused);camera->head.length = buf.bytesused;if (xioctl(camera->fd, VIDIOC_QBUF, &buf) == -1) return FALSE;return TRUE;
}int camera_frame(camera_t* camera, struct timeval timeout) {fd_set fds;FD_ZERO(&fds);FD_SET(camera->fd, &fds);int r = select(camera->fd + 1, &fds, 0, 0, &timeout);if (r == -1) quit("select");if (r == 0) return FALSE;return camera_capture(camera);
}void jpeg(FILE* dest, uint8_t* rgb, uint32_t width, uint32_t height, int quality)
{JSAMPARRAY image;image = calloc(height, sizeof (JSAMPROW));for (size_t i = 0; i < height; i++) {image[i] = calloc(width * 3, sizeof (JSAMPLE));for (size_t j = 0; j < width; j++) {image[i][j * 3 + 0] = rgb[(i * width + j) * 3 + 0];image[i][j * 3 + 1] = rgb[(i * width + j) * 3 + 1];image[i][j * 3 + 2] = rgb[(i * width + j) * 3 + 2];}}struct jpeg_compress_struct compress;struct jpeg_error_mgr error;compress.err = jpeg_std_error(&error);jpeg_create_compress(&compress);jpeg_stdio_dest(&compress, dest);compress.image_width = width;compress.image_height = height;compress.input_components = 3;compress.in_color_space = JCS_RGB;jpeg_set_defaults(&compress);jpeg_set_quality(&compress, quality, TRUE);jpeg_start_compress(&compress, TRUE);jpeg_write_scanlines(&compress, image, height);jpeg_finish_compress(&compress);jpeg_destroy_compress(&compress);for (size_t i = 0; i < height; i++) {free(image[i]);}free(image);
}int minmax(int min, int v, int max)
{return (v < min) ? min : (max < v) ? max : v;
}uint8_t* yuyv2rgb(uint8_t* yuyv, uint32_t width, uint32_t height)
{uint8_t* rgb = calloc(width * height * 3, sizeof (uint8_t));for (size_t i = 0; i < height; i++) {for (size_t j = 0; j < width; j += 2) {size_t index = i * width + j;int y0 = yuyv[index * 2 + 0] << 8;int u = yuyv[index * 2 + 1] - 128;int y1 = yuyv[index * 2 + 2] << 8;int v = yuyv[index * 2 + 3] - 128;rgb[index * 3 + 0] = minmax(0, (y0 + 359 * v) >> 8, 255);rgb[index * 3 + 1] = minmax(0, (y0 + 88 * v - 183 * u) >> 8, 255);rgb[index * 3 + 2] = minmax(0, (y0 + 454 * u) >> 8, 255);rgb[index * 3 + 3] = minmax(0, (y1 + 359 * v) >> 8, 255);rgb[index * 3 + 4] = minmax(0, (y1 + 88 * v - 183 * u) >> 8, 255);rgb[index * 3 + 5] = minmax(0, (y1 + 454 * u) >> 8, 255);}}return rgb;
}int main()
{camera_t* camera = camera_open("/dev/video0", 352, 288);camera_init(camera);camera_start(camera);struct timeval timeout;timeout.tv_sec = 1;timeout.tv_usec = 0;/* skip 5 frames for booting a cam */for (int i = 0; i < 5; i++) {camera_frame(camera, timeout);}camera_frame(camera, timeout);unsigned char* rgb =yuyv2rgb(camera->head.start, camera->width, camera->height);FILE* out = fopen("result.jpg", "w");jpeg(out, rgb, camera->width, camera->height, 100);fclose(out);free(rgb);camera_stop(camera);camera_finish(camera);camera_close(camera);return 0;
}

转载于:https://www.cnblogs.com/ynxf/p/6137091.html

ubuntu-Linux系统读取USB摄像头数据(uvc)相关推荐

  1. Win10+OpenCV无法正常读取USB摄像头数据解决方案

    采用OpenCV中的VideoCapture类获取USB摄像头的数据时,使用下列代码 VideoCapture VideoStream(0);if (!VideoStream.isOpened()) ...

  2. Win10+OpenCV4.5 无法正常读取USB摄像头数据解决方案

    借鉴了这个博客. 采用OpenCV中的VideoCapture类获取USB摄像头的数据时,使用下列代码 #include "pch.h" #include "highgu ...

  3. linux系统下 USB 摄像头1080分辨率采集帧率低问题的解决方法

    linux系统上一般使用 video4linux2来操作系统摄像. 1.安装一个 v4l2-ctrl工具: sudo apt install v4l-utils 2.查看摄像头支持的视频参数 sudo ...

  4. linux usb摄像头图像分辨率,linux系统下 USB 摄像头1080分辨率采集帧率低问题的解决方法...

    linux系统上一般使用 video4linux2来操作系统摄像. 1.安装一个 v4l2-ctrl工具: sudo apt install v4l-utils 2.查看摄像头支持的视频参数 sudo ...

  5. 国外linux内核视频播放器,基于Video for Linux内核的USB摄像头视频信号采集实现

    摘要:Video for Linux是Linux中关于视频设备的内核驱动,本文介绍了在Video for Linux内 >> 基于ARM9和USB摄像头的网络视频采集系统设计 基于嵌入式V ...

  6. Python OpenCV 读取USB摄像头报错问题解决

    报错信息: Traceback (most recent call last):   File "G:\Python图像识别相关学习视频\人体姿势检测.py", line 32, ...

  7. 大疆妙算Manifold刷机换源,cuda,opencv,qt配置以及实现opencv读取usb摄像头,qmake nvcc交叉编译

    大疆妙算Manifold刷机换源,cuda,opencv,qt配置以及实现opencv读取usb摄像头,qmake nvcc交叉编译 一.刷机 1.解压安装包 2.制作镜像 3.然后按照妙算说明书进入 ...

  8. linux是否有免安装程序,在线Ubuntu Linux系统,免安装体验Linux系统

    如果你觉得安装Linux系统有困难,又或者你只想体验一下Linux系统是什么样的,有没有这样的好事?我可以肯定的回答你,有的,今天为你介绍在线Ubuntu Linux系统,你只需要点击Ubuntu在线 ...

  9. 移动硬盘备份linux系统盘,将Ubuntu Linux系统放到你的移动硬盘

    将Ubuntu Linux系统放到你的移动硬盘 作者:佚名 来源:网络整理 2008-7-11 1.用livecd启动,插上移动硬盘,然后一切安正常的安装步骤进行,只是选择安装目标时选择你的移动硬盘, ...

最新文章

  1. Bitmap Font 报错“characters from the file are not available in the font”解决办法
  2. no output in console for unittests in pycharm 2017
  3. 【Java Web开发指南】解析Spring中Ioc和DI(入门Demo)
  4. Magento获取指定分类下的所有子分类信息
  5. 项目前端页面框架介绍
  6. 87-区间线段树(板子)--那个苑区的人最瘦
  7. 18.12.04 有品面试小记
  8. TDL(HDU-6641)
  9. bzoj 1662: [Usaco2006 Nov]Round Numbers 圆环数(枚举)
  10. 毕业后,她用1年时间拿下了30W年薪的阿里数据分析岗
  11. 【大数据处理技术】实验7(推荐林子雨老师的教程)
  12. 安装打印机驱动时报错 -536870329 或 1FFFFDB9
  13. spring-ant-处理zip
  14. QT 与日置、安捷伦测试仪 通讯 232串口 GPIB
  15. Bash Shellshock(Bash远程代码执行)漏洞分析及利用思路
  16. 中式风格室内装修 如何打造中式风格家居
  17. 计算机组装与维护我要自学网,【答疑】3D机械建模软件有哪些,3D机械建模一般用的是哪个软件? - 视频教程线上学...
  18. USB TYPE -A -B -C 接口
  19. 音响为什么要做CCC认证以及流程有哪些
  20. 安利一个Mac下好用的抓包工具-Charles

热门文章

  1. 小沙的长路(图论+数学)
  2. 2021年SWPUACM暑假集训day3最小生成树算法
  3. Caffe、TensorFlow、MXnet三个开源库对比+主流分类模型对比
  4. 可变长参数以及面试题
  5. Spring 的学习
  6. 标准模块 os.stat
  7. 4、根据前序和中序,重建二叉树
  8. mysql 聚集函数 count 使用详解
  9. 【Android】自己定义控件——仿天猫Indicator
  10. Yii框架官方指南系列41——专题:自动代码生成