生活随笔
收集整理的這篇文章主要介紹了
图像灰度化方法
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
目前,在圖像處理過程中,最常用的彩色圖片格式有RGB,HSV、YUV以及HLS三種。以下分別對這三種格式的彩色圖像進行灰度化實現(xiàn)。
1、RGB空間圖像
?? ? 定義于RGB空間的彩色圖,其每個像素點的色彩由R、G、B三個分量共同決定。每個分量在內(nèi)存所占的位數(shù)共同決定了圖像深度,即每個像素點所占的字節(jié)數(shù)。以常見的24深度彩色RGB圖來說,其三個分量各占1個字節(jié),這樣每個分量可以取值為0~255,這樣一個像素點可以有1600多萬(255*255*255)的顏色的變化范圍。對這樣一幅彩色圖來說,其對應(yīng)的灰度圖則是只有8位的圖像深度(可認(rèn)為它是RGB三個分量相等),這也說明了灰度圖圖像處理所需的計算量確實要少。不過需要注意的是,雖然丟失了一些顏色等級,但是從整幅圖像的整體和局部的色彩以及亮度等級分布特征來看,灰度圖描述與彩色圖的描述是一致的。
?? ? 對于RGB圖像進行灰度化,通俗點說就是對圖像的RGB三個分量進行加權(quán)平均得到最終的灰度值。最常見的加權(quán)方法如下:??
?? ? ?1)Gray=B;Gray=G;Gray=R
?? ? ?2)Gray=max(B+G+R)
?? ? ?3)Gray=(B+G+R)/3
?? ? ?4)Gray= 0.072169B+ 0.715160G+ 0.212671R
?? ? ?5)Gray= 0.11B+ 0.59G+ 0.3R
?? ??這三種方法中,第一種為分量法,即用RGB三個分量的某一個分量作為該點的灰度值;第二種方法為最大值法,將彩色圖像中的三分量亮度的最大值作為灰度圖的灰度值。第三種方法將彩色圖像中的三分量亮度求平均得到一個灰度圖;后兩種都是屬于加權(quán)平均法,其中第四種是OpenCV開放庫所采用的灰度權(quán)值,第五種為從人體生理學(xué)角度所提出的一種權(quán)值(人眼對綠色的敏感最高,對藍色敏感最低)。
2、其他顏色空間的灰度化
?? ??關(guān)于HSV以及HLS顏色空間的彩色圖灰度化,可以參考網(wǎng)頁《HSL和HSV色彩空間》,該網(wǎng)頁中所述方法可將幾種不同顏色表達方式進行轉(zhuǎn)換,將其轉(zhuǎn)換到RGB空間,然后再采用上述公式進行灰度化。
?? ? 關(guān)于YUV空間的彩色圖像,其Y的分量的物理意義本身就是像素點的亮度,由該值反映亮度等級,因此可根據(jù)RGB和YUV顏色空間的變化關(guān)系建立亮度Y與R、G、B三個顏色分量的對應(yīng):Y=0.3R+0.59G+0.11B,以這個亮度值表達圖像的灰度值。
3、代碼實現(xiàn)
?? ??本文旨在對整個實現(xiàn)原理及思路進行總結(jié),因此以下基于OpenCv的基本函數(shù)實現(xiàn)這幾種變化過程,至于位圖以及其他形式的圖像,在獲取了圖像原始數(shù)據(jù)后,處理方法都一樣,僅需注意指針的位置操作即可。具體代碼如下:
IplImage????*ColorImage;?????????????????????????? IplImage????*GrayImage1;?????????????????????????? IplImage????*GrayImage2;?? IplImage????*GrayImage3;?? IplImage????*GrayImage4;?? IplImage????*GrayImage5;?? IplImage????*GrayImage6;?? IplImage????*GrayImage7;?? ?? ColorImage?=?cvLoadImage(?"49138.jpg",?-1?);?????? if?(ColorImage?==?NULL)?? ????return;??? ?? GrayImage1?=?cvCreateImage(cvGetSize(ColorImage),8,1);?? GrayImage2?=?cvCreateImage(cvGetSize(ColorImage),8,1);?? GrayImage3?=?cvCreateImage(cvGetSize(ColorImage),8,1);?? GrayImage4?=?cvCreateImage(cvGetSize(ColorImage),8,1);?? GrayImage5?=?cvCreateImage(cvGetSize(ColorImage),8,1);?? GrayImage6?=?cvCreateImage(cvGetSize(ColorImage),8,1);?? GrayImage7?=?cvCreateImage(cvGetSize(ColorImage),8,1);?? ?? CvMat*?pGrayMat1?=?NULL;??????????? CvMat*?pGrayMat2?=?NULL;?? CvMat*?pGrayMat3?=?NULL;?? CvMat*?pGrayMat4?=?NULL;?? CvMat*?pGrayMat5?=?NULL;?? CvMat*?pGrayMat6?=?NULL;?? CvMat*?pGrayMat7?=?NULL;?? ?? pGrayMat1?=?cvCreateMat(ColorImage->height,?ColorImage->width,?CV_32FC1);?? pGrayMat2?=?cvCreateMat(ColorImage->height,?ColorImage->width,?CV_32FC1);?? pGrayMat3?=?cvCreateMat(ColorImage->height,?ColorImage->width,?CV_32FC1);?? pGrayMat4?=?cvCreateMat(ColorImage->height,?ColorImage->width,?CV_32FC1);?? pGrayMat5?=?cvCreateMat(ColorImage->height,?ColorImage->width,?CV_32FC1);?? pGrayMat6?=?cvCreateMat(ColorImage->height,?ColorImage->width,?CV_32FC1);?? pGrayMat7?=?cvCreateMat(ColorImage->height,?ColorImage->width,?CV_32FC1);?? ?? BYTE?data1;????????? BYTE?data2;?? BYTE?data3;?? BYTE?data4;?? BYTE?data5;?? BYTE?data6;?? BYTE?data7;?? for(int?j=0;?j<ColorImage->height;?j++)?? {?? ????for(int?i=0;?i<ColorImage->width;?i++)?? ????{????????????? ????????data1?=?(BYTE)ColorImage->imageData[j*ColorImage->widthStep?+?i*3];??????? ????????data2?=?(BYTE)ColorImage->imageData[j*ColorImage->widthStep?+?i*3?+?1];??? ????????data3?=?(BYTE)ColorImage->imageData[j*ColorImage->widthStep?+?i*3?+?2];??? ????????data4?=?max(data1,?max(data2,?data3));?????? ????????data5?=?(BYTE)((data1?+?data2?+?data3)/3);?? ????????data6?=?(BYTE)(0.072169*data1?+?0.715160*data2?+?0.212671*data3);?? ????????data7?=?(BYTE)(0.11*data1?+?0.59*data2?+?0.30*data3);?? ????????cvmSet(pGrayMat1,?j,?i,?data1);?? ????????cvmSet(pGrayMat2,?j,?i,?data2);?? ????????cvmSet(pGrayMat3,?j,?i,?data3);?? ????????cvmSet(pGrayMat4,?j,?i,?data4);?? ????????cvmSet(pGrayMat5,?j,?i,?data5);?? ????????cvmSet(pGrayMat6,?j,?i,?data6);?? ????????cvmSet(pGrayMat7,?j,?i,?data6);?? ????}?? }?? cvConvert(pGrayMat1,?GrayImage1);?? cvConvert(pGrayMat2,?GrayImage2);?? cvConvert(pGrayMat3,?GrayImage3);?? cvConvert(pGrayMat4,?GrayImage4);?? cvConvert(pGrayMat5,?GrayImage5);?? cvConvert(pGrayMat6,?GrayImage6);?? cvConvert(pGrayMat7,?GrayImage7);?? ?? cvNamedWindow(?"ColorImage",CV_WINDOW_AUTOSIZE);?? cvNamedWindow(?"GrayImage1",CV_WINDOW_AUTOSIZE);?? cvNamedWindow(?"GrayImage2",CV_WINDOW_AUTOSIZE);?? cvNamedWindow(?"GrayImage3",CV_WINDOW_AUTOSIZE);?? cvNamedWindow(?"GrayImage4",CV_WINDOW_AUTOSIZE);?? cvNamedWindow(?"GrayImage5",CV_WINDOW_AUTOSIZE);?? cvNamedWindow(?"GrayImage6",CV_WINDOW_AUTOSIZE);?? cvNamedWindow(?"GrayImage7",CV_WINDOW_AUTOSIZE);?? ?? cvShowImage("ColorImage",?ColorImage);?? cvShowImage("GrayImage1",?GrayImage1);?? cvShowImage("GrayImage2",?GrayImage2);?? cvShowImage("GrayImage3",?GrayImage3);?? cvShowImage("GrayImage4",?GrayImage4);?? cvShowImage("GrayImage5",?GrayImage5);?? cvShowImage("GrayImage6",?GrayImage6);?? cvShowImage("GrayImage7",?GrayImage7);?? ?????? cvWaitKey(0);?? cvDestroyWindow("ColorImage");?? cvDestroyWindow("GrayImage1");?? cvDestroyWindow("GrayImage2");?? cvDestroyWindow("GrayImage3");?? cvDestroyWindow("GrayImage4");?? cvDestroyWindow("GrayImage5");?? cvDestroyWindow("GrayImage6");?? cvDestroyWindow("GrayImage7");?? ?? cvReleaseImage(&ColorImage);?? cvReleaseImage(&GrayImage1);?? cvReleaseImage(&GrayImage2);?? cvReleaseImage(&GrayImage3);?? cvReleaseImage(&GrayImage4);?? cvReleaseImage(&GrayImage5);?? cvReleaseImage(&GrayImage6);?? cvReleaseImage(&GrayImage7);?? ?? cvReleaseMat(&pGrayMat1);?? cvReleaseMat(&pGrayMat2);?? cvReleaseMat(&pGrayMat3);?? cvReleaseMat(&pGrayMat4);?? cvReleaseMat(&pGrayMat5);?? cvReleaseMat(&pGrayMat6);?? cvReleaseMat(&pGrayMat7);??
?? ? 各種不同方法實現(xiàn)灰度化的效果圖對比如下;
圖1 待處理的原始圖像—脫離低級趣味的貓
圖2 分量灰度化—B分量
圖3 分量灰度化—G分量
圖4 分量灰度化—R分量
圖5 最大值灰度化
圖6 均值灰度化
圖7 OpenCV權(quán)值系數(shù)灰度化
圖8 網(wǎng)絡(luò)常用權(quán)值灰度化
4、思考
?? ??上文的代碼實現(xiàn)中,以最后一種方法為例,用到了如下代碼:
?? ??Gray= (0.11* Blue + 0.59* Green + 0.30* Red);
?? ??實際計算機處理時,這種方法已經(jīng)很快了,但實際上還存在可以優(yōu)化的余地。以上代碼所采用的是浮點運算。而在圖像處理中,速度就是生命,實時性往往是很重要的指標(biāo),這就要求我們在實現(xiàn)算法時必須考慮到代碼的效率問題。所以有一個原則:在圖像處理中,能不用浮點運算,就最好不要用!
?? ??因此,上述代碼可以等效的優(yōu)化為:
?? ??Gray = (30 * Red + 59 *Green + 11 * Blue) / 100;
?? ??這樣一改,可以有效避免浮點運算,因此可以提高代碼的效率
?? ??對這行代碼還可以繼續(xù)改進為如下:
?? ??Gray= HiByte(77 * Red + 151 * Green + 28 * Blue);
?? ??其中77,151,28分別除以256,即為上文的三個系數(shù)。
?? ??同樣的,還可以實現(xiàn)為:
?? ??Gray= (77 * Red + 151 * Green + 28 * Blue) shr 8;
?? ??這種方法實現(xiàn)了移位運算,避免了除法,效率上又有所提高。
?? ??關(guān)于具體的代碼效率問題,可以參考博文《由圖像的灰度化看基本圖像處理》。
轉(zhuǎn)自http://blog.csdn.net/likezhaobin/article/details/6915754#
總結(jié)
以上是生活随笔為你收集整理的图像灰度化方法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。