CSK.Blog--个人原创Weblog

« 在MK802上结合OpenCV库进行计算机视觉处理低成本激光投射虚拟键盘的设计制作-下(算法与实现) »

基于MK802、Arduino和OpenCV库的互动开发

这是一个文章系列的一部分,介绍基于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个主要问题:

  1. 在画面中提取最亮点并定位
  2. 将光点相对于画面中央的偏移量,转换成对舵机的控制量

对于第一个问题,主要的方法就是在图像进行二值化后,使用blob提取算法进行定位,他的具体过程这里不再贴出代码,大家可以去github直接阅读它的代码。

图:摄像头画面在MK802中进行的CV处理

经过上述处理后,MK802将得到摄像头画面中光点的坐标信息,为了用于后续的跟踪控制,需要将该坐标变换成相对于画面中心点的坐标。为了演示和调试,我将完成上述处理的画面显示在了VFD上:

图:VFD上显示的光点定位画面

有了光点相对于画面中心点的坐标后,就可以将它用于对舵机的控制了。不过这里的偏移信息和舵机的控制信息(旋转偏移量)是不同的物理量,不能直接将这个偏移数据传递到舵机。因此这里采用了类似PID[]方式的一个控制算法,具体可以看例子给出的代码

实现舵机的平滑运动

一般我们会按照如下的单线程方式进行上述算法:

读取摄像头一桢画面->进行图像处理->得到Blob坐标->转化为舵机控制信号->控制舵机->读取下一帧。


这样的算法本身并没有问题,但是对于MK802来说运算性能并不如PC。上述的算法无法实现30fps(摄像头的输出刷新率)的运行效率,实际在MK802上该算法大约为20fps。这样会导致对舵机的控制信号不连贯,在人看来,舵机的运动将变得不连贯不自然。因此这里把对舵机的控制逻辑安排在一个单独线程当中,以比较高的控制频率(60hz)来控制舵机,从而使得舵机的运动变得平滑。而视觉识别算法将在另外一个线程当中执行,并定期将提取的光点坐标通过共享内存发送到舵机控制线程。
不过由于60hz相比图像识别算法来说快很多,因此在2次视觉识别算法提供出坐标信息的间隙,舵机控制算法就需要进行运动估计。

图:采用将视觉运算和舵机控制线程分离的方式实现平滑的舵机运动

程序的使用

如果你准备好了对应的硬件,则可以使用下面的命令执行本实例:

LD_LIBRARY_PATH=`pwd` ./lighttrack <VFD串口路径> <控制舵机的Arduino串口路径>

图:程序启动时的提示画面

程序启动后将出现如下画面,此时将手电这类发光物体放入摄像头视野,就可以开始跟踪。

2. 实例二:基于MK802的人脸摄像机云台跟踪

这个例子对前面的光源跟踪做了扩展,实现了对人脸的跟随。相比光源来说,跟踪人脸更加具有趣味性,可以用来制作很多有趣的玩意。另外相对光源来说人脸识别的抗干扰性强很多。

图:本实例的工作效果

可以观看下面的演示视频了解本例子的具体工作情况:

 

本实例的代码:

 

原理简介

本实例是在上一个例子的框架基础上制作的,因此总体的原理和之前的例子一样,只是这里使用了人脸识别的算法,将画面中人脸的位置提取出来,作为后续舵机控制的参考信号。
对于人类的识别,我简单的使用了OpenCV中的CascadeClassifier分类器[6]进行对人类的识别过程。并且直接使用了OpenCV附带例子中的训练数据。因此对于他的原理,大家就可以直接去参考OpenCV给出的文档了。

图:识别人脸的效果

不过这个分类器的运算量比较大,对于MK802来说已经是比较大的负担。我将摄像头画面缩小了4倍后进行CascadeClassifier处理,大概只能实现8fps的运行速度。不过后来对MK802进行超频[2]后,发现该算法的运行效率也有一定的改观。
下图是该实例的框图:

图:本实例的框架图

另外得益于前面提到的平滑舵机控制的策略,这里即使人脸识别只有8fps的性能,但是舵机的运动依旧平滑流畅。但是还是受限于识别算法的运行效率,从视频中大家就可以感觉到舵机跟踪具有比较大的延迟了。

程序的使用:

如果拥有对应的硬件,就可以使用如下命令执行本程序:

LD_LIBRARY_PATH=`pwd` ./facetrack /dev/ttyUSB0 /dev/ttyUSB1

其中参数/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抓取这个页面:

