【C++】开源:Linux端V4L2视频设备库

这篇具有很好参考价值的文章主要介绍了【C++】开源:Linux端V4L2视频设备库。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

😏★,°:.☆( ̄▽ ̄)/$:.°★ 😏
这篇文章主要介绍Linux端V4L2视频设备库。
无专精则不能成,无涉猎则不能通。——梁启超
欢迎来到我的博客,一起学习,共同进步。
喜欢的朋友可以关注一下,下次更新不迷路🥞

😏1. 项目介绍

Video4Linux2(V4L2)是一个用于Linux操作系统的视频设备驱动框架。它提供了一个统一的接口,用于在应用程序和视频设备之间进行通信和交互。

V4L2支持各种类型的视频设备,包括USB摄像头、摄像机、TV调谐器、网络摄像头等。通过使用V4L2,开发者可以轻松地访问和控制视频设备,以捕获视频流、调整图像参数、设置视频格式和分辨率等。

以下是V4L2的一些重要特点和概念:

1.设备节点:每个视频设备在Linux系统中都表示为一个设备节点,通常位于/dev/video*路径下。应用程序通过打开这些设备节点来访问相应的视频设备。

2.视频捕捉:V4L2允许应用程序从视频设备中捕获视频帧或图像。它提供了一系列的API函数,使应用程序能够请求存储视频帧的缓冲区,并在设备准备好时将其读取到内存中。

3.视频输出:除了捕获视频,V4L2还支持将视频数据发送到视频设备,以便在外部显示设备上进行输出。应用程序可以将视频帧写入输出缓冲区,并通过相应的IOCTL调用将其发送到视频设备。

4.控制和参数设置:V4L2允许应用程序对视频设备进行控制和配置。例如,应用程序可以设置摄像头的亮度、对比度、饱和度等参数,选择摄像头的输入源,设置视频格式和分辨率等。

5.帧缓冲管理:V4L2通过Frame Buffer子系统来管理视频帧的缓冲区。它提供了API函数来请求和管理用于存储视频帧的缓冲区,并进行帧缓冲的交换和处理。

😊2. 环境配置

下面进行环境配置:

# v4l2是linux内核的一部分,只需安装开发库
sudo apt-get install libv4l-dev
# 使用v4l2开发
# 在应用程序中使用 #include <linux/videodev2.h> 来引入V4L2的头文件,并使用相关的API函数

😆3. 使用说明

下面进行使用分析:

基于v4l2调用usb摄像头并用opencv显示示例:

#include <iostream>
#include <cstdlib>
#include <cstring>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/mman.h>	//共享内存
#include <linux/videodev2.h>
#include <opencv2/opencv.hpp>

#define WIDTH 640
#define HEIGHT 480

