注:此教程是对贾志刚老师的opencv课程学习的一个记录,在此表示对贾老师的感谢. 基于颜色的对象跟踪和过滤步骤如下: 1.inRange过滤 2. 形态学操作提取 3. 轮廓查找 4. 外接矩形获取 5. 位置标定
#include <opencv2/opencv.hpp> #include <iostream> using namespace std; using namespace cv; Rect roi; void processFrame(Mat &binary, Rect &rect); int main(int argc, char** argv) { // load video VideoCapture capture; capture.open("/home/fuhong/code/cpp/opencv_learning/src/object_tracing/video/video_006.mp4"); if (!capture.isOpened()) { printf("could not find video file"); return -1; } Mat frame, mask; Mat kernel1 = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1)); Mat kernel2 = getStructuringElement(MORPH_RECT, Size(5, 5), Point(-1, -1)); namedWindow("input video", CV_WINDOW_AUTOSIZE); namedWindow("track mask", CV_WINDOW_AUTOSIZE); while (capture.read(frame)) { //inrange()函数:提取两个像素值范围内的像素点 inRange(frame, Scalar(0, 127, 0), Scalar(120, 255, 120), mask); morphologyEx(mask, mask, MORPH_OPEN, kernel1, Point(-1, -1), 1); //开操作,可以去掉小的对象,假设对象是前景色,背景是黑色 dilate(mask, mask, kernel2, Point(-1, -1), 4); //膨胀操作 imshow("track mask", mask); processFrame(mask, roi); rectangle(frame, roi, Scalar(0, 0, 255), 3, 8, 0); imshow("input video", frame); // trigger exit char c = waitKey(100); if (c == 27) { break; } } capture.release(); //释放资源 waitKey(0); return 0; } /*! * @note .作用: 从所有的轮廓中找出面积最大的轮廓所在的boundingRect包围矩形。 * @param binary : 二值化图像 * @param rect : 感兴趣区域 */ void processFrame(Mat &binary, Rect &rect) { vector<vector<Point>> contours; vector<Vec4i> hireachy; findContours(binary, contours, hireachy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point(0, 0)); 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; rect = boundingRect(contours[static_cast<int>(t)]); } } } else { rect.x = rect.y = rect.width = rect.height = 0; } }效果如下:
