OpenCV4入门89:视频直方图反向投影

索引地址:系列索引

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
// Program to illustrate histogram backprojection 
// Author: Samarth Manoj Brahmbhatt, University of Pennsylvania

//---------------------------------【头文件、命名空间包含部分】----------------------------
// 描述:包含程序所使用的头文件和命名空间
//------------------------------------------------------------------------------------------------
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace cv;
using namespace std;


//-----------------------------------【全局变量声明部分】---------------------------------------
// 描述:声明全局变量
//---------------------------------------------------------------------------------------------------
Mat frame_hsv, frame, mask;
MatND hist; //2D直方图
int conn = 4, val = 255, flags = conn + (val << 8) + CV_FLOODFILL_MASK_ONLY;
bool selected = false;
// 直方图相关参数
float hrange[] = {0, 179}, srange[] = {0, 255};
const float *ranges[] = {hrange, srange};


//-----------------------------------【on_mouse( )函数】-------------------------------------
// 描述:鼠标回调函数
//-------------------------------------------------------------------------------------------------
void on_mouse(int event, int x, int y, int, void *) {
if(event != EVENT_LBUTTONDOWN) return;

selected = true;

// floodFill
Point p(x, y);
mask = Scalar::all(0);
floodFill(frame, mask, p, Scalar(255, 255, 255), 0, Scalar(10, 10, 10), Scalar(10, 10, 10), flags);
Mat _mask = mask.rowRange(1, mask.rows-1).colRange(1, mask.cols-1);

// number of bins in the histogram for each channel
int histSize[] = {50, 50}, channels[] = {0, 1};

// calculate and normalize histogram
calcHist(&frame_hsv, 1, channels, _mask, hist, 2, histSize, ranges);
normalize(hist, hist, 0, 255, NORM_MINMAX, -1, Mat());
}



//-----------------------------------【main( )函数】--------------------------------------------
// 描述:控制台应用程序的入口函数,我们的程序从这里开始
//-------------------------------------------------------------------------------------------------
int main( )
{
//从摄像头读入视频
VideoCapture cap(0);

//检测是否读取成功
if(!cap.isOpened()) {
cout << "Capture could not be opened succesfully" << endl;
return -1;
}

namedWindow("Video");
namedWindow("Backprojection");

setMouseCallback("Video", on_mouse);

while(char(waitKey(1)) != 'q' && cap.isOpened()) {
cap >> frame;
if(!selected) mask.create(frame.rows+2, frame.cols+2, CV_8UC1);
// Check if the video is over
if(frame.empty()) {
cout << "Video over" << endl;
break;
}
cvtColor(frame, frame_hsv, CV_BGR2HSV);

// backproject on the HSV image
Mat frame_backprojected = Mat::zeros(frame.size(), CV_8UC1);
if(selected) {
int channels[] = {0, 1};
calcBackProject(&frame_hsv, 1, channels, hist, frame_backprojected, ranges);
}

imshow("Video", frame);
imshow("Backprojection", frame_backprojected);
}

return 0;
}