Mv series camera appnotes 4 rpi/zh

From wiki_veye
Jump to navigation Jump to search

English

1 概述

MV系列相机是为工业领域的AI应用推出的相机。其使用MIPI CSI-2接口,尤其适合嵌入式运算平台使用。它具备丰富的数据格式和触发特性,极低的延时,极高的带宽和可靠的稳定性。

本文介绍了如何在树莓派平台使用MV系列相机。

1.1 支持的模组

系列 型号 状态
MV系列 MV-MIPI-IMX178M 完成
MV系列 MV-MIPI-SC130M 完成
MV系列 MV-MIPI-IMX287M 完成
MV系列 MV-MIPI-IMX296M 完成
MV系列 MV-MIPI-IMX265M 完成
MV系列 MV-MIPI-IMX264M 完成
RAW系列 RAW-MIPI-SC132M 完成

2 硬件准备及安装

MV系列相机需要使用ADP-MV1转接板才能连接到树莓派。下面以MV-MIPI-IMX178M为例,介绍硬件的安装方法。

2.1 MV-MIPI-IMX178M与ADP-MV1的连接

二者使用0.5mm间距*30P的FFC异面线连接,注意接触面向外。

TOP BOTTOM
ADP-MV1 to MV-MIPI-X
ADP-MV1 to MV-MIPI-X


2.2 ADP-MV1与树莓派的连接

2.2.1 供电

ADP-MV1需要独立的5V供电,可以使用杜邦线直接从树莓派主板取电。

ADP-MV1 power supply


2.2.2 树莓派Model B和Model B+

二者使用1mm间距*15P的FFC异面线连接,注意接触面安装方向。

MV camera and RPI connection
MV camera and RPI connection


2.2.3 树莓派Zero,Zero W和Computer Module

二者使用15P转22P的FFC同面线连接,注意接触面安装方向。

MV camera and Raspberry Pi zero connection
MV camera and Raspberry Pi CM4


3 piOS的配置

具体安装树莓派系统方法请参考官方文档,详见:Install raspberrypi guide

接通电源后,树莓派系统启动,初始树莓派系统中Camera 和 I2C都处于未启用状态。开机后我们需要将其手动打开,执行命令

sudo raspi-config

raspi-config bullseye

进入Interface Options,启用I2C,然后重启树莓派。

建议启用树莓派系统的ssh服务及samba服务,这里不再赘述树莓派系统如何开启ssh和samba服务。

4 Legacy模式和V4L2模式介绍

这两个模式的区别,树莓派官网有详细的介绍。树莓派网站上提到的libcamera-stack模式与我们所说的V4L2模式架构上一致。

4.1 Legacy模式

传统模式,依赖博通的GPU进行图像处理。传统的raspicam软件集即采用此模式。此模式缺点是封闭。GPU端是闭源的,无法自由接入sensor。树莓派组织已经全面转向libcamera camera stack。

但是此模式依然有存在的价值:

  1. 更多的使用GPU资源,降低CPU负载。这点对于性能比较差的早期版本树莓派很有用。
  2. 可以简单直接的获取图像数据到应用层,无需驱动层的支持。这点对于不依赖树莓派做isp的相机尤其有用。
  3. libcamera现在还缺乏一些功能支持。

有两种方法可以使用Legacy模式:

  1. 使用Legacy版本的piOS。
  2. 对于bullseye版本piOS,raspi-config中打开Legacy Camera选项。

由于两种工作模式不能共存,因此使用V4L2模式时需要关闭Legacy模式。

4.2 libcamera以及V4L2模式

现在piOS已全面切换为libcamera-stack模式。

libcamera-stack本质上以实现isp功能为核心,这点是MV系列相机不需要的。因此,我们采用了V4L2模式,而不是使用libcamera-stack。

与libcamera-stack相同,我们的V4L2模式,也实现了linux驱动层标准的V4L2驱动。基于此驱动,应用层可以直接开发程序获取图像并进行进一步处理。

5 配置命令行全局变量

为了后面描述方便,此处根据sensor尺寸,配置全局变量。

  • MV-MIPI-IMX178M

export WIDTH=3088

export HEIGHT=2064

