【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱: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