獲取直方圖與直方圖均衡化,規定化this
原理很簡單,就是獲取像素點分佈,並改變像素點分佈。spa
一、獲取直方圖code
用到的接口是 calcHist(),有三種形式。返回一個圖像直方圖像素分佈。以後再使用opencv畫圖。blog
1 void gethist(Mat gray) 2 { 3 //Mat gray; 4 //cvtColor(src, gray, CV_RGB2GRAY); 5 const int channels[] = { 0 }; 6 Mat hist; 7 const int histsize[] = { 256 }; 8 float range[] = { 0, 256 }; 9 const float* ranges[] = { range }; 10 calcHist(&gray, 1, channels, Mat(), hist, 1, histsize, ranges, true, false); 11 double maxval = 0; 12 minMaxLoc(hist, 0, &maxval, 0, 0); 13 int row = cvRound(maxval); 14 Mat histimage(row, 256, CV_8UC1); 15 for (int i = 0; i < 256; i++) 16 { 17 int temp = (int)(hist.at<float>(i, 0)); 18 if (temp) 19 { 20 histimage.col(i).rowRange(Range(row - temp, row)) = 255; 21 } 22 } 23 Mat resizeimage; 24 resize(histimage, resizeimage, Size(256, 256)); 25 imshow("灰度圖", gray); 26 imshow("histgram", resizeimage); 27 waitKey(0); 28 }
二、直方圖均衡接口
改變像素值分佈,使其基本知足均勻分佈。由此可改善圖像對比度。get
1 Mat histbalance_local(Mat src) 2 { 3 int Hist[256] = { 0 }; 4 float p[256] = { 0 }; 5 float dist[256]; 6 int IMGH = src.rows; 7 int IMGW = src.cols; 8 for (int i = 0; i < IMGH; i++) 9 { 10 for (int j = 0; j < IMGW; j++) 11 { 12 Hist[int(src.at<uchar>(i, j))]++; 13 } 14 } 15 for (int i = 0; i < 256; i++) 16 { 17 p[i]=( (float)(Hist[i]) / (IMGH*IMGW)); 18 } 19 dist[0] = p[0]; 20 for (int i = 1; i < 256; i++) 21 { 22 dist[i] = p[i]+dist[i-1]; 23 } 24 for (int i = 0; i < 256; i++) 25 { 26 Hist[i]=255*dist[i]+0.5; 27 } 28 Mat dst(src.size(), CV_8UC1); 29 for (int i = 0; i < IMGH; i++) 30 { 31 for (int j = 0; j < IMGW; j++) 32 { 33 dst.at<uchar>(i, j)=Hist[int(src.at<uchar>(i, j))]; 34 } 35 } 36 37 //imshow("均衡後圖像", dst); 38 return dst; 39 //waitKey(0); 40 41 }
三、直方圖規定化it
使圖像像素值分佈基本知足目標圖像的分佈。原理很簡單,就是創建原圖像與目標圖像像素值映射,映射條件是累計機率分佈類似。 看過一些版本的實現,步驟以下:opencv
一、 計算原圖像累計機率分佈class
二、計算目標圖像累計機率分佈原理
三、對兩幅圖像累計機率分佈差值最小的像素點創建映射
代碼不實現了,感受有點麻煩,可是原理仍是很簡單的。這個隨便搜就有。