采用的是正点原子店里买的RK3588带显示屏的板子,买来的时候已经装好了linux buildroot系统,我重新烧录过ubuntu的试过,但是他们店里提供的ubuntu烧录的版本缺少太多东西,所以又重新烧录回了linux buildroot系统。
本次通过usb插口直接连接板子,该计算板实际上有多个摄像头插口,原理大同小异,第三章讲述如何在接显示屏的情况下实时显示录取的视频流。第四章讲述如何捕捉帧图像并储存以便用于后续边缘计算
1.准备工作
安装adb和串口插件,这里不过多赘述,关于adb和串口的连接可以看其他文件。
最后效果如下图所示:
2.连接摄像头硬件,并查找系统是否检测到摄像头、
2.1 与边缘计算板连接
通过USB接口或者其他接口连接摄像头设备。
连接后进入串口或通过adb访问边缘计算板子的终端
以下示例均通过win系统下的adb访问边缘计算板子的终端实现,在ubuntu系统下应同理:
adb devices #显示目前adb连接的设备
adb shell #进入边缘计算板子的终端,如通过串口连接可跳过这一步
进入成功后应显示如下:
PS C:\Users\yu467> adb shell
root@ATK-DLRK3588:/#
2.2 确认连接的摄像头设备
插拔摄像头前后分别使用一次以下命令查看新接入的摄像头设备是否有被读取到
ls /dev/video* 命令查看目前已有video设备
两次命令显示结果如下:
root@ATK-DLRK3588:/# ls /dev/video*
/dev/video0 /dev/video18 /dev/video27 /dev/video36 /dev/video7
/dev/video1 /dev/video19 /dev/video28 /dev/video37 /dev/video8
/dev/video10 /dev/video2 /dev/video29 /dev/video38 /dev/video9
/dev/video11 /dev/video20 /dev/video3 /dev/video39 /dev/video-camera0
/dev/video12 /dev/video21 /dev/video30 /dev/video4 /dev/video-dec0
/dev/video13 /dev/video22 /dev/video31 /dev/video40 /dev/video-enc0
/dev/video14 /dev/video23 /dev/video32 /dev/video41
/dev/video15 /dev/video24 /dev/video33 /dev/video42
/dev/video16 /dev/video25 /dev/video34 /dev/video5
/dev/video17 /dev/video26 /dev/video35 /dev/video6
root@ATK-DLRK3588:/# ls /dev/video*
/dev/video0 /dev/video17 /dev/video25 /dev/video33 /dev/video5
/dev/video1 /dev/video18 /dev/video26 /dev/video34 /dev/video6
/dev/video10 /dev/video19 /dev/video27 /dev/video35 /dev/video7
/dev/video11 /dev/video2 /dev/video28 /dev/video36 /dev/video8
/dev/video12 /dev/video20 /dev/video29 /dev/video37 /dev/video9
/dev/video13 /dev/video21 /dev/video3 /dev/video38 /dev/video-camera0
/dev/video14 /dev/video22 /dev/video30 /dev/video39 /dev/video-dec0
/dev/video15 /dev/video23 /dev/video31 /dev/video4 /dev/video-enc0
/dev/video16 /dev/video24 /dev/video32 /dev/video40
v4l2-ctl --list-devices
这个命令用来查看可用的接入设备,因为上面有四十多个video,真正能用来捕捉的可能并没有那么多
root@ATK-DLRK3588:/# v4l2-ctl --list-devices
rk_hdmirx (fdee0000.hdmirx-controller):
/dev/video40
rkisp-statistics (platform: rkisp):
/dev/video29
/dev/video30
/dev/video38
/dev/video39
rkcif-mipi-lvds (platform:rkcif):
/dev/media0
/dev/media1
rkisp_mainpath (platform:rkisp0-vir0):
/dev/video22
/dev/video23
/dev/video24
/dev/video25
/dev/video26
/dev/video27
/dev/video28
/dev/media2
rkisp_mainpath (platform:rkisp1-vir0):
/dev/video31
/dev/video32
/dev/video33
/dev/video34
/dev/video35
/dev/video36
/dev/video37
/dev/media3
USB Camera: USB Camera (usb-fc880000.usb-1.4):
/dev/video41
/dev/video42
/dev/media4
Failed to open /dev/video0: No such device
这样很明显可以看到USB Camera是哪几个
可以看到video41 和video42是我们多出来的设备,应该是我们接入的新摄像头
2.3 查看摄像头摄影规格
v4l2-ctl -d /dev/video41 --list-formats-ext
输出结果:
root@ATK-DLRK3588:/# v4l2-ctl -d /dev/video41 --list-formats-ext
ioctl: VIDIOC_ENUM_FMT
Type: Video Capture
[0]: 'MJPG' (Motion-JPEG, compressed)
Size: Discrete 1280x720
Interval: Discrete 0.017s (60.000 fps)
Interval: Discrete 0.033s (30.000 fps)
Interval: Discrete 0.040s (25.000 fps)
Size: Discrete 800x600
Interval: Discrete 0.017s (60.000 fps)
Interval: Discrete 0.033s (30.000 fps)
Interval: Discrete 0.040s (25.000 fps)
Size: Discrete 640x480
Interval: Discrete 0.017s (60.000 fps)
Interval: Discrete 0.033s (30.000 fps)
Interval: Discrete 0.040s (25.000 fps)
Size: Discrete 352x288
Interval: Discrete 0.017s (60.000 fps)
Interval: Discrete 0.033s (30.000 fps)
Interval: Discrete 0.040s (25.000 fps)
Size: Discrete 320x240
Interval: Discrete 0.017s (60.000 fps)
Interval: Discrete 0.033s (30.000 fps)
Interval: Discrete 0.040s (25.000 fps)
Size: Discrete 176x144
Interval: Discrete 0.017s (60.000 fps)
Interval: Discrete 0.033s (30.000 fps)
Interval: Discrete 0.040s (25.000 fps)
[1]: 'YUYV' (YUYV 4:2:2)
Size: Discrete 1280x720
Interval: Discrete 0.100s (10.000 fps)
Size: Discrete 800x600
Interval: Discrete 0.100s (10.000 fps)
Size: Discrete 640x480
Interval: Discrete 0.100s (10.000 fps)
Size: Discrete 352x288
Interval: Discrete 0.100s (10.000 fps)
Size: Discrete 320x240
Interval: Discrete 0.100s (10.000 fps)
Size: Discrete 176x144
Interval: Discrete 0.100s (10.000 fps)
root@ATK-DLRK3588:/# v4l2-ctl -d /dev/video42 --list-formats-ext
ioctl: VIDIOC_ENUM_FMT
Type: Video Capture
这里表示有两种像素格式,YUYV(原始未压缩) 只给 10fps,MJPG(压缩) 才给 60 fps,用压缩来节约 USB 带宽。然后有多种分辨率,这里的分辨率后面可能会用到。第二个video42的输出结果说明他可能不太适用于当前驱动,没有作用
3 调用屏幕显示摄像
(可选)
如果你有屏幕的话可以尝试,没有就算了
首先要关闭现有的图形界面,以防冲突
killall weston
使用cat活得现在的屏幕大小和图像位数
cat /sys/class/graphics/fb0/bits_per_pixel #获取图像位数
cat /sys/class/graphics/fb0/virtual_size #获取屏幕大小
像素位数为16的一般用rgb565,像素位数为32的一般用bgra/argb 这里用于后面捕获的 -pix_fmt参数
ffmpeg -f v4l2 \
-input_format yuyv422 \
-video_size 640x480 \
-framerate 30 \
-i /dev/video41 \
-vf "scale=1080:1920" \
-f fbdev \
-pix_fmt bgra /dev/fb0
ffmpeg \
-f v4l2 \
-input_format mjpeg \
-video_size 800x600 \
-framerate 30 \
-i /dev/video41 \
-vf "scale=1080:1920" \
-f fbdev \
-pix_fmt bgra /dev/fb0
调用 ffmpeg 程序 强制指定 输入格式 使用 Linux 的 v4l2 驱动(即 /dev/video* 这种摄像头设备)。告诉 ffmpeg:摄像头输出的像素格式是 YUYV422(YUY2)或mjpeg,让摄像头以 640×480 的分辨率输出(有些摄像头需要你给出它支持的分辨率之一)。指定采集帧率 30 FPS,也就是每秒 30 帧(可以低于我们上一小节用的--list-formats-ext里给的参数,但是会受到cpu的能力影响)。输入设备,USB 摄像头对应节点/dev/video41。使用视频滤镜 -vf,把输入画面缩放到 1080×1920。这里的顺序是:scale=宽:高 → 宽 1080、高 1920,是一个竖屏的分辨率(类似手机竖着拿时的分辨率)。
4.抓取图像并保存
4.1抓取一帧
这一步至关重要,抓取图像保存后我们的AI算法就可以直接调用这种图像进行推理。
ffmpeg -f v4l2 \
-framerate 10 \
-video_size 640x480 \
-i /dev/video41 \
-vframes 1 frame_001.jpg
说明:
-f v4l2:从 V4L2 驱动;-framerate 10、-video_size 640x480:根据你摄像头实际设置来写;-vframes 1:只抓 1 帧;vframe表示frame_001.jpg:输出文件名,保存在当前目录(比如/root)。
4.2 一次性抓 N 帧,保存成多张图片
ffmpeg -f v4l2 \
-framerate 10 \
-video_size 640x480 \
-i /dev/video41 \
-vframes 10 frame_%03d.jpg
如果想用实际时间命名,也可以:
ffmpeg -f v4l2\
-framerate 10\
-video_size 640x480\
-i /dev/video41 \
-vframes 10 \
-f image2 \
-strftime 1 "frame_%Y%m%d_%H%M%S_%03d.jpg"
image2:ffmpeg 的一个“图片序列”格式:- 支持
xxx_%03d.jpg这种连续命名; - 每一帧会输出一张独立图片文件。
- 支持
4.3 抓一段视频保存成mp4文件
ffmpeg -f v4l2 \
-framerate 10 \
-video_size 640x480 \
-t 5 \
-i /dev/video41 \
-c:v libx264 -preset veryfast -pix_fmt yuv420p out.mp4
-t 5:采集 5 秒;
out.mp4:保存一个小视频文件。