Linux上位机开发实战(camera视频读取)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】

关于linux camera,一般都是认为是mipi camera,或者是usb camera。当然不管是哪一种,底层的逻辑都是v4l2,这一点大家都一样。只不过如果使用mipi camera,不仅要适配i2c驱动、mipi驱动、isp驱动,而且相关的协议手册、驱动代码,soc芯片厂家也未必提供的,这一点就比较麻烦。相比较而言,usb camera容易很多,sensor侧的i2c、mipi已经不用自己处理,isp也是usb camera内部的mcu处理好了,所以剩下来的工作,就是usb uvc协议处理。这是一个标准协议。用起来比较方便,也不需要安装额外的驱动,一般linux kernel都包含在内了。

在linux上面要获取图像有两种软件接口,一种就是借助于opencv来处理;另外一种就是自己编写对应的v4l2接口。

1、opencv接口

opencv是我们能够想到的,最简单、最直接的方法。不管是windows平台,还是linux平台,都可以通过opencv来获取图像。获取视频的流程基本就是三步。第一步,创建cv::VideoCapture对象。这个对象的输入参数可以是阿拉伯数字,也可以是具体的文件名。如果是后一种情况,那么就变成从视频读取数据了。

第二步,确认设备是否打开。这一步就是调用一下isOpened()函数即可。第三步,就是直接从cv::VideoCapture导出图像给cv::Mat,导出的方法使用的运算符>>,非常形象。

复制代码
#include <opencv2/opencv.hpp>
#include <iostream>

//#pragma comment(lib, "D:/software/opencv/build/x64/vc16/lib/opencv_world480d.lib")

int main() 
{
    cv::VideoCapture cap(0);

    if (!cap.isOpened()) 
    {
        return -1;
    }

    cv::Mat frame; 
    while (true) 
    {
        cap >> frame;
        if (frame.empty()) 
        {
            break;
        }

        cv::imshow("video", frame);
        if (cv::waitKey(30) == 27) 
        {
            break;
        }
    }

    cap.release();
    cv::destroyAllWindows();

    return 0;
}

2、v4l2接口

v4l2接口是另外一种用的比较多的方式。和opencv相比较,v4l2肯定处理流程上更加复杂一点,但是好处就是我们可以通过v4l2对摄像头做更加精准的控制。一种比较通用的情况就是,我们在实际使用的时候,都会关闭自动曝光,然后通过外部补充光源的形式,实现对光源的精确控制,从而可以保证可以稳定输出高质量的图片。

另外,对于一些自定义的v4l2接口,也是没有办法通过opencv来实现的。所以,对于很多稍微有点规模的图像处理公司来说,它们习惯于自己编写统一的图像接口,兼容windows的directshow和linux的v4l2,这样就不会受到两个平台的约束,类似于这样的api接口,

复制代码
#ifndef _CAMERA_API_H
#define _CAMERA_API_H

#ifdef EXPORTS
#define DLLAPI __declspec(dllexport)
#else
#define DLLAPI __declspec(dllimport)
#endif

extern "C" 
{
DLLAPI int  CameraNumber();
DLLAPI int  EnumCameraIndex(char* vid, char* pid, unsigned char CamIndex[32]);
DLLAPI void*  CameraOpen(int index, int nWidth = 0, int nHeight = 0, const char* data_type = "");
DLLAPI int  CameraClose(void* pCamDev);
DLLAPI int  CameraWidth(void* pCamDev);
DLLAPI int  CameraHeight(void* pCamDev);
DLLAPI char* CameraDataType(void* pCamDev);
DLLAPI char* CameraName(void* pCamDev);
DLLAPI int  CameraQuery(void* pCamDev, unsigned char* szImageBuf);
}

#endif
相关推荐
Dxy12393102163 分钟前
Linux 压缩解压相关命令介绍
linux·运维·服务器
eleven_4u3 分钟前
QPS如何计算,如何部署架构
java·linux·运维·jvm·中间件
云飞云共享云桌面21 分钟前
非标自动化工厂研发部门怎么实现一台服务器带10个SolidWorks设计并发
运维·服务器·人工智能·3d·自动化·电脑·制造
分布式存储与RustFS21 分钟前
你的网站备份只存一块盘?把 1Panel 的备份目标换成 RustFS
运维·开源·备份·对象存储·1panel·s3·rustfs
遇见小修修33 分钟前
打印机无法连接故障:操作误区汇总与排查教程
运维·服务器
东城居士1 小时前
理解Linux RTC驱动
linux·嵌入式系统
Elastic 中国社区官方博客1 小时前
使用 OpenTelemetry 在 Elastic 中实现 Claude 平台的人工智能 agent 可观测性
大数据·运维·服务器·人工智能·elasticsearch·信息可视化·全文检索
hzxxxz1 小时前
3个模块搭稳一条自动化链路:定时任务、幂等与对账
运维·自动化
蘑菇小白1 小时前
Linux多线程开发
linux·开发语言·线程
做萤石二次开发的哈哈1 小时前
商场分区广播怎么开发?商用音频主机四大技能与音频文件管理实践
音视频·蓝海aiot一站式工作台·公共广播·智慧广播·萤石云开放平台·商用音频主机·矩阵路由