【笔记】Opencv 目标跟踪CamShift算法:MeanShift算法的改进算法,在跟踪的过程中随目标大小的变化实时调整搜索窗口大小,对视频序列中的每一帧采用MeanShift来寻找最优迭代结果

注:

正文:

CamShift( InputArray probImage, CV_OUT CV_IN_OUT Rect& window,
                                   TermCriteria criteria );

 

#include "core/core.hpp"      
#include "highgui/highgui.hpp"      
#include "imgproc/imgproc.hpp"  
#include "video/tracking.hpp"  
#include<iostream>      
 
using namespace cv;      
using namespace std;      
 
Mat image;    
Mat rectImage;  
Mat imageCopy; //绘制矩形框时用来拷贝原图的图像    
bool leftButtonDownFlag=false; //左键单击后视频暂停播放的标志位    
Point originalPoint; //矩形框起点    
Point processPoint; //矩形框终点    
 
Mat targetImageHSV;  
int histSize=200;    
float histR[]={0,255};    
const float *histRange=histR;    
int channels[]={0,1};   
Mat dstHist;  
Rect rect;  
vector<Point> pt; //保存目标轨迹  
void onMouse(int event,int x,int y,int flags ,void* ustc); //鼠标回调函数    
 
int main(int argc,char*argv[])      
{      
	VideoCapture video(argv[1]);    
	double fps=video.get(CV_CAP_PROP_FPS); //获取视频帧率    
	double pauseTime=1000/fps; //两幅画面中间间隔    
	namedWindow("跟踪木头人",0);      
	setMouseCallback("跟踪木头人",onMouse);    
	while(true)    
	{    
		if(!leftButtonDownFlag) //判定鼠标左键没有按下,采取播放视频,否则暂停    
		{    
			video>>image;    
		}    
		if(!image.data||waitKey(pauseTime)==27)  //图像为空或Esc键按下退出播放    
		{    
			break;    
		}   
		if(originalPoint!=processPoint&&!leftButtonDownFlag)    
		{   
			Mat imageHSV;  
			Mat calcBackImage;  
			cvtColor(image,imageHSV,CV_RGB2HSV);  
			calcBackProject(&imageHSV,2,channels,dstHist,calcBackImage,&histRange);  //反向投影  
			TermCriteria criteria(TermCriteria::MAX_ITER + TermCriteria::EPS, 1000, 0.001);    
			CamShift(calcBackImage, rect, criteria);     
			Mat imageROI=imageHSV(rect);   //更新模板             
			targetImageHSV=imageHSV(rect);  
			calcHist(&imageROI, 2, channels, Mat(), dstHist, 1, &histSize, &histRange);    
			normalize(dstHist, dstHist, 0.0, 1.0, NORM_MINMAX);   //归一化  
			rectangle(image, rect, Scalar(255, 0, 0),3);    //目标绘制    
			pt.push_back(Point(rect.x+rect.width/2,rect.y+rect.height/2));  
			for(int i=0;i<pt.size()-1;i++)  
			{  
				line(image,pt[i],pt[i+1],Scalar(0,255,0),2.5);  
			}  
		}    
		imshow("跟踪木头人",image);   
		waitKey(100);  
	}  
	return 0;    
}      
 
//*******************************************************************//      
//鼠标回调函数      
void onMouse(int event,int x,int y,int flags,void *ustc)      
{     
	if(event==CV_EVENT_LBUTTONDOWN)      
	{      
		leftButtonDownFlag=true; //标志位    
		originalPoint=Point(x,y);  //设置左键按下点的矩形起点    
		processPoint=originalPoint;    
	}      
	if(event==CV_EVENT_MOUSEMOVE&&leftButtonDownFlag)      
	{      
		imageCopy=image.clone();    
		processPoint=Point(x,y);    
		if(originalPoint!=processPoint)    
		{    
			//在复制的图像上绘制矩形    
			rectangle(imageCopy,originalPoint,processPoint,Scalar(255,0,0),2);    
		}    
		imshow("跟踪木头人",imageCopy);    
	}      
	if(event==CV_EVENT_LBUTTONUP)      
	{      
		leftButtonDownFlag=false;    
		rect=Rect(originalPoint,processPoint);        
		rectImage=image(rect); //子图像显示    
		imshow("Sub Image",rectImage);        
		cvtColor(rectImage,targetImageHSV,CV_RGB2HSV);  
		imshow("targetImageHSV",targetImageHSV);  
		calcHist(&targetImageHSV,2,channels,Mat(),dstHist,1,&histSize,&histRange,true,false);         
		normalize(dstHist,dstHist,0,255,CV_MINMAX);  
		imshow("dstHist",dstHist);  
	}        
}     

 

 

蓝色窗口是跟踪的目标,绿色线条是目标走过的轨迹。 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值