root@linaro-alip:~/demoapp/scripts# ./retrieve_ddwrt_bandwidth.sh
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


 

 

  • 相关文章:
  • quote 1.土豆
  • 感谢你这个系列的文章,我很喜欢。我也有一个mk802,但是还没玩起来
  • 11/28/2012 6:15:17 AM 回复该留言
  • quote 2.zero
  • 很感谢分享这个系列,请问选购MK802 mini pc,有没有品牌差异?我准备按照这个系列学习一下开发摄像头应用,请问有没有实际可用的摄像头品牌型号可以推荐的?我是新手,怕买回来不支持就白费了。
  • 12/4/2012 7:41:27 PM 回复该留言
  • quote 3.csk
  • 品牌差异可能有,所以你可以买原始品牌的(可以搜索下了解)
    摄像头就按我文章介绍的依据购买即可
  • 12/5/2012 12:56:05 AM 回复该留言
  • quote 4.jack
  • 我也买了mk802.第一个用来做家用服务器nas。现在又买了一个,打算配合Arduino+遥控小车+机械手+云台+摄像头做机器人。是博主的帖子引起了我玩这个的兴趣。
  • 12/6/2012 1:04:15 AM 回复该留言
  • quote 5.limint86
  • MK802 mini pc在淘宝上太多了,硬件原来基本都一样,只不过PCB布线略有不同,原始品牌好像叫新奇科,miniand上有人拆解了带这个标志的一台
  • 12/10/2012 9:50:11 PM 回复该留言
  • quote 6.云飞
  • 我对您的VFD显示很感兴趣,请问画面是如何同步显示的?
  • 12/19/2012 11:38:28 PM 回复该留言
  • quote 7.csk
  • 这个在上一篇这个系列的文章有介绍。可仔细看看
  • 12/19/2012 11:52:36 PM 回复该留言
  • quote 8.Shawn
  • 对您的VFD显示网络带宽很感兴趣。
    在github看了demo代码(PS:上面的代码很漂亮!),似乎是直接ttl操作,是yleee上的那批128x64 VFD + 您自制的STM驱动么?
    能否就这个话题多分享一些信息?
    非常感谢!
    csk 于 1/3/2013 7:06:16 PM 回复
    VFD是YLEEE上的那种VFD,我用的模块是在ourdev购买的那个模块,他本身就采用了STM32。我替换了其中的固件,让它在串口接受mk802发送来的数据显示。具体的串口协议这个系列文章有交代。至于这个固件因为比较简单,所以就没放出,呵呵
  • 1/3/2013 7:06:16 PM 回复该留言
  • quote 9.jasonque
  • 你好,很喜欢你的文章。现在有个问题想问你。我现在ARM上做机器人的视觉开发,但现在的ARM开发板处理速度很难让人接受。我现在想入手一个瑞科美的MK802iiiS,我看它的配置都非常不错,但唯一一个,就是不知到是否像您文章中有串口引出点,这个对我很重要,不知您对这个更新一版的miniPC有没了解?
    gjzzcc 于 3/3/2013 10:26:18 PM 回复
    建议用MK802 Ⅲ,不带S的那种。在网上已经有现成的系统镜像可用。
    见www.miniand.com/wiki/Picuntu+Linux+Step+by+Step+Installation
  • 3/3/2013 10:26:18 PM 回复该留言
  • quote 10.csk
  • 我手头没有这款设备,不清楚串口接出情况了,可以网上找找资料。另外如果有别人提供了他的linux镜像,也可以不需要接串口
  • 1/9/2013 8:00:01 PM 回复该留言
  • quote 11.planet
  • 楼主你好,你的MK802用的什么型号的usb摄像头呢?我买了摄像头装上了不识别,没反应
  • 1/20/2013 8:26:13 PM 回复该留言
  • quote 12.planet
  • 楼主你好,你的MK802用的是什么型号的usb摄像头呢?我买了个摄像头接上没反应,识别不了
  • 1/20/2013 8:26:49 PM 回复该留言
  • quote 13.csk
  • 就是一般的usb摄像头,用uvc框架的,具体见文章介绍
  • 1/25/2013 7:44:25 PM 回复该留言
  • quote 14.Max
  • 你的云台用的舵机应该是辉盛SG90,你的云台性能怎么样?我也试着做过这样的,效果不是很好,我还是考虑用MG995舵机。
  • 1/20/2014 1:29:20 AM 回复该留言

发表评论:

注意:为了有效防止SPAM,任何含有http://字样的消息会被阻止发布同时,本站仅供技术交流,请不要讨论任何政治敏感话题或者低级趣味问题。

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

日历

最新评论及回复

最近发表

Copyright Shikai Chen 2000-2012. Powered By Z-Blog(CSK Modified)