opencv c++ 实时对象追踪

1、根据颜色追踪

颜色范围查询表:

代码:

void Quick_Demo::object_follow_byscalar_demo()
{
	VideoCapture cap(0);
	Mat frame,mask,output;
	char ch;
	float mini_index = 0.7;
	while (true) {
		//打开错误反馈
		if (!cap.isOpened())
			break;
		cap >> frame;
		
		ch = waitKey(100);
		if (ch == 27)
			break;
		//尺寸灰度转换,翻转
		resize(frame, frame, Size(), mini_index, mini_index,INTER_AREA);
		cvtColor(frame, frame, COLOR_BGR2HSV);
		flip(frame, frame, 1);

		//设置颜色上下限,查表得到红色的上下限
		Scalar low_bound = Scalar(0, 0, 221);
		Scalar up_bound = Scalar(180, 30, 255);
		
		//获取mask掩膜
		inRange(frame, low_bound, up_bound, mask);

		bitwise_and(frame, frame, output, mask);

		//中值模糊
		medianBlur(output, output, 5);
		imshow("input", frame);
		imshow("object",output);
	}
	cap.release();
	destroyAllWindows();
}

2、自选ROI区域追踪

涉及算法:meanshift,CAMshift

meanshift:

根据选定的ROI区域的颜色直方图选定若干点,然后计算空间点图心。如果在过程中图心始终位于该ROI的中心,则对象没有移动,若图心改变,则对象朝图心改变的方向移动。但它不会允许改变边界框大小(即只允许图像对象的平动,不允许前后运动)。

CAMshift:

在meanshift的基础上可以自适应边界框大小,还可以追踪对象的方向。

2、1鼠标事件部分

包括鼠标点击,抬起事件。

1、预先定义:

鼠标事件布尔值,起始点,终止点,捕获图像矩阵相关Mat,选取矩形框,如:

Mat frame, gray; //源图像和源灰度图像
Mat framecopy;  //用于拷贝出的源图像
Mat framerect, framerecthsv;  //矩形选取后的图像
Rect rect;      //鼠标选取的矩形
//鼠标控制
bool firstleftbutton = false;
bool leftButtonDownFlag = false; //左键单击后视频暂停播放的标志位 
Point rectstartPoint; //矩形框起点    
Point rectstopPoint; //矩形框终点   

//直方图
int histSize = 200;
float histR[] = { 0,255 };
const float* histRange = histR;
int channels[] = { 0,1 };
Mat dstHist;

 2、点击事件

更新鼠标事件布尔值为true、起始点,终止点坐标。

leftButtonDownFlag = true; //更新按下标志位
rectstartPoint = Point(x, y); //设置矩形的开始点
rectstopPoint = rectstartPoint;   //刚按下时结束点和开始点一样

3、抬起事件

 更新鼠标事件布尔值为false、捕获矩形框、framerect,在对应框内计算对应直方图、归一化显示直方图结果。

leftButtonDownFlag = false;//按下鼠标标志位复位
rect = Rect(rectstartPoint, rectstopPoint);//设置选中后的矩形
framerect = frame(rect); //通过矩形获取到选取后的图像
imshow("selectimg", framerect);//显示出来选择后的图像
cvtColor(framerect, framerecthsv, COLOR_BGR2HSV);
//直方图计算
calcHist(&framerecthsv, 2, channels, Mat(), dstHist, 1, &histSize, &histRange, true, false);
//归一化显示
normalize(dstHist, dstHist, 0, 255, NORM_MINMAX);

4、鼠标移动事件

更新源图像,防止矩形框重叠显示, 更新矩形框点,绘制矩形框,显示框选图像。

		framecopy = frame.clone();  //复制源图像
		rectstopPoint = Point(x, y); //设置矩形的结束点
		if (rectstartPoint != rectstopPoint)
		{
			//当矩形的开始点和结束点不同后在复制的图像上绘制矩形
			rectangle(framecopy, rectstartPoint, rectstopPoint,
				Scalar(255, 255, 255));
		}
		imshow("srcvideo", framecopy);

 2、2Camshift应用部分(略)

代码:

Mat frame, gray; //源图像和源灰度图像
Mat framecopy;  //用于拷贝出的源图像
Mat framerect, framerecthsv;  //矩形选取后的图像
Rect rect;      //鼠标选取的矩形


//直方图
int histSize = 200;
float histR[] = { 0,255 };
const float* histRange = histR;
int channels[] = { 0,1 };
Mat dstHist;


//保存目标轨迹  
std::vector<Point> pt;


//鼠标控制
bool firstleftbutton = false;
bool leftButtonDownFlag = false; //左键单击后视频暂停播放的标志位 
Point rectstartPoint; //矩形框起点    
Point rectstopPoint; //矩形框终点    
void onMouse(int event, int x, int y, int flags, void* ustc); //鼠标回调函数    



