视频来源:https://www.youtube.com/watch?v=EvIwL0aSCZY
以下代码用OpenCV实现了视频中基于色彩的对象检测与跟踪,该方法受光照变化影响较大。
//
// main.cpp
// opencv-learning
//
// Created by _R on 2019/1/9.
// Copyright © 2019 _R. All rights reserved.
//
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
Rect roi;
void printAllContours(Mat &object, Mat &frame);
void trackObject(Mat &frame, Rect &roi);
int main(int argc, char* argv[])
{
VideoCapture video = VideoCapture("/Users/_R/Desktop/Flying_disc_freestyle_640x360.mp4");
if (!video.isOpened()) {
cout << "could not load video file ..." << endl;
return -1;
}
Mat frame, object, frame_contours;
Mat kernel_open = getStructuringElement(MORPH_RECT, Size(3,3));
Mat kernel_dilate = getStructuringElement(MORPH_RECT, Size(5,5));
namedWindow("flying_disc", WINDOW_AUTOSIZE);
namedWindow("flying_disc_contours", WINDOW_AUTOSIZE);
namedWindow("object", WINDOW_AUTOSIZE);
while (video.read(frame)) {
frame.copyTo(frame_contours);
inRange(frame, Scalar(0,120,30), Scalar(80,255,180), object);
morphologyEx(object, object, MORPH_OPEN, kernel_open);
dilate(object, object, kernel_dilate);
trackObject(object, roi);
rectangle(frame, roi, Scalar(0,0,255));
printAllContours(object, frame_contours);
imshow("flying_disc", frame);
imshow("object", object);
imshow("flying_disc_contours", frame_contours);
char c = waitKey(50);
if (c == 27) {
break;
}
}
waitKey(0);
video.release();
return 0;
}
void printAllContours(Mat &object, Mat& frame)
{
vector<vector<Point>> contours;
vector<Vec4i> hireachy;
findContours(object, contours, hireachy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
if (contours.size() > 0) {
for (size_t t=0; t < contours.size(); t++) {
rectangle(frame, boundingRect(contours[static_cast<int>(t)]), Scalar(0,0,255));
}
}
}
void trackObject(Mat &frame, Rect &roi)
{
vector<vector<Point>> contours;
vector<Vec4i> hireachy;
findContours(frame, contours, hireachy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
if (contours.size() > 0) {
double maxArea = 0.0;
for (size_t t=0; t < contours.size(); t++) {
double area = contourArea(contours[static_cast<int>(t)]);
if (area > maxArea) {
maxArea = area;
roi = boundingRect(contours[static_cast<int>(t)]);
}
}
}
else {
roi.x = roi.y = roi.height = roi.width = 0;
}
}