export FPS=22

  • MV-MIPI-SC130M

export WIDTH=1280

export HEIGHT=1024

export FPS=108

  • MV-MIPI-IMX296M

export WIDTH=1440

export HEIGHT=1088

export FPS=60

  • MV-MIPI-IMX287M

export WIDTH=704

export HEIGHT=544

export FPS=319

  • MV-MIPI-IMX265M

export WIDTH=2048

export HEIGHT=1544

export FPS=45

  • MV-MIPI-IMX264M

export WIDTH=2432

export HEIGHT=2056

export FPS=28

  • RAW-MIPI-SC132M

export WIDTH=1080

export HEIGHT=1280

export FPS=120

6 V4L2模式用法

我们在这个github仓库保存了v4l2模式的代码。

6.1 下载驱动包

wget https://github.com/veyeimaging/raspberrypi_v4l2/releases/latest/download/raspberrypi_v4l2.tgz

6.2 安装驱动

tar -xzvf raspberrypi_v4l2.tgz

cd raspberrypi_v4l2/release/

chmod +x *

sudo ./install_driver.sh veye_mvcam

然后重启树莓派。

备注:如果提示无法找到对应版本的驱动,说明我们没有提供对应您的piOS版本编译后的驱动程序。请尝试从源码编译。

6.3 卸载驱动

如需更换为Legacy模式,或者想要更换成其他摄像头模组型号的驱动,必须要先卸载现在的驱动。

sudo ./uninstall_driver.sh veye_mvcam

6.4 系统状态验证

以MV-MIPI-IMX178M为例:

dmesg | grep mvcam

可以看到linux启动阶段probe到的相机型号和以及相机的版本号:

camera is: MV-MIPI-IMX178M

firmware version: 0x1080102

并且/dev/video0 节点存在,证明摄像头状态正常。

6.5 v4l2-ctl 应用范例

6.5.1 安装v4l2-utils

sudo apt-get install v4l-utils

6.5.2 yavta安装

git clone git://git.ideasonboard.org/yavta.git

cd yavta;make

6.5.3 使用v4l2-ctl配置参数
6.5.3.1 列出相机支持的数据格式

v4l2-ctl --list-formats-ext

ioctl: VIDIOC_ENUM_FMT

        Type: Video Capture

        [0]: 'GREY' (8-bit Greyscale)

                Size: Discrete 3088x2064

        [1]: 'Y10P' (10-bit Greyscale (MIPI Packed))

                Size: Discrete 3088x2064

        [2]: 'Y10 ' (10-bit Greyscale)

                Size: Discrete 3088x2064

        [3]: 'Y12P' (12-bit Greyscale (MIPI Packed))

                Size: Discrete 3088x2064

        [4]: 'Y12 ' (12-bit Greyscale)

                Size: Discrete 3088x2064

        [5]: 'UYVY' (UYVY 4:2:2)

                Size: Discrete 3088x2064

需要特别说明的是,MV系列相机提供的UYVY模式仅作调试使用,且图像宽度不能超过2880。

6.5.3.2 列出驱动中实现的相机的可配置参数

v4l2-ctl -L

User Controls

                horizontal_flip 0x00980914 (bool)   : default=0 value=0

                  vertical_flip 0x00980915 (bool)   : default=0 value=0

                   trigger_mode 0x00981901 (int)    : min=0 max=2 step=1 default=0 value=0 flags=volatile

                    trigger_src 0x00981902 (int)    : min=0 max=1 step=1 default=1 value=1 flags=volatile

                    soft_trgone 0x00981903 (button) : flags=write-only, execute-on-write

                     frame_rate 0x00981904 (int)    : min=0 max=22 step=1 default=22 value=22 flags=volatile

可以使用下面的方法设置和获取参数。

v4l2-ctl --set-ctrl [ctrl_type]=[val]

v4l2-ctl --get-ctrl [ctrl_type]

以上所有功能,均可使用mv_mipi_i2c.sh实现。

需要指出的是,以上参数在开始取图的状态均不可修改。下面进行逐个说明:

6.5.3.3 配置翻转
  • 水平翻转

