首页 > 其他分享 >4412 使用usb摄像头拍照YUYV格式

4412 使用usb摄像头拍照YUYV格式

时间:2023-08-08 17:48:11浏览次数:35  
标签:YUYV usb fmt 4412 ret printf include 摄像头 USB

一、内核设置

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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <getopt.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <malloc.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <sys/ioctl.h>

#include <asm/types.h>
#include <linux/videodev2.h>

#define CAMERA_DEVICE "/dev/video0"
#define CAPTURE_FILE "frame.jpg"

#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 failed\n", 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: %s\n", cap.driver);
    printf("*\tcard: %s\n", cap.card);
    printf("*\tbus_info: %s\n", cap.bus_info);
    printf("*\tversion: %08X\n", cap.version);
    printf("*\tcapabilities: %08X\n", 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: %d\n", fmt.type);
    printf("*\twidth: %d\n", fmt.fmt.pix.width);
    printf("*\theight: %d\n", fmt.fmt.pix.height);

    char fmtstr[8];
    memset(fmtstr, 0, 8);
    memcpy(fmtstr, &fmt.fmt.pix.pixelformat, 4);
    printf("*\tpixelformat: %s\n", fmtstr);
    printf("*\tfield: %d\n", fmt.fmt.pix.field);
    printf("*\tbytesperline: %d\n", fmt.fmt.pix.bytesperline);
    printf("*\tsizeimage: %d\n", fmt.fmt.pix.sizeimage);
    printf("*\tcolorspace: %d\n", fmt.fmt.pix.colorspace);
    printf("*\tpriv: %d\n", fmt.fmt.pix.priv);
    //    printf("*\traw_data: %s\n", 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.%s\n", 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 memory\n");
        exit(EXIT_FAILURE);
    }    

    for(i=0;i<reqbuf.count;i++) {
        struct v4l2_buffer buf;
        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: %s\n", 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=%d\n", 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 failed\n");
        return -1;
    }
    fwrite(buffers[buf.index].start, 1, buf.length, fp);
    fclose(fp);
    printf("Capture one frame saved in %s\n", 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;
}
复制代码

 

三、使用软件打开

不过要选择对应的格式:

标签:YUYV,usb,fmt,4412,ret,printf,include,摄像头,USB
From: https://www.cnblogs.com/kn-zheng/p/17614994.html

相关文章

  • USB摄像头——v4l2打开设备、获取设备支持的格式
    一、v4l2介绍  v4l2意思为VideoforLinux2,是linux中视频设备的内核驱动。它有以下几个接口: 视频采集接口:这种设备可以是高频头或摄像头;视频输出接口:可以驱动计算机的外围视频图像设备直接传输视频接口:主要工作是把从视频采集设备采集过来的信号直接输出到输出设备之上,......
  • 嵌入式教程_DSP教程:2-27 基于USB接口的存储设备实验
    2-27基于USB接口的存储设备实验实验目的本节视频的目的是学习USBOTG的运用和工作原理,并实现USB从方式,将实验板模拟成一个USB存储设备,实现主机和实验板之间的数据传输。实验原理硬件原理图实验过程中使用的是USBOG接口T本节视频的目的是学习USBOTG的运用和工作原理,并实现USB从方......
  • Omron 欧姆龙CP1系列PLC通讯口(USB、RS232、RS485/422)的正确使用
    USB、RS232、RS485、RS422是CP1系列的主要通信接口,在现场调试、设备连接中应用广泛。(1)USB口通讯的正确使用   ①通讯电缆:请使用可靠屏蔽、且带磁环的通讯电缆,防止电磁或噪音干扰。    ②连接:避免在通信时插拔USB电缆,且插拔时避免手直接触碰USB口上的金属......
  • centos系统给usb网卡设置静态ip
    centos系统usb网卡设置静态ip有一台普通电脑作为服务器,装centos系统,没有图形界面。因为主板自带的网卡坏了(重新装过的系统发现/etc/sysconfig/network-scripts目录下没有ifcfg-eth0或者ifcfg-ens33这种类似的网络文件),所以用了绿联的usb转网卡插在主机的usb用,插上去后发现是可以自动......
  • 荣耀90pro无法在Android Studio中使用USB真机调试问题
    今日用荣耀手机进行真机调试,由于之前没有用过华为荣耀手机,所以在连接过程中出现了一些问题。首先,我还是像以前那样用数据线将手机和电脑连接,在手机开发者模式中开启USB调试,结果发现NoDevices。 之后发现,在打开USB调试时,提示如下信息,这跟我之前用其他手机提示的不一样,我记得是......
  • USB前后置摄像头切换
    方法1:修改文件:hardware\rockchip\camera\CameraHal\CameraHal_Module.cpp//默认前置置摄像头camInfoTmp[cam_cnt&0x01].facing_info.facing=CAMERA_FACING_FRONT;//默认后置置摄像头camInfoTmp[cam_cnt&0x01].facing_info.facing=CAMERA_FACING_BACK; 所以将CAME......
  • pyhon - 监听usb插入并复制
    importtimefromshutilimportcopytreefrompsutilimportdisk_partitionscopyFlag=FalsedefusbCopy(driver):try:path=r'D:\usb-'+time.strftime("%Y%m%d%H%M%S",time.localtime())print(f'开始复制,复制路径:{pa......
  • chatGPT回答的,关于使用USB引导,使用WDS安装操作系统的提示:
    理解网络引导WDS安装windows操作系统么? 当然,我可以帮助您理解以网络引导(WindowsDeploymentServices,即WDS)安装Windows操作系统的基本过程。WindowsDeploymentServices是一种让管理员远程安装Windows操作系统的工具,这样可以在域环境中快速地为多个系统进行操作......
  • v4l2采样usb摄像头并显示
    ubuntu思路:1、首先理解camera工作原理,重点理解 yuv,rgb视频流,即Sensor数据输出的图像格式;大体过程:光线通过镜头Lens进入摄像头内部,通过IR过滤掉红外光,抵达sensor,sensor将光信号转为电信号,在通过ADC电路转为数字信号,此时的数据格式是RAWData;Senso......
  • USB图像采集卡是什么
    USB图像采集卡是一种用于连接计算机和摄像机、摄像头或其他视频设备的设备。它充当了一个接口,使得视频信号可以通过USB接口传输到计算机,并且可以进行图像采集和处理,如实时监控、视频录制、图像分析等。USB图像采集卡的出现极大地方便了用户在计算机上进行视频采集和处理的需求。......