这是一个文章系列的一部分,介绍基于MK802这类MiniPC的扩展开发,并展示他在计算机视觉、机器人控制方面的潜能
欢迎转载,但请保留原始作者信息(Shikai Chen, http://www.csksoft.net),以及指向本文原始出处的链接!
访问目录:基于MK802 MiniPC的扩展开发应用-简介篇(http://www.csksoft.net/blog/post/mk802_dev_intro.html)
revision: 0
这是本系列文章的最后一篇了。本文将以如下几个基于MK802的应用实例进行介绍,向大家展示MK802在机器人控制以及计算机视觉方面的应用潜力。
1. 基于MK802的摄像头自动光源跟踪
2. 基于MK802的人脸摄像机云台跟踪
3. MK802将路由器网络通讯情况显示与VFD屏幕
这些是例子基于了我前5篇文章[1][2][3][4][5]所介绍的各类技巧和环境所形成的,这里我就假设大家已经阅读过先前的文章了,这里将以介绍思路和原理的方式来介绍这些实例。如果想进一步了解他们的实现,可以在本系列文章在github开设的项目中查看他们的源代码,在前一篇文章[5]中我也介绍了如何编译他们的。
Demo applications run on MK802 MiniPC to show MK802 potential in OpenCV and arduino related areas
另外之前也有一些朋友表示这些实例使用的算法并不高级,性能也不佳。这里我就做一个统一的回应,本系列文章介绍的这些实例的目的并不是去实现这些功能本身,这些实例目前的确存在更好地实现。我制作这些实例的目的是为了向大家介绍MK802用于机器人控制和计算机视觉算法处理方面的强大潜能,因此我都尽可能使用了被大家熟知或者存在于OpenCV例子当中的程序作为范本。至于如何将这些例子进行改进扩充,就是靠大家发扬光大了:-)。
另外还有很多人会问这些例子能不能在树梅派、MK802的后续升级版本、XXXXX上面实现?这里我再次重复前几篇文章的说明,这里介绍的一切方法和思路对所有基于Linux的系统有效。当然,如果只是简单的复制这里的步骤,那恐怕只能用于MK802了。
1. 实例一:基于MK802的摄像头自动光源跟踪
在前文[4][5]中我分别介绍了如何使用MK802通过Arduino控制2轴云台舵机以及如何用MK802采集摄像头画面并调用OpenCV库进行视觉运算。这里我们将这两者结合起来,做一个有趣的应用:会自动跟随光源的摄像头。
其效果如下视频所示:
图:本实例效果图
这个例子中,MK802会定位摄像头画面中的发光物体的位置。一旦发现了这类物体后,将控制舵机云台上下左右移动,进而调整摄像头的拍摄画面,把光源定位到摄像头的视野中央。
通过这样的不断控制,就实现了一个总是跟踪光源移动的摄像头了。
这个例子的功能可以应用到机器人的跟随当中,另外,例子中的光源也可以修改成特定色彩、特定形状或者特性图案的物体。
原理简介
这里的算法需要解决2个主要问题:
- 在画面中提取最亮点并定位
- 将光点相对于画面中央的偏移量,转换成对舵机的控制量
对于第一个问题,主要的方法就是在图像进行二值化后,使用blob提取算法进行定位,他的具体过程这里不再贴出代码,大家可以去github直接阅读它的代码。
图:摄像头画面在MK802中进行的CV处理
经过上述处理后,MK802将得到摄像头画面中光点的坐标信息,为了用于后续的跟踪控制,需要将该坐标变换成相对于画面中心点的坐标。为了演示和调试,我将完成上述处理的画面显示在了VFD上:
图:VFD上显示的光点定位画面
有了光点相对于画面中心点的坐标后,就可以将它用于对舵机的控制了。不过这里的偏移信息和舵机的控制信息(旋转偏移量)是不同的物理量,不能直接将这个偏移数据传递到舵机。因此这里采用了类似PID[]方式的一个控制算法,具体可以看例子给出的代码
实现舵机的平滑运动
一般我们会按照如下的单线程方式进行上述算法:
这样的算法本身并没有问题,但是对于MK802来说运算性能并不如PC。上述的算法无法实现30fps(摄像头的输出刷新率)的运行效率,实际在MK802上该算法大约为20fps。这样会导致对舵机的控制信号不连贯,在人看来,舵机的运动将变得不连贯不自然。因此这里把对舵机的控制逻辑安排在一个单独线程当中,以比较高的控制频率(60hz)来控制舵机,从而使得舵机的运动变得平滑。而视觉识别算法将在另外一个线程当中执行,并定期将提取的光点坐标通过共享内存发送到舵机控制线程。
不过由于60hz相比图像识别算法来说快很多,因此在2次视觉识别算法提供出坐标信息的间隙,舵机控制算法就需要进行运动估计。
图:采用将视觉运算和舵机控制线程分离的方式实现平滑的舵机运动
程序的使用
如果你准备好了对应的硬件,则可以使用下面的命令执行本实例:
图:程序启动时的提示画面
程序启动后将出现如下画面,此时将手电这类发光物体放入摄像头视野,就可以开始跟踪。
2. 实例二:基于MK802的人脸摄像机云台跟踪
这个例子对前面的光源跟踪做了扩展,实现了对人脸的跟随。相比光源来说,跟踪人脸更加具有趣味性,可以用来制作很多有趣的玩意。另外相对光源来说人脸识别的抗干扰性强很多。
图:本实例的工作效果
可以观看下面的演示视频了解本例子的具体工作情况:
本实例的代码:
原理简介
本实例是在上一个例子的框架基础上制作的,因此总体的原理和之前的例子一样,只是这里使用了人脸识别的算法,将画面中人脸的位置提取出来,作为后续舵机控制的参考信号。
对于人类的识别,我简单的使用了OpenCV中的CascadeClassifier分类器[6]进行对人类的识别过程。并且直接使用了OpenCV附带例子中的训练数据。因此对于他的原理,大家就可以直接去参考OpenCV给出的文档了。
图:识别人脸的效果
不过这个分类器的运算量比较大,对于MK802来说已经是比较大的负担。我将摄像头画面缩小了4倍后进行CascadeClassifier处理,大概只能实现8fps的运行速度。不过后来对MK802进行超频[2]后,发现该算法的运行效率也有一定的改观。
下图是该实例的框图:
图:本实例的框架图
另外得益于前面提到的平滑舵机控制的策略,这里即使人脸识别只有8fps的性能,但是舵机的运动依旧平滑流畅。但是还是受限于识别算法的运行效率,从视频中大家就可以感觉到舵机跟踪具有比较大的延迟了。
程序的使用:
如果拥有对应的硬件,就可以使用如下命令执行本程序:
其中参数/dev/ttyUSB0表示了VFD屏幕的串口设备,/dev/ttyUSB1表示了舵机云台的串口设备,需要按照自身情况替换。
程序启动后,将展示如下画面,这时请对着摄像头看,大概保持半米的距离,此时本实例就可开始工作。
图:本实例的初始启动画面
3. 实例三:MK802将路由器网络通讯情况显示与VFD屏幕
这里介绍一个与计算机视觉和机器人控制关系不大,但是也比较有趣的例子。从家庭路由器中读取网络访问量情况,并显示在VFD上。
图:通过MK802在VFD屏幕显示网络的通讯统计信息
可以观看下面的演示录像:
该例子的代码:
工作原理
该实例将定期从网络路由器上获取当前外网的访问带宽,并将其绘制成曲线图。这里主要的问题是如何从路由器中获得这个数据。对此我用了一个简单的实现,直接从安装有DD-WRT[7]固件的路由器的bandwidth页面中抓取该数据。考虑到目前市面上很多路由器都可以安装DD-WRT固件,因此这个方法还是具有普遍性的。(OpenWRT的固件也可以实现)
首先我们观察下DD-WRT中那个流量显示页面:
图:dd-wrt中的流量显示画面
通过查看网页源代码,可以知道这类画面是使用SVG[8]产生的。比如上述页面对应地址:
查看该svg文件的源代码,可以提取出用于获取网络带宽数据的url接口:
访问该页面会得到如下的数据:
图:浏览器访问带宽信息获取url接口的画面
分析前面svg中的javascript代码可以知道上述信息的含义。这里我们在命令行下用curl抓取这个页面:
Tue Nov 27 12:51:19 UTC 2012
ppp0: 88641492 138399 0 0 0 0 0 0 14653513 73958 0 0 0 0 0 0
(上述脚本包含在本实例代码中)
可以发现实际返回的数据有两行,第一行是当前时间,而第二行中,我们只关注其中那个88641492以及14653513这两个数据。按照对javascript代码的解读,他们分别是当前路由器发送数据和接受数据的总字节量。
因此,我们只需要定期抓取这个页面的数据,并通过时间差就可以换算成发送和接受的速度信息了。
随后我们利用OpenCV提供的简单的绘图功能,将上述数据显示在VFD上即可。
3. 总结
这个系列的文章到此就全部结束了。我从如何在MK802上自制系统开始,分别介绍了如何给MK802开发第一个hello world程序到运行基于OpenCV的视觉算法程序以及如何与Arduino这类外设通讯的过程。另外也给出了一些对Mk802硬件和kernel修改的例子和背后的思路。而这篇文章介绍的几个例子都是建立在之前的工作基础上的。
这里希望这个系列文章对大家有所帮助。同时我也希望大家不要局限于文章介绍的MK802平台上,毕竟这个平台将来会不断地升级直到淘汰,因此针对他的那些操作流程不久就会失效。但是文章中介绍的各种思路和方法是永远不会过时的。
4. 参考文献
[1] 第一部分:MK802的系统自制
http://www.csksoft.net/blog/post/mk802_dev_sysbuild.html
[2] 第二部分:MK802的软/硬件修改和扩展
http://www.csksoft.net/blog/post/mk802_dev_hacks.html
[3] 第三部分:基于MK802的应用开发和相关的工具
http://www.csksoft.net/blog/post/mk802_dev_devtools.html
[3] 第四部分:MK802与外部硬件设备的通讯
http://www.csksoft.net/blog/post/mk802_dev_devtools.html
[4] 第五部分:在MK802上结合OpenCV库进行计算机视觉处理
http://www.csksoft.net/blog/post/mk802_dev_opencv.html
[5] PID controller
http://en.wikipedia.org/wiki/PID_controller
[6] CascadeClassifier
http://docs.opencv.org/doc/tutorials/objdetect/cascade_classifier/cascade_classifier.html
[7] DD-WRT
http://www.dd-wrt.com/site/index
[8] Scalable Vector Graphics (SVG)
http://en.wikipedia.org/wiki/Scalable_Vector_Graphics