上一篇《OpenCV第八篇灰階長條圖》介紹對灰階長條圖,本篇將介紹長條圖的均衡化,這是映像增強常用方法。長條圖均衡化的數學原理這裡就不介紹了,有興趣可以查閱專業書籍。下面來看看灰階長條圖均衡化的函數——cvEqualizeHist
一.cvEqualizeHist
函數功能:長條圖均衡化,該函數能歸一化映像亮度和增強對比
函數原型:
/* equalizes histogram of 8-bit single-channel image */
CVAPI(void) cvEqualizeHist( const CvArr* src, CvArr* dst );
第一個參數表示輸入映像,必須為灰階圖(8位,單通道圖)。
第二個參數表示輸出映像
函數說明:
該函數採用如下法則對輸入映像進行長條圖均衡化:
1:計算輸入映像的長條圖H。
2:長條圖歸一化,因此直方塊和為255。
3:計算長條圖積分,H'(i) = Sum(H(j)) (0<=j<=i)。
4:採用H'作為查詢表:dst(x, y) = H'(src(x, y))進行映像變換。
在維基百科上對灰階長條圖均衡化有個很好的對比,參見(網址:http://zh.wikipedia.org/zh-cn/%E7%9B%B4%E6%96%B9%E5%9B%BE%E5%9D%87%E8%A1%A1%E5%8C%96)
可以看出長條圖均衡化對映像增強效果很不錯,對映像細節部分能起到明顯的突出增強效果。下面我們自己動手寫一個灰階長條圖均衡化的程式,代碼如下:
//映像的灰階長條圖均衡化//By MoreWindows (http://blog.csdn.net/MoreWindows)#include <opencv2/opencv.hpp>#include <opencv2/legacy/compat.hpp>using namespace std;#pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"")void FillWhite(IplImage *pImage){cvRectangle(pImage, cvPoint(0, 0), cvPoint(pImage->width, pImage->height), CV_RGB(255, 255, 255), CV_FILLED);}// 建立灰階映像的長條圖CvHistogram* CreateGrayImageHist(IplImage **ppImage){int nHistSize = 256;float fRange[] = {0, 255}; //灰階級的範圍 float *pfRanges[] = {fRange}; CvHistogram *pcvHistogram = cvCreateHist(1, &nHistSize, CV_HIST_ARRAY, pfRanges);cvCalcHist(ppImage, pcvHistogram);return pcvHistogram;}// 根據長條圖建立長條圖映像IplImage* CreateHisogramImage(int nImageWidth, int nScale, int nImageHeight, CvHistogram *pcvHistogram){IplImage *pHistImage = cvCreateImage(cvSize(nImageWidth * nScale, nImageHeight), IPL_DEPTH_8U, 1);FillWhite(pHistImage);//統計長條圖中的最大直方塊float fMaxHistValue = 0;cvGetMinMaxHistValue(pcvHistogram, NULL, &fMaxHistValue, NULL, NULL);//分別將每個直方塊的值繪製到圖中int i;for(i = 0; i < nImageWidth; i++){float fHistValue = cvQueryHistValue_1D(pcvHistogram, i); //像素為i的直方塊大小int nRealHeight = cvRound((fHistValue / fMaxHistValue) * nImageHeight); //要繪製的高度cvRectangle(pHistImage,cvPoint(i * nScale, nImageHeight - 1),cvPoint((i + 1) * nScale - 1, nImageHeight - nRealHeight),cvScalar(i, 0, 0, 0), CV_FILLED); }return pHistImage;}int main( int argc, char** argv ){const char *pstrWindowsSrcTitle = "原圖(http://blog.csdn.net/MoreWindows)";const char *pstrWindowsGrayTitle = "灰階圖(http://blog.csdn.net/MoreWindows)";const char *pstrWindowsHistTitle = "長條圖(http://blog.csdn.net/MoreWindows)";const char *pstrWindowsGrayEqualizeTitle = "灰階圖-均衡化後(http://blog.csdn.net/MoreWindows)";const char *pstrWindowsHistEqualizeTitle = "長條圖-均衡化後(http://blog.csdn.net/MoreWindows)";// 從檔案中載入原圖IplImage *pSrcImage = cvLoadImage("013.jpg", CV_LOAD_IMAGE_UNCHANGED);IplImage *pGrayImage = cvCreateImage(cvGetSize(pSrcImage), IPL_DEPTH_8U, 1);IplImage *pGrayEqualizeImage = cvCreateImage(cvGetSize(pSrcImage), IPL_DEPTH_8U, 1);// 灰階圖cvCvtColor(pSrcImage, pGrayImage, CV_BGR2GRAY);// 長條圖映像資料int nHistImageWidth = 255;int nHistImageHeight = 150; int nScale = 2; // 灰階長條圖及長條圖映像CvHistogram *pcvHistogram = CreateGrayImageHist(&pGrayImage);IplImage *pHistImage = CreateHisogramImage(nHistImageWidth, nScale, nHistImageHeight, pcvHistogram);// 均衡化cvEqualizeHist(pGrayImage, pGrayEqualizeImage);// 均衡化後的灰階長條圖及長條圖映像CvHistogram *pcvHistogramEqualize = CreateGrayImageHist(&pGrayEqualizeImage); IplImage *pHistEqualizeImage = CreateHisogramImage(nHistImageWidth, nScale, nHistImageHeight, pcvHistogramEqualize);// 顯示//顯示代碼….cvWaitKey(0);//回收資原始碼…return 0;}
運行結果如下所示:
可以看出,灰階長條圖均衡化對灰階圖的映像增強效果明顯,讀者可以嘗試將灰階長條圖均衡化加入到《OpenCV第六篇輪廓檢測下》中,看看均衡化後對輪廓檢測的提升效果。
由於人眼對彩色更為敏感,下一篇《OpenCV第十一篇 彩色長條圖均衡化》將對彩色映像進行長條圖均衡化,讓大家對長條圖均衡化有一個更加直觀的瞭解。
《OpenCV入門指南》系列文章地址:
http://blog.csdn.net/morewindows/article/category/1291764
轉載請標明出處,原文地址:http://blog.csdn.net/morewindows/article/details/8364690
歡迎關注微博:http://weibo.com/MoreWindows