请查看以下代码
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace std;
using namespace cv;
Mat image,image_clone,testImage,testImageHSV,imageHSV,testImageHue,imageHue;
int ch[] = {0,0};
int bins=10;
char *windowName = "BackProjection";
void histAndBackProjection(int,void*);
int main()
{
//Load the image
image = imread("E:/Trip/DSC01894.jpg");
image_clone ;
image.copyTo(image_clone);
//Break a small piece from the image
testImage = image(Rect(450,470,20,20));
cv::rectangle(image_clone,Point(450,470),Point(500,500),Scalar(255,0,0),2);
//Transfor to HSV
cvtColor(testImage,testImageHSV,CV_BGR2HSV);
cvtColor(image,imageHSV,CV_BGR2HSV);
//Seperate the HUE channel
testImageHue.create(testImageHSV.size(),testImageHSV.depth());
imageHue.create(imageHSV.size(),imageHSV.depth());
cv::mixChannels(&testImageHSV,1,&testImageHue,1,ch,1);
cv::mixChannels(&imageHSV,1,&imageHue,1,ch,1);
namedWindow("Image");
imshow("Image",image_clone);
namedWindow("Test Image");
imshow("Test Image",testImage);
//Creating windows for trackbar
namedWindow(windowName);
//Creating the track bar
createTrackbar("Select Bins",windowName,&bins,255,histAndBackProjection);
histAndBackProjection(0,0);
waitKey(0);
return 0;
}
void histAndBackProjection(int, void *)
{
MatND histImage,backProjection;
int histSize = MAX(bins,2);
float range[]={0,180};
const float* rangePtr={range};
//Calculate the histogram
cv::calcHist(&testImageHue,1,0,Mat(),histImage,1,&histSize,&rangePtr,true,false);
cv::normalize(histImage,histImage,1.0);
//Do the backprojection
cv::calcBackProject(&imageHue,1,0,histImage,backProjection,&rangePtr,1,true);
imshow(windowName,backProjection);
}
我正在使用此代码进行反投影。但是,我的反投影输出是100%黑色!无论我移动滑块的位置,它仍然是黑色的!在我的图像中,我的目标是反投影100%的白色位置,因为我需要找到白色区域。
这是为什么?代码中的任何问题?
答案 0 :(得分:0)
当您normalize直方图时会出现问题:
cv::normalize(histImage,histImage,1.0);
将缩放直方图的所有元素,使其L2范数为1.0
。但是,您尝试反投影:
cv::calcBackProject(&imageHue,1,0,histImage,backProjection,&rangePtr,1,true);
,缩放为1
。输出的类型为CV_8UC1
,因此小于1
的值(所有)将被截断为零。
相反,您应该以这种方式标准化直方图:
cv::normalize(histImage, histImage, 0, 255, NORM_MINMAX);
或者将scale
中的cv::calcBackProject()
参数更改为255
。应该注意的是,这两种方法给出了不同的(虽然大致相似)结果。使用NORM_MINMAX
似乎在直方图使用中更受欢迎。