int main() {
    int fd;
    struct v4l2_capability cap;
    struct v4l2_format fmt;
    struct v4l2_requestbuffers req;
    struct v4l2_buffer buf;
    enum v4l2_buf_type type;

    // 打开摄像头设备
    fd = open("/dev/video0", O_RDWR);
    if (fd == -1) {
        std::cerr << "无法打开摄像头设备" << std::endl;
        return 1;
    }

    // 查询摄像头能力
    if (ioctl(fd, VIDIOC_QUERYCAP, &cap) == -1) {
        std::cerr << "无法查询摄像头能力" << std::endl;
        close(fd);
        return 1;
    }

    // 设置视频格式
    memset(&fmt, 0, sizeof(fmt));
    fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    fmt.fmt.pix.width = WIDTH;
    fmt.fmt.pix.height = HEIGHT;
    fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; // YUV格式
    if (ioctl(fd, VIDIOC_S_FMT, &fmt) == -1) {
        std::cerr << "无法设置视频格式" << std::endl;
        close(fd);
        return 1;
    }

    // 请求视频缓冲区
    memset(&req, 0, sizeof(req));
    req.count = 1;
    req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    req.memory = V4L2_MEMORY_MMAP;
    if (ioctl(fd, VIDIOC_REQBUFS, &req) == -1) {
        std::cerr << "无法请求视频缓冲区" << std::endl;
        close(fd);
        return 1;
    }

    // 映射视频缓冲区到用户空间
    struct v4l2_buffer* buffers = new v4l2_buffer[req.count];
    void** frame_buffers = new void*[req.count];
    for (int i = 0; i < req.count; i++) {
        memset(&buf, 0, sizeof(buf));
        buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        buf.memory = V4L2_MEMORY_MMAP;
        buf.index = i;
        if (ioctl(fd, VIDIOC_QUERYBUF, &buf) == -1) {
            std::cerr << "无法查询视频缓冲区" << std::endl;
            close(fd);
            return 1;
        }
        frame_buffers[i] = mmap(NULL, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, buf.m.offset);
        if (frame_buffers[i] == MAP_FAILED) {
            std::cerr << "无法映射视频缓冲区到用户空间" << std::endl;
            close(fd);
            return 1;
        }
    }

    // 入队视频缓冲区
    for (int i = 0; i < req.count; i++) {
        memset(&buf, 0, sizeof(buf));
        buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        buf.memory = V4L2_MEMORY_MMAP;
        buf.index = i;
        if (ioctl(fd, VIDIOC_QBUF, &buf) == -1) {
            std::cerr << "无法入队视频缓冲区" << std::endl;
            close(fd);
            return 1;
        }
    }

    // 开始视频流采集
    type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    if (ioctl(fd, VIDIOC_STREAMON, &type) == -1) {
        std::cerr << "无法开始视频流采集" << std::endl;
        close(fd);
        return 1;
    }

    // 循环获取并显示相机数据
    cv::Mat frame(HEIGHT, WIDTH, CV_8UC2);
    cv::namedWindow("Camera", cv::WINDOW_AUTOSIZE);
    while (true) {
        // 出队视频缓冲区
        memset(&buf, 0, sizeof(buf));
        buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        buf.memory = V4L2_MEMORY_MMAP;
        if (ioctl(fd, VIDIOC_DQBUF, &buf) == -1) {
            std::cerr << "无法出队视频缓冲区" << std::endl;
            close(fd);
            return 1;
        }

        // 处理相机数据(这里只是简单地将YUYV格式的数据转换为RGB格式)
        cv::cvtColor(cv::Mat(HEIGHT, WIDTH, CV_8UC2, frame_buffers[buf.index]), frame, cv::COLOR_YUV2BGR_YUYV);

        // 显示相机数据
        cv::imshow("Camera", frame);
        if (cv::waitKey(1) == 27) {
            break; // 按下Esc键退出循环
        }

        // 再次入队视频缓冲区
        if (ioctl(fd, VIDIOC_QBUF, &buf) == -1) {
            std::cerr << "无法再次入队视频缓冲区" << std::endl;
            close(fd);
            return 1;
        }
    }

    // 停止视频流采集
    type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    if (ioctl(fd, VIDIOC_STREAMOFF, &type) == -1) {
        std::cerr << "无法停止视频流采集" << std::endl;
        close(fd);
        return 1;
    }

    // 解除映射视频缓冲区
    for (int i = 0; i < req.count; i++) {
        munmap(frame_buffers[i], buf.length);
    }

    // 关闭摄像头设备
    close(fd);

    delete[] buffers;
    delete[] frame_buffers;

    return 0;
}

编译运行:

g++ -o main main.cpp `pkg-config --libs opencv`
./main

【C++】开源:Linux端V4L2视频设备库,# c++开源项目学习,c++,开源,linux

以上。文章来源地址https://www.toymoban.com/news/detail-672146.html

