关于mipi摄像头demo的相关问题

各位开发者在使用RDK X3板卡时,运行mipi摄像头demo时可能出现报错,此帖关于如下demo的问题给予一些解释和方法。-
感谢飞哥,家乐哥和晟哥的解答和测试。

/app/pydev_demo/03_mipi_camera_sample/mipi_camera.py

目前成功率最高的demo运行方法:

  1. sudo apt update && sudo apt upgrade 升级到最新,重启
  2. 确认mipi摄像头连接完好
  3. 确认为root账户或使用sudo python3拉起程序
  4. 如果使用HDMI显示器,需要确认HDMI显示器符合要求,并且在程序运行前就已经插好
  5. 注意,此demo的画面不能通过VNC展示

特别提示:mipi摄像头必须要在断电的情况下插拔,不然有较大可能损坏。

目录-
一、确认mipi摄像头成功连接的方法-
二、关于HDMI显示器没有画面的相关问题-
三、权限问题导致的运行失败-
四、mipi摄像头或VPS的资源被占用导致没有成功运行-
五、219的Sensor不影响运行的特殊报错-
六、关于RDK X3的mipi摄像头相关的Python接口

一、测试mipi摄像头硬件上成功连接的方法

# 使能sensor的24MHz主时钟
sudo bash -c "echo 1 > /sys/class/vps/mipi_host0/param/snrclk_en"
sudo bash -c "echo 24000000 > /sys/class/vps/mipi_host0/param/snrclk_freq"
# 执行 i2cdetect 命令探测
sudo i2cdetect -y -r 1

如检测不到,用户需要检查FPC排线连接是否正常。成功探测到iic地址时,log打印如下所示。其中显示的 40 即JXF37这颗sensor的i2c设备地址,说明摄像头连接正常。

0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- UU -- -- -- -- 
40: 40 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --

参考手册硬件接口说明:https://developer.horizon.cc/documents_rdk/installation/hardware_interface#mipi_port

二、关于HDMI显示器没有画面的相关问题

有的开发者会遇到这个demo没有画面输出的问题,主要的原因如下:

1. HDMI显示器不符合要求

所插的HDMI显示器不符合板卡要求,板卡在一般情况下,Server版本的系统会显示地平线的LOGO,Desktop版本的系统会显示Ubuntu的桌面。如果能正常显示LOGO或者桌面,显示器是没有问题的。目前HDMI接口支持的显示分辨率如下:1920x1080,1280x720,1024x600,800x480。

用户手册HDMI接口说明:https://developer.horizon.cc/documents_rdk/installation/hardware_interface#hdmi_interface

用户手册认证配件清单:https://developer.horizon.cc/documents_rdk/hardware_development/rdk_x3/accessory#%E6%98%BE%E7%A4%BA%E5%B1%8F

当然有的显示器不是如上配件清单中的显示器,或者不是如上分辨率的显示器,但是这个显示器的主控有硬件上拉伸画面输出的能力(比如我的2K显示器能拉伸RDK X3的1080p的画面,成功显示),也可以成功显示HDMI的画面,但是不一定所有的都能成功,故不推荐这么使用。

2. 使用了VNC来查看该demo的输出画面

通过阅读这个程序源代码可以发现,在代码第309~318行声明了一个使用HDMI显示的对象,程序的输出是从这个HDMI输出的,而VNC是将Ubuntu的图形界面显示在开发机上,并不是将HDMI画面显示到开发机上,所以这个demo是不能通过VNC在显示器上看到画面输出的。

如果想在开发机中体验mipi摄像头推理fcos的模型的画面效果,可以参考第4小点,体验TROS版本的mipi摄像头fcos目标检测的demo。

关于RDK X3的多媒体接口说明,display对象:https://developer.horizon.cc/documents_rdk/python_development/pydev_multimedia_api_x3/object_display

3. 在程序运行后插入HDMI显示器

理由同上,部分显示器可能需要Python的HDMI接口的API中初始化时的某个操作,也就是声明HDMI的display对象时就需要将HDMI显示器连接好,而程序成功运行后初始化已经结束,所以在程序运行后插入HDMI显示器,有一些显示器会无法显示目标检测的画面。

4. TROS版本的mipi摄像头fcos目标检测demo

