Verybot之OpenCV应用三:色标跟踪

来源:互联网 发布:凯立德v5配置端口修改 编辑:程序博客网 时间:2024/05/09 16:51

        下面的这个应用主要完成的是Verybot跟踪色标的功能,识别部分还是居于OpenCV编写,色标跟踪一般需要将图像的颜色模式进行转换,将RGB转换为HSV,因为对HSV格式下的图像进行识别时受光线的影响比较小,但是也有采用RGB模式来进行识别的情况,这种情况一般光线条件比较固定,背景跟识别物在颜色上很容易区分出来。

        下面这个程序的流程大致是这样的:

        1、先将颜色模式进行转换,也就是将RGB模式转换为HSV模式;

        2、然后将HSV模式下的图像分成H、S、V3个平面;

        3、对H通道在识别颜色范围内的点进行标定;

        4、对S通道在识别颜色范围内的点进行标定;

        5、将H通道标定的点与S通道标定的点进行与运算;

        6、对与运算的结果进行腐蚀,去掉离散的点;

        7、计算最后识别出的点的几何中心;

        8、根据几何中心位置来进行跟踪。

        下面是该程序:

#include "cv.h"#include "highgui.h"#include "stdio.h"#include <netinet/in.h>    #include <sys/types.h>    #include <sys/socket.h>    #include <stdlib.h>       #include <string.h>       #include     <unistd.h>  #include     <sys/stat.h>#include     <fcntl.h> #include     <termios.h>#include     <errno.h>int main(int argc, char** argv){////////////////////////////////////////////...   //此处省去串口初始化的代码//////////////////////////////////////////////    cvNamedWindow("vedio",0);    CvCapture* capture;    if(1 == argc)    {        capture = cvCreateCameraCapture(0);    }    else    {        capture = cvCreateCameraCapture(atoi(argv[1]));    }    assert(NULL != capture);//   设置采集分辨率cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, 320);cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT,240);    IplImage* frame;char keyCode;frame = cvQueryFrame(capture);    if(!frame)    {printf("sould exit1\n");        return 0;    }    IplImage* gray = cvCreateImage( cvGetSize(frame), 8, 1 );CvMemStorage* storage = cvCreateMemStorage(0);    IplImage* tHSV = cvCreateImage(cvGetSize(frame), IPL_DEPTH_8U, 3);         //   hsv指向颜色转换为HSV模式以后的图像    IplImage* hc = cvCreateImage( cvGetSize(frame), IPL_DEPTH_8U, 1);      //   分割之后的H通道数据    IplImage* sc = cvCreateImage( cvGetSize(frame), IPL_DEPTH_8U, 1);          //   分割之后的S通道数据    IplImage* vc = cvCreateImage( cvGetSize(frame), IPL_DEPTH_8U, 1);          //   分割之后的V通道数据    IplImage* tH = cvCreateImage( cvGetSize(frame), IPL_DEPTH_8U, 1);          IplImage* tS = cvCreateImage(cvGetSize(frame), IPL_DEPTH_8U, 1);       IplImage* tImg=cvCreateImage(cvGetSize(frame),8,3);                        //    用于存放高斯模糊后的图像double m00, m10, m01;CvMoments moment;int cx, cy;while((keyCode = cvWaitKey(15)))    {    if(keyCode == 'q'){break;}        frame = cvQueryFrame(capture);        if(!frame)        {            break;        }cvSmooth(frame,tImg,CV_GAUSSIAN,3,3);                                   //      高斯模糊       cvCvtColor(tImg, tHSV, CV_BGR2HSV );   //颜色转换cvCvtPixToPlane(tHSV,hc,sc,vc,0); //图像分割成H、S、V三个通道cvInRangeS(hc,cvScalar(60,0.0,0,0),cvScalar(100,0.0,0,0),tH);   //标定H通道在范围内的点cvInRangeS(sc,cvScalar(70,0.0,0,0),cvScalar(180,0.0,0,0),tS); //标定S通道在范围内的点cvAnd(tH,tS,tH,0);   //将H通道在范围内的点与S通道在范围内的点进行与运算cvErode(tH,tH,NULL,3);//图像进行腐蚀,去掉离散点cvMoments( tH, &moment, 1);//下面这几行代码求标定出的点的几何中心m00 = cvGetSpatialMoment( &moment, 0, 0 );if( m00 != 0){m10 = cvGetSpatialMoment( &moment, 1, 0 );m01 = cvGetSpatialMoment( &moment, 0, 1 );cx = (int) (m10/m00);cy = (int) (m01/m00);//printf("%d   ,%d   \n",cx,cy);if((cx>=110)&&(cx<=210)){... //机器人前进代码}if(cx<110){... //机器人左转代码}if(cx>210){... //机器人右转代码}}else //如果找不到目标{...  //机器人停止代码}//       cvShowImage("vedio",tmpH1);    }close(fd);    cvReleaseImage(&frame);    cvDestroyAllWindows();    return 0;}

 

        这个程序的运行效果还是不错的,效率跟准确度都还不错,只是由于目前使用的摄像头的焦距比较长,视角很小,所以不能将色标移动太远,之后换上广角一些的摄像头,再调整好Verybot的转弯速度,跟踪效果应该会好很多。

        下面是Verybot跟踪色标的视频:

        http://v.youku.com/v_show/id_XNjYxNjk1MDQ4.html

0 0