v4l2-ctl --set-ctrl horizontal_flip=1

  • 垂直翻转

v4l2-ctl --set-ctrl vertical_flip=1

6.5.3.4 配置触发模式

v4l2-ctl --set-ctrl trigger_mode=[0-2]

0:流模式

1:普通触发模式

2:快速连续触发模式

6.5.3.5 配置触发源

v4l2-ctl --set-ctrl trigger_src=[0-1]

0: 软触发

1: 硬触发

6.5.3.6 软触发一次

v4l2-ctl --set-ctrl soft_trgone=1

6.5.3.7 设置帧率

v4l2-ctl --set-ctrl frame_rate=[1-max]

随分辨率的调整,最大帧率会自动更新。

6.5.3.8 设置ROI

举例:

  • 对于MV-MIPI-IMX178M

v4l2-ctl --set-selection=target=crop,top=32,left=64,width=2592,height=1944

  • 对于MV-MIPI-SC130M

v4l2-ctl --set-selection=target=crop,top=32,left=64,width=640,height=640

设置roi后,最大帧率会自动调整。

6.6 流模式

6.6.1 设置ROI

v4l2-ctl --set-selection=target=crop,top=0,left=0,width=$WIDTH,height=$HEIGHT

6.6.2 设置帧率

v4l2-ctl --set-ctrl frame_rate=$FPS

6.6.3 可使用如下命令进行帧率统计

v4l2-ctl --set-fmt-video=width=$WIDTH,height=$HEIGHT,pixelformat=GREY --stream-mmap --stream-count=-1 --stream-to=/dev/null

6.6.4 保存图片到文件
6.6.4.1 MV-MIPI-IMX178M
  • raw8格式

v4l2-ctl -d /dev/video0 --set-fmt-video=width=3088,height=2064,pixelformat=GREY --stream-mmap --stream-count=1 --stream-to=y8-3104x2064.raw

或者

./yavta -c1 -Fy8-3104x2064.raw --skip 0 -f Y8 -s 3088x2064 /dev/video0

由于Raspberry Pi为图像申请的内存,宽度为32对齐,高度为16对齐,所以3088*2064的图像将被保存为3104*2064大小。

  • raw10格式

v4l2-ctl -d /dev/video0 --set-fmt-video=width=3088,height=2064,pixelformat='Y10 ' --stream-mmap --stream-count=1 --stream-to=y10-3088x2064.raw

  • raw12格式

v4l2-ctl -d /dev/video0 --set-fmt-video=width=3088,height=2064,pixelformat='Y12 ' --stream-mmap --stream-count=1 --stream-to=y12-3088x2064.raw

6.6.4.2 MV-MIPI-SC130M
  • raw8格式

v4l2-ctl -d /dev/video0 --set-fmt-video=width=1280,height=1024,pixelformat=GREY --stream-mmap --stream-count=1 --stream-to=y8-1280x1024.raw

  • raw10格式

v4l2-ctl -d /dev/video0 --set-fmt-video=width=1280,height=1024,pixelformat='Y10 ' --stream-mmap --stream-count=1 --stream-to=y10-1280x1024.raw

6.6.4.3 MV-MIPI-IMX296M
  • raw8格式

v4l2-ctl -d /dev/video0 --set-fmt-video=width=1440,height=1088,pixelformat=GREY --stream-mmap --stream-count=1 --stream-to=y8-1440x1088.raw

  • raw10格式

v4l2-ctl -d /dev/video0 --set-fmt-video=width=1440,height=1088,pixelformat='Y10 ' --stream-mmap --stream-count=1 --stream-to=y10-1440x1088.raw

6.6.4.4 MV-MIPI-IMX265M
  • raw8格式

v4l2-ctl -d /dev/video0 --set-fmt-video=width=2048,height=1544,pixelformat=GREY --stream-mmap --stream-count=1 --stream-to=y8-2048x1544.raw

  • raw10格式

v4l2-ctl -d /dev/video0 --set-fmt-video=width=2048,height=1544,pixelformat='Y10 ' --stream-mmap --stream-count=1 --stream-to=y10-2048x1544.raw

  • raw12格式

