首先感谢贾志刚老师的教学视频及教学材料…
本材料来自贾志刚老师:
如上图所示,这是一张视频里面的截图,现在我们想要一直跟踪上图中绿色的飞盘。
现在有如下几步:
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(i)]);//外接矩形
5、绘制最大外接矩形。
rectangle(frame, roi, Scalar(0, 0, 255), 3, 8, 0);
实例:
#include
#include
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>contours;
vectorhierarchy;
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(i)]);//面积
rect = boundingRect(contours[static_cast(i)]);//外接矩形
if (contours_Area > area)
{
area = contours_Area;
}
}
}
else
{
rect.x = rect.y = rect.width = rect.height = 0;
}
}