Blog:
在嵌入式 Linux 系统使用摄像头
本博文介绍了在 计算机模块(COM) / 系统模块(SOM)上查看和记录视频的多种方法。本章使用的计算机模块是成本敏感产品的理想选择,其不带视频硬件编解码器。
俗话说“眼见为实”,这或许是为什么近年来摄像头在嵌入式系统上快速增长的原因。它们被用于不同的场景,如:
- 远程监控:典型的例子是闭路电视,监控人员在监视环境(或许你所在的大楼就有)或者警察监控城市状况。
- 安防录像:监视系统或许能够记录视频,并不是所有的监控系统都一直需要监视人员,它们只是在有情况发生时提供监控证据。
- 嵌入式视觉系统:计算机监控系统处理图像从而获取更加复杂的信息。我们可以在雷达和城市交通监控系统中看到类似的应用。
- 作为传感器:许多医疗诊断系统都是基于图像分析。另外一个应用是智能购物窗,鉴别用户的特征,提供针对性的营销。
我们将会使用 Colibri VF61 模块,其采用 NXP®/Freescale Vybrid 处理器,这是一个异构双核处理器(Arm® Cortex-A5 + Arm Cortex-M4)。除了处理器,模块还有 256MB RAM 和 512 MB Flash。这本博文中,我们将只用到 Cortex™-A5。尽管没有硬件视频加速器,你还是可以用该处理器完成许多视频相关的任务。更多关于 Colibri VF61 的信息和说明可以参考 Toroadex 网站的 开发者中心。
摄像头是 Logitech HD 720p,一般的 mjpeg USB 模块和 D-Link DCS-930L IP 摄像头。
本为使用的 Linux 有 LXDE 桌面环境,这也是我们标准的镜像。我们的标准镜像可以在从 开发者中心网站。本次所使用的是 V2.4 版本镜像。我们将会使用在多媒体应用中广泛使用的 GStreamer 框架。GStreamer 提供了诸如视频编辑、媒体传输和播放等多媒体应用服务。一系列的插件使得 GStreamer 能够支持许多不同的媒体格式,如 MP3、ffmpeg 等。这些插件包括输入和输出组件、滤镜、编解码器等。
该指导基于我们的 V2.4 Linux 镜像所编写并测试。在写这篇文章时,V2.5 缺失一个 GStreamer 所依赖软件的源。目前我们正在调查这个问题。解决方案是,你可以从下面的链接中手动下载和安装缺失的依赖软件:
http://feeds.angstrom-distribution.org/feeds/v2015.06/ipk/glibc/armv7ahf-vfp-neon/base
这是安装 GStreamer、Video4Linux2 以及其他软件所需要的。在模块的终端里运行下面的命令:
opkg update opkg install gst-plugins-base-meta gst-plugins-good-meta gst-ffmpeg
通过 gst-inspect 命令,你可以看到之前安装的插件和组件。下面是一些安装的插件和组件。
根据 GStreamer Application Development Manual 中 第三章所述,element 是 GStreamer 中最重要的对象。通常你可以创建一个相互连接的 element 链,数据从 element 链上经过。每一个 element 都有特定的功能,例如读取文件、解码、显示等。element 组合成的链成为 pipeline,这可以用于执行特定的任务,如视频播放或者采集。GStreamer 默认包含了大量的 element,使其可以开发各种多媒体应用。在这篇文章中我们会使用一些 pipeline 为您介绍 element。
下面是典型的 Ogg 播放器 pipeline,其中使用一个 demuxer 和两个 branche, 分别用于视频和音频。我们可以看到一些 element 只有 src 输入,其他的只具有一个 sink 或者兼有两者。
在创建 pipeline 的时候,你需要使用 gst-inspect 检查所需的插件是否相互兼容。我们使用 ffmpegcolorspace 作为演示。在终端中运行下面的命令:
gst-inspect ffmpegcolorspace
然后,你可以看到如下关于插件的描述:
Factory Details: Long name: FFMPEG Colorspace converter Class: Filter/Converter/Video Description: Converts video from one colorspace to another Author(s): GStreamer maintainers
以及插件所支持的 source 和 sink:
SRC template: 'src' Availability: Always Capabilities: video/x-raw-yuv video/x-raw-rgb video/x-raw-gray SINK template: 'sink' Availability: Always Capabilities: video/x-raw-yuv video/x-raw-rgb video/x-raw-gray
另外一个例子是 v4l2src.。它只有 source 输入,可以读取源视频并发送到另外一个 element。查看 ximagesink element,我们发现其支持 rgb 格式 sink 输出。
参考下面的文档 http://gstreamer.freedesktop.org/documentation/plugins.html 并配合使用 gst-inspect,能够帮助你了解 element 的功能和他们的属性。
通过下面命令显示测试视频:
gst-launch videotestsrc ! autovideosink
autovideosink \element 自动检测视频输出。videotestsrc 用于生产各种格式的测试视频,可以使用 pattern 参数进行设置。
gst-launch videotestsrc pattern=snow ! autovideosink
连接的网络摄像头会在 /dev/videox 目录下显示,其中 x 可以是 0、1、2 等,这取决于连接到电脑的摄像头数量。
使用下面命令全屏显示网络摄像头:
gst-launch v4l2src device=/dev/video0 ! ffmpegcolorspace ! ximagesink
下面的连接展示了全屏模式网络摄像头: video_webcam_fullscr.mp4
Video4Linux 是捕捉和播放的 API 以及驱动框架,支持多种类型的 USB 摄像头和设备。v4l2src 是 Video4Linux2 的一个插件,从 Video4Linux2 设备中读取数据帧,在我们的演示中这就是网络摄像头。
ffmpegcolorspace 是一个用于转化多种色彩格式的滤镜。摄像头一般输出 YUV 色彩格式,然而显示则使用 RGB 格式。
ximagesink 基于桌面 X 的标准 videosink。
我们可以使用 top 命令查看显示网络摄像头视频时 gstreamer 所使用的是 CPU 和内存资源。在第一个演示中,我们看到了 77.9% 的 CPU 负载。.
top - 16:32:37 up 4:36, 2 users, load average: 0.83, 0.28, 0.13 Tasks: 72 total, 1 running, 70 sleeping, 0 stopped, 1 zombie Cpu(s): 69.3%us, 7.1%sy, 0.0%ni, 0.0%id, 0.0%wa, 0.0%hi, 23.6%si,0.0%st Mem: 235188k total, 107688k used, 127500k free, 0k buffers Swap: 0k total, 0k used, 0k free, 61232k cached PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ CoMMAND 1509 root 20 0 39560 8688 6400 S 77.9 3.7 0:16.83 gst-launch-0.10 663 root 20 0 17852 8552 4360 S 19.7 3.6 4:12.32 X 1484 root 20 0 2116 1352 1144 R 1.3 0.6 0:00.80 top
也可以使用诸如 size 等其他参数的属性来显示视频。width、height 和 framerate 参数可以根据摄像头所支持进行配置。针对摄像头1、2、3 分别执行一下命令(这里连接了 3 个摄像头)显示 320x240 或者其他格式的视频。
gst-launch v4l2src device=/dev/video0 ! 'video/x-raw-yuv,width=320,height=240,framerate=30/1' ! ffmpegcolorspace ! ximagesink
gst-launch v4l2src device=/dev/video1 ! 'video/x-raw-yuv,width=320,height=240,framerate=30/1' ! ffmpegcolorspace ! ximagesink
gst-launch v4l2src device=/dev/video2 ! 'video/x-raw-yuv,width=320,height=240,framerate=30/1' ! ffmpegcolorspace ! ximagesink
本次,CPU 负荷为 28.2%。
你可以同时显示两个摄像头。我们使用下面的 Logitech HD 720p 摄像头和一般的 MJPEG USB 摄像头模组测试下面的 pipeline 。
gst-launch v4l2src device=/dev/video0 ! 'video/x-raw-yuv,width=320,height=240,framerate=30/1' ! ffmpegcolorspace ! ximagesink v4l2src device=/dev/video1 'video/x-raw-yuv,width=320,height=240,framerate=30/1' ! ffmpegcolorspace ! ximagesink
下面的链接是双网络摄像头同时显示的视频: video_duas_webcams.mp4
这个测试中 CPU 负荷为 64.8%。
使用下面 pipeline 录制 MP4 格式的视频:
gst-launch --eos-on-shutdown v4l2src device=/dev/video0 ! ffmux_mp4 ! filesink location=video.mp4
命令 --eos-on-shutdown 用于正确关闭文件。ffenc_mjpeg 是 MJPEG 格式编码器参数。 ffmux_mp4 MP4 格式混合器。filesink 表明来自 v4l2 的数据需要存储在一个文件中,而不是在 ximagesink 中显示。你也可以指定目标目录。
您可以观看下面链接的视频: recording_video1.mp4来查看模块所录制视频的质量。
录制以上视频大致需要 8% 的 CPU 负载。
使用下面的 pipeline 播放方才录制的视频:
gst-launch filesrc location=video.mp4 ! qtdemux name=demux demux.video_00 ! queue ! ffdec_mjpeg ! ffmpegcolorspace ! ximagesink
这时,视频源来自于 filesrc,例如视频来自一个文件,而不是网络摄像头视频设备。这个视频之前使用 mjepg 编码,所以需要使用 ffdec_mjpeg 解码。
由于之前网络摄像头使用最大分辨率录制的视频,CPU 负载在 95% 左右。
我们使用下面的 pipeline 查看之前录制的视频:
gst-launch souphttpsrc location=http://upload.wikimedia.org/wikipedia/commons/4/4b/MS_Diana_genom_Bergs_slussar_16_maj_2014.webm ! matroskademux name=demux demux.video_00 ! queue ! ffdec_vp8 ! ffmpegcolorspace ! ximagesink
souphttpsrc 使用 HTTP 通过网络作为客户端接收数据。在这个应用中,location 参数使用包含视频文件的 URL,而不是文件。注意,ffdec_vp8 被用于解码 webm 格式。
这时,CPU 负载大致为 40%。
我们也可以从 VF61 模块上向运行 Ubuntu Linux 的电脑传输视频。
IP VF61 = 192.168.0.8
IP Ubuntu = 192.168.0.7
在 VF61 终端上运行下面的 pipeline:
gst-launch v4l2src device=/dev/video1 ! video/x-raw-yuv,width=320,height=240 ! ffmpegcolorspace ! ffenc_mjpeg ! tcpserversink host=192.168.0.7 port=5000
同时在电脑主机上运行下面 pipeline 查看传输的视频:
gst-launch tcpclientsrc host=192.168.0.8 port=5000 ! jpegdec ! autovideosink
注意,IP 地址需要根据您的配置情况调整。在终端中运行 ifconfig 查看您的 IP 地址。
下面的链接是上面演示的视频: video_streaming_webcam.mp4
这里使用 Logitech HD 720p 摄像头,CPU 负载大约 65%。
这例子中,我们使用 D-Link DCS-930L 网络摄像头。该摄像头被配置成传输 320x240,15fps 的一般质量 JPEG 格式视频。CPU 的负载会根据网络摄像头设置的不同而变换。
在模块的终端上,使用下面的 pipeline 查看网络摄像头视频:
gst-launch -v souphttpsrc location='http://192.168.0.200/video.cgi' is-live=true ! multipartdemux ! decodebin2 ! ffmpegcolorspace ! ximagesink
下面的链接是以上演示视频: video_streaming_ipcam.mp4
您也可以在 VF61 上使用下面 pipeline:
gst-launch --eos-on-shutdown –v souphttpsrc location='http://192.168.0.200/video.cgi' is-live=true ! multipartdemux ! decodebin2 ! ffmpegcolorspace ! ffenc_mjpeg ! ffmux_mp4 ! filesink location=stream.mp4
您可以观看下面的视频来分析录像的质量: video_gravacao_ipcam.mp4
摄像头分辨率 320x240, 15fps,一般 JPEG 质量, CPU 复杂大约为 40%。
这次我们将从一个网络摄像头传输视频到 VF61 模块,并且同时向另外一个 IP 传输视频。
在 VF61 模块终端上执行下面命令:
gst-launch --eos-on-shutdown –v souphttpsrc location='http://192.168.0.200/video.cgi' is-live=true ! multipartdemux ! decodebin2 ! ffmpegcolorspace ! ffenc_mjpeg ! Tcpserversink host=192.168.0.12 port 5000
此时,CPU 负载为 95%。
使用下面命令在 Linux 电脑上查看来自模块的视频:
gst-launch tcpclientsrc host=192.168.0.8 port=5000 ! jpegdec ! autovideosink
Test performed |
%CPU | %MEM |
Displaying Video From a Webcam | 28.2 | 2.7 |
Displaying Two Cameras Simultaneously | 64.8 | 3.1 |
Recording Video | 8.0 | 4.9 |
Video Playback | 95.0 | 3.9 |
Video Playback Using HTTP | 41.9 | 4.1 |
Video Streaming Using TCP | 66.0 | 3.6 |
Displaying Video from IP camera | 25.2 | 3.3 |
IP camera recording | 40.1 | 3.9 |
TCP streaming IP to IP | 95.2 | 4.8 |
文章涉及到的内容,包括 GStreamer 各种变量的理论研究和学习,需要花费几天时间。掌握 plugins 和 使用 gst-inspect,你可以查看每个 plugin 的属性,组建各个 elements 之间相互兼容的 pipeline。同时,在网上也有大量例子,可以帮助你组建 pipeline。读者或许也需要向本文一样进行研究。安装和检查 plugin 属性对于组建 pipeline 以及找到于文中所用设置兼容的 GStreamer element 十分有必要。
NXP/Freescale Vybrid VF61 处理器能满足多种媒体和视频处理的要求,即使没有针对这些任务的特定硬件加速器。该处理器在执行视频和图形相关任务时所表现的性能,我们对此感到十分惊讶。
VF61 Vybrid 是不需要太多视频处理需求的成本敏感型嵌入式设备的理想选择。但是对于需要以更好的性能处理视频时,例如嵌入式视觉系统,我们建议使用同样来自 NXP/Freescale 的 iMX6,其带有专门的视频处理器。
- https://www.toradex.com/computer-on-modules/colibri-arm-family/freescale-vybrid-vf6xx
- http://gstreamer.freedesktop.org/documentation/plugins.html
- http://wiki.lxde.org/
- http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/index.html
- http://developer.toradex.com/knowledge-base/camera-interface-on-toradex-computer-modules
- http://developer.toradex.com/knowledge-base/webcam-(linux)
- http://developer.toradex.com/knowledge-base/video-playback-(linux)#Video_Playback_on_Vybrid_Modules
- http://developer.toradex.com/knowledge-base/multi-camera-module-linux
- http://developer.toradex.com/knowledge-base/how-to-use-usb-webcam
- http://en.wikipedia.org/wiki/GStreamer
- http://www.freedesktop.org/software/gstreamer-sdk/data/docs/latest/gst-plugins-base-plugins-0.10/index.html
- http://pt.wikipedia.org/wiki/Codec
- http://pt.wikipedia.org/wiki/Codec_de_vídeo
- http://gstreamer.freedesktop.org/data/doc/gstreamer/0.10.36/manual/manual.pdf
- 图2: http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/images/simple-player.png
- 图9: http://www.premiumstore.com.br/images/product/DCDLDCS930L_1.jpg
本博文最初以葡萄牙语在 Embarcados.com 发表. 请查看这里。
KIms - 7 years 7 months | Reply
It would be neat to see a sister-article to this, that looks at a front+rear facing car dash-cam with GPS and text overlay on the recordings, with a focus on file management and handling continuous recordings.