转自:http://blog.csdn.net/sununs11/article/details/9173549
我们用Android版本的OpenCV来做颜色团块追踪(Color Blob Tracker),首先最关键的当然是Android上的OpenCV。Android+OpenCV开发环境搭建不多说,参考官网文档:http://docs.opencv.org/doc/tutorials/introduction/android_binary_package/android_dev_intro.html 和http://docs.opencv.org/doc/tutorials/introduction/android_binary_package/O4A_SDK.html
1. OpenCV4Android Samples在你下载的OpenCV-x.x.x-android-sdk.zip中,有一些示例程序,比如摄像头采集图像,常用的图像处理,人脸检测,包括一个“color-blob-detection”,这些程序我并没有全都成功运行,不过经过一番折腾,color-blob-detection是成功了。它的主要作用就是检测出团块(blob),点一下某个区域,就会确定一种颜色,检测这种颜色的团块,然后界面上会显示一圈红色的轮廓。于是我把它改造了一下,先找出其中最大的一个轮廓,然后利用轮廓矩计算出团块的重心位置。
2. 轮廓矩一个轮廓对应一系列的点,也就是一条曲线。把图像经过一些处理,得到一个膨胀处理的二值图像,然后用findContours函数寻找到轮廓。接下来就是处理轮廓了。比较两个轮廓最简单的方式是比较轮廓矩,矩是对轮廓上的点做一些运算得到的一个特征,在这里我们只关心它如何得到中心位置。X = M10/M00,Y = M01/M00.就这么简单。
- Moments mMoments = Imgproc.moments(iContour);
- double x = mMoments.get_m10()/mMoments.get_m00();
- double y = mMoments.get_m01()/mMoments.get_m00();
- Point center = new Point(x,y);
- distance = Math.sqrt( (x-360)*(x-360) + (y-240)*(y-240) ); // 720x480 image
- Core.circle(rgbaImage,center,3,new Scalar(0,255,0),3,8,0);
3.舵机跟踪控制
二自由度舵机云台要根据团块的位置来移动,一开始我们想到的方法是把平面分成几个区域,团块坐标在不同的区域对应舵机的不同角度。但是后来发现效果不好,于是采取更直接的办法,比如团块在左边舵机就向左转,团块在上边舵机就向上转。遇到的问题是,检测速度不够导致舵机连续向某个方向转,视野里就没有团块了。如果把舵机调得太慢的话效果也不好,看得很纠结。
然后我问了一下CSK大神,他用MK802做了一个类似的东西,说是要根据团块偏离中心位置的距离调整舵机的运动速度。于是我开窍了。。。
- // ColorBlobDetector.java中
- if (PixelX > 288 && PixelX < 432 )
- angleH = 0;
- else if (PixelX <= 288) angleH = 1;
- else if (PixelX >= 432) angleH = -1;
- if (PixelY > 192 && PixelY < 288 )
- angleV = 0;
- else if (PixelY <= 192) angleV = 1;
- else if (PixelY >= 288) angleV = -1;
- // ColorTrack.java中
- Thread tColorControl = new Thread(new Runnable(){
- public void run(){
- try{
- int deltaT = 100;
- while(true){
- deltaT = (int) (ColorBlobDetector.distance/433*110 + 30);
- Thread.sleep(deltaT);
- Handler01.post(rImageControl);
- }
- }catch(Throwable t){
- }
- }
- });
- tColorControl.start();
通过Handler post的延时来调整舵机运动的速度,另外降低图像的分辨率也让检测的速度提高了很多,这样达到的效果还算不错。