v4l2-ctl -d /dev/video0 --set-fmt-video=width=2048,height=1544,pixelformat='Y12 ' --stream-mmap --stream-count=1 --stream-to=y12-2048x1544.raw

6.6.4.5 MV-MIPI-IMX264M
  • raw8格式

v4l2-ctl -d /dev/video0 --set-fmt-video=width=2432,height=2056,pixelformat=GREY --stream-mmap --stream-count=1 --stream-to=y8-2432x2056.raw

  • raw10格式

v4l2-ctl -d /dev/video0 --set-fmt-video=width=2432,height=2056,pixelformat='Y10 ' --stream-mmap --stream-count=1 --stream-to=y10-2432x2056.raw

  • raw12格式

v4l2-ctl -d /dev/video0 --set-fmt-video=width=2432,height=2056,pixelformat='Y12 ' --stream-mmap --stream-count=1 --stream-to=y12-2432x2056.raw

6.6.4.6 RAW-MIPI-SC132M
  • raw8格式

v4l2-ctl -d /dev/video0 --set-fmt-video=width=1080,height=1280,pixelformat=GREY --stream-mmap --stream-count=1 --stream-to=y8-1088x1280.raw

  • raw10格式

v4l2-ctl -d /dev/video0 --set-fmt-video=width=1080,height=1280,pixelformat='Y10 ' --stream-mmap --stream-count=1 --stream-to=y10-1088x1280.raw

6.6.4.7 MV-MIPI-IMX287M
  • raw8格式

v4l2-ctl -d /dev/video0 --set-fmt-video=width=704,height=544,pixelformat=GREY --stream-mmap --stream-count=1 --stream-to=y8-704x544.raw

  • raw10格式

v4l2-ctl -d /dev/video0 --set-fmt-video=width=704,height=544,pixelformat='Y10 ' --stream-mmap --stream-count=1 --stream-to=y10-704x544.raw

  • raw12格式

v4l2-ctl -d /dev/video0 --set-fmt-video=width=704,height=544,pixelformat='Y12 ' --stream-mmap --stream-count=1 --stream-to=y12-704x544.raw

图片格式请参考下面:raw data图片格式说明 章节。

6.6.5 实时预览

export DISPLAY=:0

为了方便进行安装和调试,MV系列相机提供了UYVY模式。UYVY模式支持的最大宽度为2880,使用如下命令可以进行实时预览。

6.6.5.1 MV-MIPI-IMX178M

v4l2-ctl -d /dev/video0 --set-fmt-video=width=2816,height=2064,pixelformat=UYVY

gst-launch-1.0 v4l2src device=/dev/video0 ! "video/x-raw,format=(string)UYVY, width=(int)2816, height=(int)2064, framerate=(fraction)22/1" ! v4l2convert ! "video/x-raw,format=(string)NV12" ! autovideosink sync=false -v

6.6.5.2 MV-MIPI-SC130M, MV-MIPI-IMX296M, MV-MIPI-IMX265M,MV-MIPI-IMX264M,MV-MIPI-IMX287M

v4l2-ctl --set-selection=target=crop,top=0,left=0,width=$WIDTH,height=$HEIGHT

v4l2-ctl --set-ctrl frame_rate=$FPS

gst-launch-1.0 v4l2src device=/dev/video0 ! "video/x-raw,format=(string)UYVY, width=(int)$WIDTH, height=(int)$HEIGHT,framerate=(fraction)$FPS/1" ! v4l2convert ! "video/x-raw,format=(string)NV12" ! autovideosink sync=false -v

6.7 触发模式

本节以IMX178为例,讲述一下触发模式的配置和使用。其他摄像头,参考流模式的宽高推论即可。

6.7.1 设置ROI和帧率

v4l2-ctl --set-selection=target=crop,top=0,left=0,width=$WIDTH,height=$HEIGHT

v4l2-ctl --set-ctrl frame_rate=$FPS

6.7.2 软触发模式
6.7.2.1 设置模式

v4l2-ctl --set-ctrl trigger_mode=1

v4l2-ctl --set-ctrl trigger_src=0

6.7.2.2 开始取图

