)
将采用D415深度学习相机连接全志OK527板子通过mipi屏幕做一个人脸识别系统。本文所做工作是将相机连接板子并在屏幕上输出画面。此环节的流程大概是硬件连接后检查-是否识别到usb-dmesg看内核日志看是否绑定上对应驱动-检查设备文件找到相机对应的设备文件-打开D415设备文件下对应的彩色节点-输出彩色画面。1.检查是否识别到usb相机通过USB3.0与板子连接连上后需要检查是否识别到usb设备输入命令input:lsusb output: Bus 003 Device 001: ID 1d6b:0002 Bus 001 Device 001: ID 1d6b:0002 Bus 004 Device 001: ID 1d6b:0001 Bus 002 Device 001: ID 1d6b:0003 Bus 003 Device 003: ID 8086:0ad3 Bus 003 Device 002: ID 1a40:0101Bus表示总线号后面的Device代表根设备观测输出查官方设备号表可知8086:0ad3即为D415相机的设备号其挂载在总线3下的003号根设备上而Linux设定总线下的Device001代表的ID后面四位表示其对应的USB代次通过Bus 003 Device 001: ID 1d6b:0002可发现3号总线对应的是USB2.0而相机是USB3.0说明插错了usb口随后重新插到USB3.0上。2.观察是否绑定了对应驱动而后需要查内核看是否绑定了对应驱动输入命令inputdmesg | grep -iE uvc|8086|RealSense|video output usbcore: registered new interface driver uvcvideo//说明本板子中存在uvcvideo驱动设备 usb 3-1.3: New USB device found, idVendor8086, idProduct0ad3, bcdDevice51.10 usb 3-1.3: Product: Intel(R) RealSense(TM) Depth Camera 415 usb 3-1.3: Manufacturer: Intel(R) RealSense(TM) Depth Camera 415 uvcvideo 3-1.3:1.1: Unknown video format 00000050-0000-0010-8000-00aa00389b71 usb 3-1.3: Found UVC 1.50 device Intel(R) RealSense(TM) Depth Camera 415 (8086:0ad3) input: Intel(R) RealSense(TM) Depth Ca as /devices/platform/soc3000000/4200000.ehci1-controller/usb3/3-1/3-1.3/3-1.3:1.0/input/input19 usb 3-1.3: Found UVC 1.50 device Intel(R) RealSense(TM) Depth Camera 415 (8086:0ad3) # ← 这是 USB2 / EHCI看上一行路径里的 ehci1-controller usb 1-1: New USB device found, idVendor8086, idProduct0ad3, bcdDevice51.10 usb 1-1: Product: Intel(R) RealSense(TM) Depth Camera 415 usb 1-1: Manufacturer: Intel(R) RealSense(TM) Depth Camera 415 uvcvideo 1-1:1.1: Unknown video format 00000050-0000-0010-8000-00aa00389b71 usb 1-1: Found UVC 1.50 device Intel(R) RealSense(TM) Depth Camera 415 (8086:0ad3) input: Intel(R) RealSense(TM) Depth Ca as /devices/platform/soc3000000/12.usbc2/4d00000.xhci2-controller/xhci-hcd.23.auto/usb1/1-1/1-1:1.0/input/input20 usb 1-1: Found UVC 1.50 device Intel(R) RealSense(TM) Depth Camera 415 (8086:0ad3) # ← 这是 USB3 / xHCI要用的看上一行路径里的 xhci-hcd由于内核日志太多因此需要从全本日记里面筛关键词-iE代表忽视大小写而搜索uvc是因为USB 摄像头在 Linux 上几乎都走 UVC驱动名是uvcvideo8086是刚刚看到的idRealSense是深度相机的厂家型号video在摄像头文件里面涉及最广。从日志输出来看由于刚才误插入2.0后又改成插入3.0所以出现了两次插入历史。usb 1-1: Found UVC 1.50 device Intel(R) RealSense(TM) Depth Camera 415 (8086:0ad3)表示挂载在总线1的1号口上且已绑定uvc并被当成了UVC1.5设备。3.检查设备文件找到相机对应的设备文件目前确定了设备已经绑定了驱动之后需要找到对应的设备文件才能进行后续的文件操作输入input: ls -l /dev/video* which v4l2-ctl output: crw-rw---- 1 root video 81, 0 Jan 1 08:00 /dev/video0 crw-rw---- 1 root video 81, 37 Jan 1 08:02 /dev/video1 crw-rw---- 1 root video 81, 3 Jan 1 08:00 /dev/video12 crw-rw---- 1 root video 81, 4 Jan 1 08:00 /dev/video16 crw-rw---- 1 root video 81, 5 Jan 1 08:00 /dev/video17 crw-rw---- 1 root video 81, 38 Jan 1 08:02 /dev/video2 crw-rw---- 1 root video 81, 39 Jan 1 08:02 /dev/video3 crw-rw---- 1 root video 81, 1 Jan 1 08:00 /dev/video4 crw-rw---- 1 root video 81, 40 Jan 1 08:02 /dev/video5 crw-rw---- 1 root video 81, 41 Jan 1 08:02 /dev/video6 crw-rw---- 1 root video 81, 42 Jan 1 08:02 /dev/video7 crw-rw---- 1 root video 81, 2 Jan 1 08:00 /dev/video8 /usr/bin/v4l2-ctl通过ls可以初步确认存在video设备节点但无法确认具体的设备节点是哪个一般来说给项目open的设备文件都是挂载在/dev下面。通过时间戳其实也可以初步辨别再插上D415相机后出现了video1/2/3/5/6/7。然而不同的节点其功能不同对于当前需要输出彩色画面需要找到对应的彩色节点。因此需要用到v4l2-ctl调试工具V4L2 是 Linux 里摄像头以及部分视频采集/输出设备的标准接口。而v4l2-ctl 是在命令行里操作 V4L2 设备的工具用于发现设备文件查询并修改文件参数还可以取走节点数据。通过which命令找到了工具的位置下面需要用工具找到对应的彩色节点。4.找到D415设备文件下对应的彩色节点输入input v4l2-ctl --list-devices for d in /dev/video1 /dev/video2 /dev/video3 /dev/video5 /dev/video6 /dev/video7; do echo $d v4l2-ctl -d $d --list-formats-ext 2/dev/null | head -n 25 done output: sunxi-vin (): /dev/video0 /dev/video4 /dev/video8 /dev/video12 /dev/video16 /dev/video17 Allwinner Vin (platform:sunxi-vin-media): /dev/media0 Intel(R) RealSense(TM) Depth Ca (usb-xhci-hcd.23.auto-1): /dev/video1 /dev/video2 /dev/video3 /dev/video5 /dev/video6 /dev/video7 /dev/media1 /dev/media2 /dev/video1 ioctl: VIDIOC_ENUM_FMT Type: Video Capture [0]: Z16 (16-bit Depth) Size: Discrete 256x144 ... 90 fps Size: Discrete 480x270 / 640x360 / 640x480 / 848x480 / 1280x720 各种帧率 /dev/video2 ioctl: VIDIOC_ENUM_FMT Type: Video Capture 下面没有 [0]没有格式 /dev/video3 ioctl: VIDIOC_ENUM_FMT Type: Video Capture [0]: GREY (8-bit Greyscale) 480x270 / 640x360 / 640x480 / 848x480 / 1280x720 [1]: UYVY (UYVY 4:2:2) head 截断只看到 480x270 开头 /dev/video5 ioctl: VIDIOC_ENUM_FMT Type: Video Capture 同样没有格式 /dev/video6 ioctl: VIDIOC_ENUM_FMT Type: Video Capture [0]: YUYV (YUYV 4:2:2) 424x24060/30/15/6 fps 640x48030/15/6 fps 1280x72015/10/6 fps 1920x10808 fps /dev/video7 ioctl: VIDIOC_ENUM_FMT Type: Video Capture 没有格式通过v4l2-ctl --list-devices指令能够按「哪台相机」把 /dev/video* 分组列出来从输出可以看出有三组sunxi代表全志片内的CSI/VIN摄像头接口ALLwinner Vin代表同一套 VIN 的 媒体控制器节点用来描述内部管线相当于全志这块 VIN视频输入硬件内部怎么接线的说明书在下面的Intel RealSense即表示深度相机设备可以看出其对应的节点。而下面的for.....命令则是对 D415 那几个节点逐个问「你会什么格式」好从里面挑出彩色口其具体解释如下for d in /dev/video1 /dev/video2 /dev/video3 /dev/video5 /dev/video6 /dev/video7; do 对列表里每一个路径把名字存进变量 d循环一遍。这里故意没写 video0/4/8/...那些是空的 sunxi-vin。 echo $d 先打印 /dev/video6 这类分隔否则六段输出会糊成一坨。 v4l2-ctl -d $d --list-formats-ext 2/dev/null | head -n 25 -d $d问当前这个节点 --list-formats-ext格式、分辨率、帧率 2/dev/null报错不刷屏空节点常有 ioctl 失败 head -n 25每个节点最多 25 行避免某口分辨率特别多把串口刷爆 done 结束循环。通过输出可得知各个节点对应的含义其中YUYV代表彩色节点因此/dev/video6即为所要找的彩色节点对应节点含义如下5.输出彩色画面目前已经找到了彩色节点下面需要对节点进行读取操作不同于点灯程序的是相机文件更加复杂节点得到的元数据需要按照对应的协议进行解码转换输出才能最终得到彩色画面一般来说为了简便使用可以直接调用GStreamer或者FFmeg框架这些框架内部提供现成的程序帮助直接进行取流转换操作输入命令input which gst-launch-1.0 ffplay gst-play-1.0 export XDG_RUNTIME_DIR/var/run output /usr/bin/gst-play-1.0 /usr/bin/gst-launch-1.0用which命令查找是否存在对应框架程序从输出可看出出厂镜像带 GStreamer没有 ffplay。不必交叉编译预览程序。export用于给当前串口会话设环境变量不设的话管道往往取流成功但画不到 MIPI。不过其只对当前终端有效重开 Xshell 或重启要再执行一次。找到框架程序后输入命令input gst-launch-1.0 v4l2src device/dev/video6 ! video/x-raw,formatYUY2,width640,height480,framerate30/1 ! videoconvert ! waylandsink 对应含义 v4l2src device/dev/video6打开彩色口 video/x-raw,formatYUY2,width640,height480,framerate30/1指定 640×48030和 v4l2-ctl 列出的能力一致适合 1024×600 小屏 videoconvert转格式 waylandsink画到 Weston/MIPI执行输入程序后摄像头打开工作按 Ctrl C停止程序。针对输入命令的最后一项。“waylandsink画到 Weston/MIPI”代表通过 Wayland 协议把相机帧交给 Weston再显示到 MIPI。Weston是这块板上正在跑的图形桌面Linux 上应用一般不直接操作屏幕中间有一层「谁在管屏幕」管屏幕的那个进程叫 Weston而Wayland 是一套「应用程序怎么把窗口交给屏幕」的协议。而waylandsink是 GStreamer 里专门把画面交给Weston的出口插件。前面export XDG_RUNTIME_DIR/var/run设置环境就是为了让waylandsink能找到Weston的Socket将数据顺利传入进去。不过由于在Xshell一次性粘贴命令时出现了长命令被撕碎的情况且程序运行时反馈刷屏日志因此对输入命令稍作修改如下intput set H dmesg -n 3 export XDG_RUNTIME_DIR/var/run gst-launch-1.0 v4l2src device/dev/video6 ! videoconvert ! waylandsink fullscreentrue set H 关掉 bash 的历史展开。否则命令里的 ! 会被当成「重复上一条命令」整句粘坏。只对当前串口会话有效。 dmesg -n 3 把往控制台打的内核日志压到级别 3。减轻 crtc 94 刷屏方便看到 GStreamer 自己的字。 export XDG_RUNTIME_DIR/var/run 告诉程序去 /var/run 找 Weston 的 Wayland 套接字。waylandsink 靠这个把窗口交给桌面。重开 Xshell 要再执行一次。