OpenCv-C++-视频分析与对象跟踪-对象检测与跟踪(基于颜色)

首先感谢贾志刚老师的教学视频及教学材料…
本材料来自贾志刚老师:
在这里插入图片描述
如上图所示,这是一张视频里面的截图,现在我们想要一直跟踪上图中绿色的飞盘。
现在有如下几步:
1、inRange()过滤------------过滤掉绿色飞盘以外的颜色;
2、形态学操作---------------去噪点,强化飞盘轮廓;
3、轮廓查找---------------查找飞盘轮廓;
4、查找最大外接矩形---------------在轮廓查找的基础上,找到最大外接矩形;
5、绘制最大外接矩形。

1、inRange过滤:
OpenCv中有这个函数可以查找所需要的颜色:inRange()
我们要查找绿色部分,则只要这样写:

inRange(frame, Scalar(0, 127, 0), Scalar(120, 255, 120), dst);

过滤掉颜色之后的图:
在这里插入图片描述
我们可以看到有很多噪点(视频流畅播放时有很多噪点,懒得做动图)。
2、形态学操作:
这里使用开操作去掉小部分的噪点已经强化飞盘轮廓:
在这里插入图片描述

3、轮廓查找

findContours(img, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point(-1, -1));

这里使用RETR_EXTERNAL而不使用RETR_TREE。因为我们只要找到最外层的就可以了。
大致意思就是:
在这里插入图片描述
使用RETR_TREE会把黑、红、黄三个矩形轮廓全找出来,RETR_EXTERNAL只会找出来黑色矩形框。

4、查找最大外接矩形

rect = boundingRect(contours[static_cast<int>(i)]);//外接矩形

5、绘制最大外接矩形。

rectangle(frame, roi, Scalar(0, 0, 255), 3, 8, 0);

实例:

#include<opencv2/opencv.hpp>
#include<iostream>

using namespace cv;
using namespace std;

void processFrame(Mat& img, Rect& rect);//绘制外接矩形

int main(int argc, char** argv)
{
	Rect roi;//存储最大外接矩形的数据
	VideoCapture capture;
	capture.open("D:/test/video_006.mp4");
	if (!capture.isOpened())
	{
		cout << "视频文件未找到..." << endl;
		return -1;
	}
	Mat frame,dst;
	Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));
	Mat kernel_dilite = getStructuringElement(MORPH_RECT, Size(7, 7), Point(-1, -1));
	while (capture.read(frame))
	{
		
		//筛选出绿色
		inRange(frame, Scalar(0, 127, 0), Scalar(120, 255, 120), dst);
		
		//开操作去噪点
		morphologyEx(dst, dst, MORPH_OPEN, kernel, Point(-1, -1), 1);
		//膨胀操作把飞盘具体化的显示出来
		dilate(dst, dst, kernel_dilite, Point(-1, -1), 2);
		imshow("output video", dst);
		processFrame(dst, roi);
		rectangle(frame, roi, Scalar(0, 0, 255), 3, 8, 0);
		imshow("input video", frame);
		char c = waitKey(50);
		if (c == 27)
		{
			break;
		}

	}
	capture.release();
	waitKey(0);
	return 0;
}

void processFrame(Mat & img, Rect & rect)
{
	//寻找外接轮廓
	vector<vector<Point>>contours;
	vector<Vec4i>hierarchy;
	findContours(img, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point(-1, -1));
	double area=0.0;
	if (contours.size() > 0) 
	{
		for (size_t i = 0; i < contours.size(); i++)
		{
			double contours_Area = contourArea(contours[static_cast<int>(i)]);//面积
			rect = boundingRect(contours[static_cast<int>(i)]);//外接矩形
			if (contours_Area > area)
			{
				area = contours_Area;
			}
		}
		
	}
	else
	{
		rect.x = rect.y = rect.width = rect.height = 0;
	}
}


运行结果:
在这里插入图片描述
在这里插入图片描述

  • 4
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值