【OpenCV】OpenCV之calcHist() 計算直方圖
阿新 • • 發佈:2018-12-27
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; }