版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012841922/article/details/87824125
视频来源:http://edu.51cto.com/course/8837.html?source=so
以下代码用OpenCV实现了视频中基于CAMShift算法的对象检测与跟踪,该方法实质上仍然是基于色彩的对象跟踪,不过是在HSV色彩空间,选取Hue通道,一定程度上降低了光照变化所造成的影响。
//
// 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;
int main(int argc, char* argv[])
{
VideoCapture video = VideoCapture("/Users/_R/Desktop/video_006.mp4");
if (!video.isOpened()) {
cout << "could not load video file ..." << endl;
return -1;
}
Mat frame, frame_hsv, frame_hsv_mask, ROI_image, ROI_image_hsv, ROI_image_mask, ROI_hist, backProjection;
Mat ROI_hist_image = Mat::zeros(300, 300, CV_8UC3);
Rect ROI_rect;
const int channels[] = {0};
const int bins = 8;
int bin_width = ROI_hist_image.cols / bins;
float hrange[] = {0,180};
const float *ranges[] = {hrange};
const string text_pause_ROI = "Press SPACE button to pause and select a ROI!";
const string text_ROI_continue = "Please select a ROI and then press ENTER & SPACE button to continue!";
namedWindow("ROI", WINDOW_AUTOSIZE);
namedWindow("ROI Histogram", WINDOW_AUTOSIZE);
namedWindow("Frame BackProjection", WINDOW_AUTOSIZE);
namedWindow("CAMShift Tracking", WINDOW_AUTOSIZE);
int vmin = 10;
int smin = 100;
int vmax = 256;
createTrackbar("Vmin", "CAMShift Tracking", &vmin, 256);
createTrackbar("Smin", "CAMShift Tracking", &smin, 256);
createTrackbar("Vmax", "CAMShift Tracking", &vmax, 256);
while (video.read(frame)) {
char key_striked = waitKey(50);
cvtColor(frame, frame_hsv, COLOR_BGR2HSV);
inRange(frame_hsv, Scalar(0,smin,vmin), Scalar(180,256,vmax), frame_hsv_mask);
// puase video
if (key_striked == 32) {
// ROI not selected
if (ROI_rect.empty()) {
putText(frame, text_ROI_continue, Point(20,20), FONT_ITALIC, 0.5, Scalar(0,0,255), 1, LINE_AA);
ROI_rect = selectROI("CAMShift Tracking", frame);
ROI_image = Mat(frame, ROI_rect);
imshow("ROI", ROI_image);
ROI_image_hsv = frame_hsv(ROI_rect);
ROI_image_mask = frame_hsv_mask(ROI_rect);
calcHist(&ROI_image_hsv, 1, channels, ROI_image_mask, ROI_hist, 1, &bins, ranges);
normalize(ROI_hist, ROI_hist, 0, 300, NORM_MINMAX);
for (int i = 0; i < bins; i++) {
rectangle(ROI_hist_image, Point(i*bin_width, ROI_hist_image.rows), Point((i+1)*bin_width, ROI_hist_image.rows - saturate_cast<int>(ROI_hist.at<float>(i))), Scalar(i*255/bins, 255 - i*255/bins, 255), -1);
}
imshow("ROI Histogram", ROI_hist_image);
}
char key_striked_while_paused = waitKey(0);
if (key_striked_while_paused == 32) {
continue;
} else if (key_striked_while_paused == 27) {
video.release();
return 0;
}
// close window
} else if (key_striked == 27) {
video.release();
return 0;
}
if (ROI_rect.empty()) {
putText(frame, text_pause_ROI, Point(20,20), FONT_ITALIC, 0.5, Scalar(0,0,255), 1, LINE_AA);
}
// ROI selected
if (!ROI_rect.empty()) {
calcBackProject(&frame_hsv, 1, channels, ROI_hist, backProjection, ranges);
backProjection &= frame_hsv_mask;
imshow("Frame BackProjection", backProjection);
RotatedRect tracking_rect = CamShift(backProjection, ROI_rect, TermCriteria((TermCriteria::COUNT | TermCriteria::EPS), 10, 1));
ellipse(frame, tracking_rect, Scalar(0,0,255), 1, LINE_AA);
}
imshow("CAMShift Tracking", frame);
}
waitKey(0);
video.release();
return 0;
}