Verybot之OpenCV应用三:色标跟踪

        下面的这个应用主要完成的是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     
#include     
#include     
#include        
#include        


#include       
#include     
#include      
#include     
#include     




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

你可能感兴趣的:(Verybot之OpenCV应用三:色标跟踪)