v4l2-ctl --set-fmt-video=width=3088,height=2064,pixelformat=GREY --stream-mmap --stream-count=5 --stream-to=y8-3104x2064.yuv

6.7.2.3 进行软触发操作

在其他的shell终端,可以多次执行下面命令进行多次触发。

v4l2-ctl --set-ctrl soft_trgone=1

6.7.3 硬触发模式

下面以使用树莓派GPIO21为模拟触发源,上升沿触发为例。

可以使用mv_mipi_i2c.sh脚本进行丰富的触发参数设置。

6.7.3.1 硬件连接
MV camera hardware trigger connection


6.7.3.2 设置模式

v4l2-ctl --set-ctrl trigger_mode=1

v4l2-ctl --set-ctrl trigger_src=1

6.7.3.3 开始取图

v4l2-ctl --set-fmt-video=width=3088,height=2064,pixelformat=GREY --stream-mmap --stream-count=5 --stream-to=y8-3104x2064.raw

6.7.3.4 进行硬触发操作

python gpio_trigger.py

Note:触发脚本链接

6.8 CM4的补充说明

cm4支持两路摄像头同时使用,采用上面的步骤安装的dtbo将只能使用CAM1。如需使用两路摄像头,请按如下步骤:

6.8.1 硬件连接

参考树莓派这个说明,将J6进行短接。

6.8.2 更新dt-blob.bin

sudo wget https://datasheets.raspberrypi.com/cmio/dt-blob-dualcam.bin -O /boot/dt-blob.bin

6.8.3 对于Buster系统(kernel5.10)

更新双摄像头的dtbo,

以mvcam为例:

sudo cp raspberrypi_v4l2/release/driver_bin/$(uname -r)/veye_mvcam-cm4.dtbo /boot/overlays/veye_mvcam.dtbo

sudo reboot

6.8.4 对于Bullseye系统(kernel5.15+)

手动编辑/boot/config.txt文件,增加一行dtoverlay=[camera],cam0,如下所示:

[all]

dtparam=i2c_vc=on

dtoverlay=veye_mvcam

dtoverlay=veye_mvcam,cam0

6.8.5 设备文件说明

CM4模块采用两路I2C分别与两个摄像头通信。

description i2c bus num video node
CAM0 0 video0
CAM1 10 video2(Buster),video1(Bullseye)

注:只连一个摄像头,无论CAM0还是CAM1,都是video0。

6.9 从源代码编译驱动方法

请参考:树莓派平台上摄像头驱动源码编译指南

7 Legacy模式用法

我们在这个github仓库中存储legacy模式的代码。

7.1 下载软件包

git clone https://github.com/veyeimaging/mvcam_raspberrypi.git

增加可执行权限

chmod +x -R ./mvcam_raspberrypi/

7.2 软件包主要内容介绍

camera_i2c_config:自动识别不同的树莓派板型,并控制power on 引脚给摄像机供电。

mv_raspicam:实现图像预览、图片保存等功能。

mv_mipi_i2c.sh:通过i2c协议读取和设置相机参数的脚本。

veye_i2c_upgrade:相机固件升级工具。

7.3 相机上电

./camera_i2c_config

相机上电后,可以执行:

i2cdetect -y 10

出现0x3b的设备,则表明相机已启动,并且i2c通道正常工作。

7.4 视频预览

./mv_raspicam -t -1 -roi 0,0,3088,2064 -md 0

其中 -md指明像素数据格式:

-md option data type
0 8bit Y
1 10bit Y
2 12bit Y

-roi可以指明需要的roi尺寸。

对于宽度超过1920的尺寸,mv_raspicam 会先将图像缩小一倍,然后进行预览显示。

7.5 保存图片

./mv_raspicam -t 1000 -roi 0,0,3088,2064 -md 0 -sr 10 -o /dev/shm/y8-3104x2064_%04d.raw

-sr是存储图片的间隔,这里每间隔10张图片保存一张。

-t 1000,单位是ms,这里表示1秒。

完成后在/dev/shm/目录下会保存下几个文件。

7.6 触发模式

本章节需要使用mv_mipi_i2c.sh,请参考下面相关i2c参数配置方法章节

7.6.1 软触发
7.6.1.1 设置模式

