OpenCV數字影象處理(一)——直方圖均衡化的實現
阿新 • • 發佈:2018-12-19
計算一幅影象的直方圖
影象是由不同數值的顏色畫素組成,畫素值在整幅影象中的分佈情況是該影象的一個重要屬性。直方圖(Histogram)是一幅影象分佈的精確圖形表示。因此,灰度影象的直方圖有256個專案。
OpenCV計算直方圖
- 環境:Windows 10, Microsoft Visual Studio 2015
Histogram1D類的建立
OpenCV可以簡單地呼叫 cv:calcHist 函式來進行直方圖計算,我們建立一個專用類來處理單通道灰度影象的類。
class Histogram1D { private: int histSize[1]; float hranges[2]; const float* ranges[1]; int channels[1]; public: Histogram1D() { histSize[0] = 256; hranges[0] = 0.0; hranges[1] = 256.0; ranges[0] = hranges; channels[0] = 0; } Mat getHistogram(const Mat &image) { Mat hist; calcHist(&image, 1, channels, Mat(), hist, 1, histSize, ranges); return hist; } Mat getHistogramImage(const Mat &image, int zoom = 1) { Mat hist = getHistogram(image); return getImageOfHistogram(hist, zoom); } static Mat getImageOfHistogram(const Mat &hist, int zoom) { double maxVal = 0; double minVal = 0; minMaxLoc(hist, &minVal, &maxVal, 0, 0); int histSize = hist.rows; Mat histImg(histSize*zoom, histSize*zoom, 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); if (binVal > 0) { int intensity = static_cast<int>(binVal*hpt / maxVal); line(histImg, Point(h*zoom, histSize*zoom), Point(h*zoom, (histSize - intensity)*zoom), Scalar(0), zoom); } } return histImg; } };
影象直方圖計算
所使用的圖片如下所示:
主函式編輯:
int main() { Mat image = imread("Fig3.15(a)1top.BMP", 0); Histogram1D h; Mat histo = h.getHistogram(image); for (int i = 0; i < 256; i++) { cout << "Value " << i << " = " << histo.at<float>(i) << endl; } namedWindow("Histogram"); imshow("Histogram", h.getHistogramImage(image)); waitKey(0); return 0; }
輸出的值非0的結果:
Value 12 = 477 Value 13 = 16986 Value 14 = 379 Value 15 = 572 Value 16 = 1917 Value 17 = 8955 Value 18 = 2129 Value 19 = 16228 Value 20 = 10188 Value 21 = 3327 Value 22 = 5751 Value 23 = 1406 Value 24 = 4224 Value 25 = 1266 Value 26 = 4332 Value 27 = 2539 Value 28 = 2830 Value 29 = 5529 Value 30 = 2141 Value 31 = 3653 Value 32 = 2187 Value 33 = 4142 Value 34 = 3227 Value 35 = 5808 Value 36 = 3019 Value 37 = 4913 Value 38 = 6980 Value 39 = 4303 Value 40 = 3729 Value 41 = 4048 Value 42 = 6398 Value 43 = 1849 Value 44 = 6581 Value 45 = 1762 Value 46 = 6731 Value 47 = 9532 Value 48 = 3374 Value 49 = 5324 Value 50 = 2989 Value 51 = 4945 Value 52 = 3840 Value 53 = 3528 Value 54 = 3609 Value 55 = 5614 Value 56 = 5712 Value 57 = 1385 Value 58 = 4312 Value 59 = 2731 Value 60 = 3788 Value 61 = 1018 Value 62 = 3184 Value 63 = 863 Value 64 = 1910 Value 65 = 3471 Value 66 = 2638 Value 67 = 697 Value 68 = 2341 Value 69 = 1434 Value 70 = 1339 Value 71 = 1378 Value 72 = 1744 Value 73 = 971 Value 74 = 2267 Value 75 = 1460 Value 76 = 861 Value 77 = 909 Value 78 = 158 Value 79 = 141 Value 80 = 16 Value 81 = 9 Value 82 = 1 Value 83 = 1
直方圖顯示如下:
OpenCV直方圖均衡
OpenCV提供了一個直方圖均衡化的函式 cv::equalizeHist(image,result),我們通過使用這個函式來實現直方圖均衡化,通過修改下面main函式:
int main()
{
Mat image = imread("Fig3.15(a)1top.BMP", 0);
Histogram1D h;
Mat histo = h.getHistogram(image);
for (int i = 0; i < 256; i++)
{
if (histo.at<float>(i) != 0)
cout << "Value " << i << " = " << histo.at<float>(i) << endl;
}
namedWindow("Histogram");
imshow("Histogram", h.getHistogramImage(image));
/*namedWindow("Cell");
imshow("Cell", image);
equalizeHist(image, image);
namedWindow("CellequalizeHist");
imshow("CellequalizeHist", image);
namedWindow("Histogram2");
imshow("Histogram2", h.getHistogramImage(image));*/
waitKey(0);
return 0;
}
最終效果如下: