ARM Linux平台下 OpenCV Camera 实验

一、硬件原理

1. OV2640

1.1 基本功能

OV2640 是一款低功耗、高性能的图像传感器,支持以下功能:

  • 最高分辨率:200 万像素(1600x1200)。

  • 输出格式:JPEG、YUV、RGB。

  • 内置图像处理功能:自动曝光、自动白平衡、自动增益控制等。

1.2 硬件接口

2. CSI

2.1 基本功能

CSI 是一种高速串行接口,专为摄像头模块设计,具有以下特点:

  • 支持高带宽数据传输(适合高分辨率和高帧率视频)。

  • 低引脚数,减少硬件复杂度。

  • 支持多种数据格式(如 RAW、YUV、RGB)。

2.2 硬件原理

CSI 接口通常包括以下信号:

  • 数据通道(Data Lanes)

    • 差分信号对(如 CSI_D0+/CSI_D0-)。

    • 支持 1-4 对数据通道,带宽随通道数增加。

  • 时钟通道(Clock Lane)

    • 差分信号对(如 CSI_CLK+/CSI_CLK-)。

    • 用于同步数据传输。

  • 控制信号

    • I2C 或 SPI 接口,用于配置摄像头模块。

2.3 工作流程

  1. 初始化:通过 I2C 或 SPI 配置摄像头模块。

  2. 数据传输

    • 摄像头模块通过 CSI 数据通道发送图像数据。

    • 主控设备通过 CSI 时钟通道同步接收数据。

  3. 数据处理:主控设备对接收到的图像数据进行处理或存储。

二、设备树

根节点

复制代码
&csi {
	status = "okay";

	port {
		csi1_ep: endpoint {
			remote-endpoint = <&ov2640_ep>;
		};
	};
};

&i2c1 {
    ov2640: ov2640@30 {
		compatible = "ovti,ov2640";
		reg = <0x30>;
		pinctrl-names = "default";
		pinctrl-0 = <&pinctrl_csi1>;
		clocks = <&clks IMX6UL_CLK_CSI>;
		clock-names = "csi_mclk";
		/*pwn-gpios = <&gpio1 4 1>;*/
		rst-gpios = <&gpio1 2 0>;
		/*csi_id = <0>;
		mclk = <24000000>;
		mclk_source = <0>;*/
		status = "okay";
		port {
			ov2640_ep: endpoint {
				remote-endpoint = <&csi1_ep>;
			};
		};
	};
};

三、驱动简单分析

四、Qt 编写测试文件

1. 简介

Qt 里有一个 QCamera 类,但是不支持4.1.15 内核版本上使用 OV5640、OV2640。

因为 OV5640、OV2640 的驱动默认是读取 YUYV 格式数据,而 QCamera 里读取的数据是 RGB 格式数据。当然也能通过修改驱动来支持。不过有 V4l2 框架,就没必要这么做了。V4l2 的数据直接可以显示在 fb0,且处理效率比 Qt 来的流程。

直接使用 V4l2 的方案留在后面的视频监控项目上。本次使用的是 Qt+OpenCV 调用摄像头。

OpenCV 的环境搭建:ARM Linux 移植 tslib、Qt和OpenCV-CSDN博客

2. 主要功能

  • 摄像头管理

    • selectCameraDevice(int index):选择并打开指定索引的摄像头
    • cameraProcess(bool bl):控制摄像头的启动和停止
    • timerTimeOut():定时采集摄像头图像并发送信号
  • 图像处理

    • matToQImage(const cv::Mat &img):将 OpenCV cv::Mat 格式转换为 Qt QImage 格式
  • 定时器机制

    • 使用 QTimer 控制图像采集频率(33ms,约等于 30fps)

3. 程序编写

3.1 .pro 文件

添加 opencv 库

cpp 复制代码
INCLUDEPATH += /home/prover/linux/opencv-3.4.1/install/include
LIBS += /home/prover/linux/opencv-3.4.1/install/lib/libopencv_core.so \
 /home/prover/linux/opencv-3.4.1/install/lib/libopencv_highgui.so \
 /home/prover/linux/opencv-3.4.1/install/lib/libopencv_imgproc.so \
 /home/prover/linux/opencv-3.4.1/install/lib/libopencv_videoio.so \
 /home/prover/linux/opencv-3.4.1/install/lib/libopencv_imgcodecs.so

3.2 简单分析

3.3 编译

cpp 复制代码
source /opt/fsl-imx-x11/4.1.15-2.1.0/environment-setup-cortexa7hf-neon-poky-linux-gnueabi
/home/prover/linux/qt-5.12.9/arm-qt/bin/qmake
make -j 8

五、测试

1. 手动加载

将内核源码的drivers/media/paltform/mxc/subdev 中的mx6s_capture.c 单独拿出来编译 .ko文件

然后将 ov2640_driver.ko 和 mx6s_capture.ko 文件进行加载即可。

一般加载后,设备为 /dev/video1。然后运行第四节的 Qt 程序即可。

2. 内核修改

配置 4.1.15 内核

按1进入

按Y选中,并进入红框

红框默认是 M 的,改成 Y,并选择 VF SDC。

还有这个也要选中:

如果不出意外的话,就会出意外了:

修改内核源码中的 drivers/media/platform/mxc/capture/ 下的 ipu_prp_vf_sdc.c和ipu_prp_vf_sdc_bg.c

重新编译下内核。

发现取消绑定了。

然后加载自己写的驱动,当然也可以编入到内核的 drivers/media/paltform/mxc/capture:

运行测试前,可以添加格式:drivers\media\platform\mxc\subdev\mx6s_capture.c

复制代码
static struct mx6s_fmt formats[] = {
	{
		.name		= "UYVY-16",
		.fourcc		= V4L2_PIX_FMT_UYVY,
		.pixelformat	= V4L2_PIX_FMT_UYVY,
		.mbus_code	= MEDIA_BUS_FMT_UYVY8_2X8,
		.bpp		= 2,
	}, {
		.name		= "YUYV-16",
		.fourcc		= V4L2_PIX_FMT_YUYV,
		.pixelformat	= V4L2_PIX_FMT_YUYV,
		.mbus_code	= MEDIA_BUS_FMT_YUYV8_2X8,
		.bpp		= 2,
	}, {
		.name		= "YUV32 (X-Y-U-V)",
		.fourcc		= V4L2_PIX_FMT_YUV32,
		.pixelformat	= V4L2_PIX_FMT_YUV32,
		.mbus_code	= MEDIA_BUS_FMT_AYUV8_1X32,
		.bpp		= 4,
	}, {
		.name		= "RAWRGB8 (SBGGR8)",
		.fourcc		= V4L2_PIX_FMT_SBGGR8,
		.pixelformat	= V4L2_PIX_FMT_SBGGR8,
		.mbus_code	= MEDIA_BUS_FMT_SBGGR8_1X8,
		.bpp		= 1,
	}, {
		.name		= "RGB565_LE",
		.fourcc		= V4L2_PIX_FMT_RGB565,
		.pixelformat	= V4L2_PIX_FMT_RGB565,
		.mbus_code	= MEDIA_BUS_FMT_RGB565_2X8_LE,
		.bpp		= 2,
	}, {
		.name		= "RGB565_BE",
		.fourcc		= V4L2_PIX_FMT_RGB565,
		.pixelformat	= V4L2_PIX_FMT_RGB565,
		.mbus_code	= MEDIA_BUS_FMT_RGB565_2X8_BE,
		.bpp		= 2,
	}, {
		.name		= "JPEG",
		.fourcc		= V4L2_PIX_FMT_JPEG,
		.pixelformat	= V4L2_PIX_FMT_JPEG,
		.mbus_code	= MEDIA_BUS_FMT_JPEG_1X8,
		.bpp		= 2,
	}
};

一般加载后,设备为 /dev/video0.

然后运行第四节的 Qt 程序即可。

相关推荐
秋风&萧瑟6 分钟前
【QT】QT的多界面跳转以及界面之间传递参数
开发语言·qt
kfepiza43 分钟前
Debian/Ubuntu的networking的`/etc/network/interfaces`配置文件,如何配置route路由
linux·网络·tcp/ip·ubuntu·debian·ip·tcp
Esun_R1 小时前
使用防火墙与 fail2ban 防止公网服务器被攻击
linux
榆榆欸2 小时前
4.Socket类、InetAddr类、Epoll类实现模块化
linux·c++·tcp/ip
易保山3 小时前
MIT6.S081 - Lab6 Copy-on-Write(写时复制)
linux·操作系统·c
獨枭3 小时前
Linux 下安装和使用 Jupyter Notebook
linux·chrome·jupyter
Monee..3 小时前
linux里安装pip和conda
linux·conda·pip
AAA废品回收站陈师傅4 小时前
10乱码问题的解释(1)
qt
长流小哥4 小时前
可视化开发:用Qt实现Excel级动态柱状图
开发语言·c++·qt·ui
阳区欠4 小时前
【Linux】进程通信
linux·运维·服务器·共享内存·进程通信·system v·管道文件