1:由於calhist()函數求得的直方圖返回值也是一個一維或三維等等的矩陣,因此可以採用可視化的方式將結果顯示出來;爲此我們將計算和顯示的功能封裝到一個類中來實現:
class Histogram1D
{
private:
int histSize[1]; //項的數量;保存了維數和分塊的信息;
float histRange[2]; //灰度最大值和最小值;
const float *range[1]; //指針數組,
int channels[1]; //通道數目;
public:
Histogram1D()
{
histSize[0] = 255;
histRange[0] = 0;
histRange[1] = 255;
range[0] = histRange; //range[0]是一個指針,range就是指針的指針
channels[0] = 0;
}
MatND getHistorgram(const Mat& image) //計算直方圖數組
{
MatND hist;
calcHist(&image,1,channels,Mat(),hist,1,histSize,range);
return hist;
}
Mat GetHistoImage(const Mat &image); //直方圖數組的show;
};
Mat Histogram1D::GetHistoImage(const Mat &image)
{
MatND hist = getHistorgram(image);
double maxVal=0;
double minVal=0;
minMaxLoc(hist,&minVal,&maxVal,0,0);
int histSize=hist.rows;
Mat histImage(histSize,histSize,CV_8U,Scalar(255));
int hpt=static_cast<int>(0.9*histSize);
for(int h=0;h<histSize;h++)
{
float binVal=hist.at<float>(h);
int intensity=static_cast<int>(binVal*hpt/maxVal);
line(histImage,Point(h,histSize),Point(h,histSize-intensity),Scalar::all(0));
}
return histImage;
}
然後在主函數中定義一個對象,就可以直接實現直方圖的可視化了
int _tmain(int argc, _TCHAR* argv[])
{
Mat image = imread("meng.jpg",1);
cvtColor(image,image,CV_RGB2GRAY);
Histogram1D h;
namedWindow("直方圖");
imshow("直方圖",h.GetHistoImage(image));
waitKey(0);
return 0;
}
得到的結果:
但是需要注意的是,在顯示的過程中用到了line函數,該函數的原型:
C: void cvLine(CvArr* img, CvPoint pt1, CvPoint pt2, CvScalar color, int thickness=1, int line_type=8, int shift=0 )
第一個參數爲需要劃線的圖像指針,第二第三爲起始點終點,color表示畫筆顏色;默認的座標體系爲:原點在window的左上角,向下爲y軸正方向,向右爲x軸正方向;