./mv_mipi_i2c.sh -w -f trgmode -p1 1

./mv_mipi_i2c.sh -w -f trgsrc -p1 0

7.6.1.2 设置触发属性

可以设置触发数量,触发间隔等。下面设置单次触发5张,每张间隔1毫秒。

./mv_mipi_i2c.sh -w -f trgnum -p1 5

./mv_mipi_i2c.sh -w -f trginterval -p1 1000

7.6.1.3 开始取图

./mv_raspicam -t -1 -roi 0,0,3088,2064 -md 0

7.6.1.4 进行软触发操作

在其他的shell终端,可以多次执行下面命令进行多次触发。

./mv_mipi_i2c.sh -w -f trgone

7.6.2 硬触发
MV camera hardware trigger connection
7.6.2.1 设置模式

本次以高速连续触发为例

./mv_mipi_i2c.sh -w -f trgmode -p1 2

./mv_mipi_i2c.sh -w -f trgsrc -p1 1

7.6.2.2 设置触发属性

高速连续触发下,触发间隔无效。这次触发2张。

./mv_mipi_i2c.sh -w -f trgnum -p1 2

设置上升沿触发

./mv_mipi_i2c.sh -w -f trgedge -p1

此外,还可以对硬触发设置丰富的触发属性,如触发延迟、信号过滤等。

7.6.2.3 开始取图

./mv_raspicam -t -1 -roi 0,0,3088,2064 -md 0

7.6.2.4 进行硬触发操作

python gpio_trigger.py

Note:触发脚本链接

8 raw data图片格式说明

8.1 具有填充位的图片格式

对于10bit深度、12bit深度的像素数据,总是使用两个字节来存储一个像素。用不到的高位以0填充。V4L2标准的'Y10 ' (10-bit Greyscale),'Y12 ' (12-bit Greyscale)格式都是以这种方式存储的。

这种存储方式方便软件处理,缺点是空间占用较大。

8.2 紧密排列的图片格式

mv_raspicam保存的数据格式就是mipi总线上的数据格式,像素和像素之间不会进行空bit位填充。

V4L2标准的'Y10P' (10-bit Greyscale (MIPI Packed)),'Y12P' (12-bit Greyscale (MIPI Packed))格式都是以这种方式存储的。

Packed raw data layer


8.2.1 紧密排列图片大小

Buffersize= ALIGN_UP(width*bit_depth/8,32)*ALIGN_UP(height,16)

行buffersize需要是32字节的整数倍;列buffersize是16字节的整数倍。

举例来说,3088*2064@8bit的图像大小是6406656; 3088*2064@10bit的图像大小是7991808;3088*2064@12bit 的图像大小是9576960。

8.3 转换工具

我们编写了一个小工具:pixel_layer_convert,可以很方便的将紧密排列的图片转为具有填充位的图片。

比如下面的命令,可以将一个3088宽度的packed raw10 图片转为unpacked raw10。

./pixel_layer_convert -I Y10P -i y10-3088x2064_0001.raw -o y10-3088x2064_0001_new.raw -w 3088

8.4 raw图片播放器

推荐使用vooya作为播放器,支持GREY, 和具有填充位的图片格式。

Y8文件可以用这个播放器: YUV Displayer Deluxe

9 shell脚本进行参数配置

我们提供了shell脚本来配置参数。

mv_mipi_i2c.sh user guide

10 参考资料

11 问题反馈

我们致力于为嵌入式平台的图像应用提供更丰富的可能性。因此,我们在嵌入式平台的软件基于开源的原则而进行。

如对我们现有软件有任何的问题、建议,欢迎提交到论坛:,或者给我们的技术人员发邮件xumm#csoneplus.com。

12 本文修改记录

  • 20230326

增加MV-MIPI-IMX287M的支持。

  • 20230304

增加Bullseye系统中CM4的相关说明。

  • 20230210

V4L2模式下增加了CM4的说明。

  • 20221208

增加了MV-MIPI-IMX264M的支持。

  • 20221102

增加了IMX265和SC132新型号的支持。

  • 2022-05-16

提供了图片格式转换工具。

  • 2022-04-14

第一个版本