1. 程式人生 > >【OpenCV】OpenCV之calcHist() 計算直方圖

【OpenCV】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