void onMouse(int event, int x, int y, int flags, void* ustc)
{
	//鼠标左键按下
	if (event == EVENT_LBUTTONDOWN)
	{
		leftButtonDownFlag = true; //更新按下标志位
		rectstartPoint = Point(x, y); //设置矩形的开始点
		rectstopPoint = rectstartPoint;   //刚按下时结束点和开始点一样
	}
	//当鼠标按下并且开始移动时
	else if (event == EVENT_MOUSEMOVE && leftButtonDownFlag)
	{
		framecopy = frame.clone();  //复制源图像
		rectstopPoint = Point(x, y); //设置矩形的结束点
		if (rectstartPoint != rectstopPoint)
		{
			//当矩形的开始点和结束点不同后在复制的图像上绘制矩形
			rectangle(framecopy, rectstartPoint, rectstopPoint,
				Scalar(255, 255, 255));
		}
		imshow("srcvideo", framecopy);
	}
	//当鼠标抬起时
	else if (event == EVENT_LBUTTONUP)
	{
		leftButtonDownFlag = false;//按下鼠标标志位复位
		rect = Rect(rectstartPoint, rectstopPoint);//设置选中后的矩形
		framerect = frame(rect); //通过矩形获取到选取后的图像
		imshow("selectimg", framerect);//显示出来选择后的图像
		cvtColor(framerect, framerecthsv, COLOR_BGR2HSV);
		//直方图计算
		calcHist(&framerecthsv, 2, channels, Mat(), dstHist, 1, &histSize, &histRange, true, false);
		//归一化显示
		normalize(dstHist, dstHist, 0, 255, NORM_MINMAX);
	}


}
void Quick_Demo::object_follow_demo()
{

	VideoCapture cap(0);

	namedWindow("srcvideo", WINDOW_FREERATIO);

	//设置图像中鼠标事件
	setMouseCallback("srcvideo", onMouse, 0);
	bool first = false;
	while (true)
	{
		char ch = waitKey(50);
		//当鼠标左键没有按下时
		if (!leftButtonDownFlag)
		{
			cap >> frame;
		}
		//图像为空或Esc键按下退出播放    
		if (ch == 27)
			break;
		//如果已经截取了图像进行处理

		if (rectstartPoint != rectstopPoint && !leftButtonDownFlag)
		{
			Mat imageHSV;
			Mat calcBackImage;

			cvtColor(frame, imageHSV, COLOR_BGR2HSV);

			//反向投影
			calcBackProject(&imageHSV, 2, channels,
				dstHist, calcBackImage, &histRange);

			TermCriteria criteria(TermCriteria::MAX_ITER +
				TermCriteria::EPS, 10, 1);

			CamShift(calcBackImage, rect, criteria);
			//更新模板
			Mat imageROI = imageHSV(rect);
			framerecthsv = imageHSV(rect);
			calcHist(&imageROI, 2, channels, Mat(),
				dstHist, 1, &histSize, &histRange);
			normalize(dstHist, dstHist, 0.0, 1.0, NORM_MINMAX);   //归一化  
			rectangle(frame, 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(frame, pt[i], pt[i + 1], Scalar(0, 255, 0), 2.5);
			}
		}
		imshow("srcvideo", frame);
		
	}
	cap.release();
	waitKey(0);
	destroyAllWindows();
}

参考:(33条消息) C++ OpenCV视频操作之CamShift跟踪算法_Vaccae的博客-CSDN博客 

  • 0
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个基于OpenCV实现物体检测追踪C++代码示例: ```cpp #include <opencv2/opencv.hpp> #include <opencv2/tracking.hpp> #include <iostream> #include <string> using namespace cv; using namespace std; int main(int argc, char** argv) { // 加载视频 VideoCapture cap("video.mp4"); if (!cap.isOpened()) { cout << "Could not open the video file" << endl; return -1; } // 创建对象检测器 CascadeClassifier detector; if (!detector.load("haarcascade_frontalface_default.xml")) { cout << "Could not load the detector" << endl; return -1; } // 创建跟踪器 Ptr<Tracker> tracker = TrackerKCF::create(); // 初始化目标位置 Rect2d bbox; Mat frame; cap >> frame; cvtColor(frame, frame, COLOR_BGR2GRAY); vector<Rect> faces; detector.detectMultiScale(frame, faces, 1.3, 5); if (faces.size() > 0) { bbox = faces[0]; tracker->init(frame, bbox); } // 循环处理每一帧 while (cap.read(frame)) { // 检测目标并更新bbox if (bbox.area() == 0) { cvtColor(frame, frame, COLOR_BGR2GRAY); detector.detectMultiScale(frame, faces, 1.3, 5); if (faces.size() > 0) { bbox = faces[0]; tracker->init(frame, bbox); } } else { bool ok = tracker->update(frame, bbox); if (ok) { rectangle(frame, bbox, Scalar(0, 255, 0), 2, 1); } else { bbox = Rect2d(); } } // 显示结果 imshow("frame", frame); // 按下q键退出循环 if (waitKey(1) == 'q') { break; } } // 释放资源 cap.release(); destroyAllWindows(); return 0; } ``` 该代码使用了Haar Cascades检测人脸,并使用KCF跟踪器追踪人脸。在每一帧中,首先检测目标并初始化bbox,然后使用跟踪器更新bbox并绘制矩形框。最后显示结果并等待用户按下q键退出循环。你可以根据需要调整检测器和跟踪器,并对算法参数进行调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值