【Opencv】【C++】 Opencv之calcHist() 計算直方圖

OpenCV 2.4.13

calcHist 通過圖像計算直方圖

函數聲明如下:

void calcHist( const Mat* images, int nimages,
               const int* channels, InputArray mask,
               OutputArray hist, int dims, const int* histSize,
               const float** ranges, bool uniform=true, bool accumulate=false );
//1.輸入的圖像數組   2.輸入數組的個數             3.通道數              4.掩碼                5.直方圖         
//6.直方圖維度       7.直方圖每個維度的尺寸數組   8.每一維數組的範圍    9.直方圖是否是均勻   10.配置階段不清零

1.圖像數組 

2.圖像數組個數

3.圖像的通道數

4.圖像掩碼

5.計算得到的直方圖

6.直方圖的維度(灰度直方圖爲1維)

7.直方圖每一維度上的數組個數(bin 的個數)

8.每一維進行直方圖統計的數組的範圍  範圍如 0~256 表示統計 0~255的數組 這裏注意 (0,256) 包含0而不包含256 包含的是256-1

9.是否均勻的統計(個人理解爲是否統計的每個bin包含相同的灰度級 可能理解有誤)

10.這個還真不明白 待學習。。。 

以下做個了計算直方圖的例子 並進行直方圖的顯示

#include <opencv2/opencv.hpp>

int main()
{
	cv::Mat src = imread("image.jpg", cv::IMREAD_GRAYSCALE); //讀取灰度圖像
	cv::Mat hist; //將要獲得的直方圖
	int imgNum = 1;//圖像數
	int histDim = 1;//直方圖維度
	int histSize = 256; //直方圖每一維度bin個數
	float range[] = { 0, 256 };//每一維度的統計範圍
	const float* histRange = { range };//因爲我們計算1維直方圖所以 只有一個rang
	bool uniform = true;//
	bool accumulate = false;//
	cv::calcHist(&src, imgNum, 0, cv::Mat(), hist, histDim, &histSize, &histRange, uniform, accumulate);

	int scale = 2;//控制圖像的寬大小
	cv::Mat histImg(cv::Size(histSize*scale, histSize), CV_8UC1);//用於顯示直方圖

	uchar* pImg = nullptr;
	for (size_t i = 0; i < histImg.rows; i++) //初始化圖像爲全黑
	{
		pImg = histImg.ptr<uchar>(i);
		for (size_t j = 0; j < histImg.cols; j++)
		{
			pImg[j] = 0;
		}
	}

	double maxValue = 0; //直方圖中最大的bin的值
	cv::minMaxLoc(hist, 0, &maxValue, 0, 0); //minMaxLoc可以計算最大值最小值以及其對應的位置 這裏求最大值

	int histHeight = 256; //要繪製直方圖的最大高度

	float* p = hist.ptr<float>(0);
	for (size_t i = 0; i < histSize; i++)//進行直方圖的繪製
	{
		float bin_val = p[i];
		int intensity = cvRound(bin_val*histHeight / maxValue);  //要繪製的高度 
		for (size_t j = 0; j < scale; j++) //繪製直線 這裏用每scale條直線代表一個bin
		{
			cv::line(histImg, cv::Point(i*scale + j , histHeight - intensity), cv::Point(i*scale + j, histHeight - 1), 255);
		}
		//cv::rectangle(histImg, cv::Point(i*scale, histHeight - intensity), cv::Point((i + 1)*scale, histHeight - 1), 255); //利用矩形代表bin
	}
	cv::namedWindow("直方圖");
	cv::imshow("直方圖", histImg);
	cv::waitKey(0);
	cv::destroyWindow("直方圖");
	//cv::destroyAllWindows();
	return 0;
}


參考:http://blog.csdn.net/sydnash/article/details/7451039

            http://blog.csdn.net/xfortius/article/details/8829246

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章