到了这里,关于【C++】开源:Linux端V4L2视频设备库的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Linux摄像头(v4l2应用)——获取摄像头一帧图像

    一.V4L2简介 V4L2(Video for Linux 2):Linux内核中视频设备中的驱动框架,对于应用层它提供了一系列的API接口,同时对于硬件层,它适配大部分的视频设备,因此通过调用V4L2的接口函数可以适配大部分的视频设备。 二、操作流程 1.打开设备 当把摄像头插入到电脑后,执行ls /

    2024年02月20日
    浏览(53)
  • Linux + 香橙派 + V4L2 + http 实现远程监控摄像头在网页端显示

    项目需求,需要做一个基于边缘端的人脸识别远程监控摄像头并在网页前端展示 ,这里采用国产香橙派作为边缘计算终端,安装ubuntu系统,系统中采用v4l2接口对摄像头进行获取,当客户端通过网页进行请求时,服务器通过http服务的形式将一帧帧图像发送给客户端,只要一秒

    2024年02月15日
    浏览(42)
  • V4L2常用调试命令

    这篇文章简单记录一下RK平台基于V4L2框架camera调试过程中常用的一些命令: (1)查看拓扑结构:查看media0的pipeline (2)抓数据流命令: 对video0节点,设置格式为NV12,分辨率为1920x1080,不裁剪,4个buf轮转,--verbose的作用是刷出帧率。 (3)抓图命令: 类似上面的,将图像保

    2024年02月03日
    浏览(48)
  • V4L2 摄像头应用编程

    ALPHA/Mini I.MX6U 开发板配套支持多种不同的摄像头,包括正点原子的ov5640(500W 像素)、 ov2640(200W 像素)以及ov7725(不带FIFO、30W 像素)这三款摄像头,在开发板出厂系统上,可以使用这些摄像头;当然,除此之外我们还可以使用USB 摄像头,直接将USB 摄像头插入到开发板上的

    2024年02月11日
    浏览(43)
  • linux v4l2架构分析之异步注册v4l2_async_subdev_notifier_register、v4l2_async_register_subdev、v4l2_async_notifie

            在camera驱动注册中,v4l2_async_subdev_notifier_register、v4l2_async_register_subdev、v4l2_async_notifier_register这几个函数都会被使用到,三者在异步注册的实现中是紧密关联的,所以本文将三者放在一起进行分析。本文主要介绍异步注册的功能的整体实现框架,为了更好把握整体思

    2024年02月14日
    浏览(51)
  • 内存不足V4L2 申请DMC缓存报错问题

    当内存不足时,V4L2可能存在申请DMA缓存报错,如下日志:

    2024年02月12日
    浏览(40)
  • RK3568平台开发系列讲解(驱动基础篇)V4L2 用户空间 API 说明

    🚀返回专栏总目录 沉淀、分享、成长,让自己和他人都能有所收获!😄 📢设备驱动的主要目的是控制和利用底层硬件,同时向用户展示功能。 这些用户可以是在用户空间或其他内核驱动中运行的应用。 本篇我们将学习如何利用内核公开的 V4L2 设备功能。 我们将从描述和

    2023年04月25日
    浏览(51)
  • opencv-python调用摄像头失败 global /io/opencv/modules/videoio/src/cap_v4l.cpp (1000) tryIoctl VIDEOIO(V4L2

    Ubuntu 18.04 aarch64 Python 3.7.15 opencv-python 4.6.0 插入USB摄像头后, /dev/video0 会正常出现,使用 fswebcam 也能正常拍摄照片。但运行 opencv-python 的视频拍摄例程时出错,例程如下。 如果例程正确运行,屏幕窗口中将显示灰度处理后的摄像头实时视频。 报错信息如下 单步调试后,发现

    2023年04月24日
    浏览(77)
  • Ubuntu下python-opencv无法打开摄像头,open VIDEOIO(V4L2:/dev/video0): can‘t open camera by index

    我们在ubuntu下使用opencv获取摄像头画面是,报错 open VIDEOIO(V4L2:/dev/video0): can‘t open camera by index 然后观察虚拟机桌面的右下角,如果出现摄像头有小绿点表示连接成功 然后我们来测试一下,摄像头的画面 ####### 这是摄像头传输回来的画面

    2024年02月16日
    浏览(46)
  • 【Linux驱动】Linux--V4L2视频驱动框架

    v4l2驱动框架主要的对象有video_device、v4l2_device、v4l2_subdev、videobuf video_device 一个字符设备,为用户空间提供设备节点(/dev/videox),提供系统调用的相关操作(open、ioctl…) v4l2_device 嵌入到video_device中,表示一个v4l2设备的实例 v4l2_subdev 依附在v4l2_device之下,并表示一个v4l2设备的子

    2024年02月14日
    浏览(31)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包