另外,关于这个demo有一个TROS的版本,在root账户下成功运行后,可以在同一局域网下,访问IP:8000,通过TogetheROS 的Web展示端,看到mipi摄像头推理fcos的模型的画面效果,不需要VNC或者HDMI显示器。其中IP为RDK X3开发板在局域网中的IP地址。

参考网址:https://developer.horizon.cc/documents_tros/boxs/detection/fcos

三、权限问题导致的运行失败

如果在sunrise账户下使用如下命令运行,会出现如下报错

cd /app/pydev_demo/03_mipi_camera_sample/
python3 mipi_camera.py


[C][3911][11-18][09:47:28:476][configuration.cpp:49][EasyDNN]EasyDNN version: 0.5.4
[BPU_PLAT]BPU Platform Version(1.3.3)!
[HBRT] set log level as 0. version = 3.15.25.0
[DNN] Runtime version = 1.18.6_(3.15.25 HBRT)
[A][DNN][packed_model.cpp:234][Model](2023-11-18,09:47:28.653.356) [HorizonRT] The model builder version = 1.6.8
--- model input properties ---
tensor type: NV12_SEPARATE
data type: uint8
layout: NCHW
shape: (1, 3, 512, 512)
--- model output properties ---
tensor type: float32
data type: float32
layout: NHWC
shape: (1, 64, 64, 80)

...省略...

tensor type: float32
data type: float32
layout: NHWC
shape: (1, 4, 4, 1)
Camera: gpio_num=19, active=low, i2c_bus=1, mipi_host=0
Camera: gpio_num=19, active=low, i2c_bus=1, mipi_host=2
Camera 0:
        enable: 1
        i2c_bus: 1
        mipi_host: 0
Camera 1:
        enable: 1
        i2c_bus: 1
        mipi_host: 2
Camera 2:
        enable: 0
        i2c_bus: 0
        mipi_host: 0
No camera sensor found, please check whether the camera connection or video_idx is correct.
2023/11/18 09:47:28.761 ERROR [x3_cam_init_param][0111]vin_param_init failed, -1
[ERROR]["sys"][sys/hb_sys.c:258] [118.014431]HB_SYS_Bind[258]: vps grp 255 chn 255 donot create.

[Module_bind]:[808]:HB_SYS_Bind failed, src:3 pipe:255 chn:255 dst:2 pipe:0 chn:0
Error: vps was not enable
Traceback (most recent call last):
  File "mipi_camera.py", line 345, in <module>
    img = np.frombuffer(img, dtype=np.uint8)
TypeError: a bytes-like object is required, not 'NoneType'
【INFO】: Offload model "fcos_512x512_nv12" Successfully.

主要的报错信息在第37行~39行,camera程序会通过ioctl去打开Sensor的mclk,这里sunrise账户的权限不够,从而没能成功运行。

No camera sensor found, please check whether the camera connection or video_idx is correct.
2023/11/18 09:47:28.761 ERROR [x3_cam_init_param][0111]vin_param_init failed, -1
[ERROR]["sys"][sys/hb_sys.c:258] [118.014431]HB_SYS_Bind[258]: vps grp 255 chn 255 donot create.

细心的开发者会发现,如果使用root账户或者sudo先运行一遍这个demo,后面再使用sunrise账户不带sudo运行这个demo也可以成功运行了,这是因为带sudo运行一遍后,mclk就常开了,后面不带sudo执行也就没问题了。

再多嘴一句解释一下报错信息的第43~46行:

Traceback (most recent call last):
  File "mipi_camera.py", line 345, in <module>
    img = np.frombuffer(img, dtype=np.uint8)
TypeError: a bytes-like object is required, not 'NoneType'

这句Python的报错是因为上面的mipi摄像头没有启动成功,所以没有获取到mipi摄像机的数据流,所以img指向了NoneType,根本原因还是mipi摄像头没有启动成功。

四、mipi摄像头或VPS的资源被占用导致没有成功运行

有时候可能会出现如下错误:

[ERROR]["LOG"][/mnt/data/bsp.rdk/rdk-gen_2023_0619/source/hobot-spdev/src/vpp_swap/src/x3_vio_vin.c:280] HB_VIN_SetDevAttr error!
2023/11/18 12:52:05.851 ERROR [x3_cam_init][0244]x3_vin_init failed, -268565506
[ERROR]["sys"][sys/hb_sys.c:258] [1847.647395]HB_SYS_Bind[258]: vps grp 255 chn 1 donot create.

这时候可能是因为有其他的程序占用了这个资源,或者在其他的终端运行了这个程序。还有一种可能就是上一个使用mipi摄像机的程序没有及时回收mipi摄像机这个资源,或者使用Ctrl + Z来结束程序,mipi摄像机被某个进程占用,导致启动失败。

这时候可以首推使用重启大法

也可以在root账户下使用ps命令来查看是哪一个进程占用了mipi_can的资源,再将这个进程杀掉。

ps

上述命令运行效果如下:

root@ubuntu:~# ps
    PID TTY          TIME CMD
   3845 pts/0    00:00:00 bash
   5099 pts/0    00:00:02 ros2
   5104 pts/0    00:00:03 mipi_cam
   5106 pts/0    00:00:03 hobot_codec_rep
   5108 pts/0    00:00:23 example
   5110 pts/0    00:00:02 websocket
   5269 pts/0    00:00:00 ps

我们看到PID号为5104的进程占用了mipi摄像头,可以使用kill命令将其杀掉,这样就可以正常运行我们的mipi摄像头demo了。特别的,如果杀不掉这个进程,可能是mipi摄像头在子进程中被占用,我们需要杀掉父进程,这里占用mipi的其实是5099的ros2进程,将其kill掉即可。

kill -9 5104

还有一种就是python程序占用了mipi摄像头导致无法成功运行,将其杀掉即可。

root@ubuntu:/app/pydev_demo/03_mipi_camera_sample# ps
    PID TTY          TIME CMD
   3846 pts/0    00:00:00 bash
   3860 pts/0    00:00:04 python3
   3932 pts/0    00:00:00 python3
   3933 pts/0    00:00:00 python3
   3934 pts/0    00:00:00 python3
   3935 pts/0    00:00:00 python3
   3975 pts/0    00:00:00 ps


kill -9 3860

五、219的Sensor不影响运行的特殊报错

有的时候使用IMX219的Sensor成功运行这个demo时,虽然成功运行,能够成功检测出目标并且在终端中输出了检测结果,但是会出现以下的ERROR信息:

[ERROR]["vio_core"][commom_grp/binding_main.c:1725] [4991.140076]comm_dq_fail_process[1725]: dq fail need continue

这个[ERROR]是不影响程序运行的,导致这个问题的是temperMode太高导致,遗留问题。可以在root账户下使用如下命令调整QoS,暂时解决这个问题:

sudo sh -c "echo 120 > /sys/devices/platform/soc/a4001000.sif/hblank"
sudo sh -c "echo 0x10100000 > /sys/bus/platform/drivers/ddr_monitor/axibus_ctrl/all"
sudo sh -c "echo 0x03120000 > /sys/bus/platform/drivers/ddr_monitor/read_qos_ctrl/all"
sudo sh -c "echo 0x03120000 > /sys/bus/platform/drivers/ddr_monitor/write_qos_ctrl/all"

六、报错-35

可能是摄像头open的参数不对导致的,将类似下面的参数行:

cam.open_cam(0, 1, 30, [w, disp_w], [h, disp_h])

修改为:

cam.open_cam(0, -1, 30, [w, disp_w], [h, disp_h])

七、关于RDK X3的mipi摄像头相关的Python接口

文章末尾再多嘴一句,X3关于mipi摄像头有一套专门的Python接口,而不像树莓派一样直接用cv2的接口,VideoCapture直接声明一个摄像机对象来使用mipi摄像头,获取numpy存储的BGR格式图像。

这是一种取舍的结果,没有优劣之分。个人更加喜欢这种接近底层的接口,速度快,资源占用较小,与VPS模块整合较好,可以直接获得nv12的图像数据。与BPU和工具链那边很好的配合上,减少模型推理任务的前处理时间,给予开发者更高的自由度。

如果有需要,可以将mipi摄像头获得的nv12的图像转化为cv2中numpy存储的BGR格式图像,请参考:https://developer.horizon.cc/forumDetail/188481611833243698

挺好