[英]OpenCV histogram doesn't update, despite new video data
我正在嘗試計算來自單通道黑白視頻流的每一幀的直方圖。 最終,我將這些直方圖的投影反饋給OpenCV的camshift函數。
這是我的代碼:
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/opencv.hpp"
#include "opencv2/core/core.hpp"
#include <iostream>
#include <vector>
using namespace std;
using namespace cv;
int main(int argc, char* argv[]) {
Mat frame, back, fore, hist, image, v_hist;
BackgroundSubtractorMOG2 bgs;
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
int bins = 8;
int histSize[] = { bins };
float range[] = { 0, 255 }; //values will range from 0 to 256
const float* histRange = { range };
bool uniform = true, accumulate = true;
VideoCapture cap(0);
if (!cap.isOpened()) {
cout << "Cannot open the video cam" << endl;
return -1;
}
namedWindow("histogram",CV_WINDOW_AUTOSIZE);
namedWindow("Foreground",CV_WINDOW_AUTOSIZE);
for (;;) {
if (!cap.read(frame)){
cout << "No frame" << endl;
break;
}
frame.copyTo(image);
//***start mask computation***
bgs.operator()(image, fore);
bgs.getBackgroundImage(back);
findContours(fore, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
int idx = 0;
for( ; idx >= 0; idx = hierarchy[idx][0] ){
Scalar color( 255, 255, 255 );
drawContours( fore, contours, idx, color, CV_FILLED, 8, hierarchy );
}
erode(fore, fore, Mat());
erode(fore, fore, Mat());
dilate(fore, fore, Mat());
dilate(fore, fore, Mat());
//****end mask computation****
calcHist( &fore, 1, 0, Mat(), v_hist, 1, histSize, &histRange, uniform, accumulate);
int hist_w = 512; int hist_h = 400;
int bin_w = cvRound( (double) hist_w/ (*histSize) );
Mat histImage( hist_h, hist_w, CV_8UC3, Scalar(0, 0, 0) );
normalize( v_hist, v_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() );
//draw histogram
for (int i = 1; i < *histSize; i++)
line ( histImage,
Point(bin_w*(i-1), hist_h - cvRound(v_hist.at<float>(i-1)) ),
Point( bin_w*(i), hist_h - cvRound(v_hist.at<float>(i)) ),
Scalar( 255, 255, 255), 2, 8, 0 );
if(!histImage.empty()) imshow("histogram", histImage);
if(!fore.empty()) imshow("Foreground", fore);
if (waitKey(30) >= 0) break;
}
return 0;
}
這是輸出最初的樣子(請記住,一開始,前景遮罩全是黑色的):
..但即使在前景提取之后,直方圖仍保持不變:
該直方圖似乎僅適用於第一個全黑圖像,這就是為什么線從x =(x軸的長度)/ 8開始到y = 0的原因。 這是有道理的,因為直方圖有8個bin,此原始圖片中的所有值均為0。(FWIW:當只有2個bin時,線從x =(x軸的長度)開始到y = 0 / 2)。
我過去曾使用OpenCV繪制過線和矩形,並且與我在這里所做的沒什么不同,因此我可以肯定地說,這與任何繪制功能都沒有關系。 如果是這樣,隨着新視頻數據的進入,直方圖似乎沒有更新。
有誰知道為什么會這樣嗎?
雖然我還沒有找出繪制的直方圖為什么不更新的確切原因,但我已經進行了一些測試,現在充滿信心,直方圖會在不同幀之間變化。
這是我添加到先前程序中的代碼:
//new declarations
Mat last_hist;
bool first = true;
//code is the same, leading up to...
normalize( v_hist, v_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() );
if (!first){
eq = std::equal( v_hist.begin<uchar>(), v_hist.end<uchar>(), last_hist.begin<uchar>() );
if (eq)
cout << "hists equal" << endl;
else
cout << "hists not equal" << endl;
}
else
first = false;
//draw histogram
for (int i = 1; i < *histSize; i++)
//...
if(!frame.empty())imshow("Frame", frame);
v_hist.copyTo(last_hist);
if (waitKey(30) >= 0) break;
//from here to end is the same
normalize()
之后在條件語句中使用STL equal()
來自如何檢查OpenCV中兩個矩陣是否相同 。
當我運行此代碼時,在前景蒙版受到充分干擾后,我會看到“歷史不相等”打印了幾幀。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.