前面幾篇文章介紹的是圖像的空間域?yàn)V波,其對(duì)像素的處理都是基于像素的某一鄰域進(jìn)行的。本文介紹的圖像的灰度變換則不同,其對(duì)像素的計(jì)算僅僅依賴(lài)于當(dāng)前像素和灰度變換函數(shù)。
灰度變換也被稱(chēng)為圖像的點(diǎn)運(yùn)算(只針對(duì)圖像的某一像素點(diǎn))是所有圖像處理技術(shù)中最簡(jiǎn)單的技術(shù),其變換形式如下:
s = T ( r )
其中,T 是灰度變換函數(shù);r 是變換前的灰度;s 是變換后的像素。
圖像灰度變換的有以下作用:
? ? ?改善圖像的質(zhì)量,使圖像能夠顯示更多的細(xì)節(jié),提高圖像的對(duì)比度(對(duì)比度拉伸)
? ? ?有選擇的突出圖像感興趣的特征或者抑制圖像中不需要的特征
? ? ?可以有效的改變圖像的直方圖分布,使像素的分布更為均勻
常見(jiàn)的灰度變換
灰度變換函數(shù)描述了輸入灰度值和輸出灰度值之間變換關(guān)系,一旦灰度變換函數(shù)確定下來(lái)了,那么其輸出的灰度值也就確定了??梢?jiàn)灰度變換函數(shù)的性質(zhì)就決定了灰度變換所能達(dá)到的效果。
用于圖像灰度變換的函數(shù)主要有以下三種:
? ? ?線(xiàn)性函數(shù) (圖像反轉(zhuǎn))
? ? ?對(duì)數(shù)函數(shù):對(duì)數(shù)和反對(duì)數(shù)變換
? ? ?冪律函數(shù):n次冪和n次開(kāi)方變換
上圖給出了幾種常見(jiàn)灰度變換函數(shù)的曲線(xiàn)圖,根據(jù)這幾種常見(jiàn)函數(shù)的曲線(xiàn)形狀,可以知道這幾種變換的所能達(dá)到的效果。例如,對(duì)數(shù)變換和冪律變換都能實(shí)現(xiàn)圖像灰度級(jí)的擴(kuò)展/壓縮,另外對(duì)數(shù)變換還有一個(gè)重要的性質(zhì),它能壓縮圖像灰度值變換較大的圖像的動(dòng)態(tài)范圍(例如,傅立葉變換的頻譜顯示)。
線(xiàn)性變換
令 r 為變換前的灰度,s為變換后的灰度,則線(xiàn)性變換的函數(shù):
s = a ? r + b
其中,a 為直線(xiàn)的斜率,b 為在 y 軸的截距。選擇不同的 a,b 值會(huì)有不同的效果:
? ? ?a > 1,增加圖像的對(duì)比度
? ? ?a < 1,減小圖像的對(duì)比度
? ? ?a = 1 且 b ≠ 0,圖像整體的灰度值上移或者下移,也就是圖像整體變亮或者變暗,不會(huì)改變圖像的對(duì)比度。
? ? ?a < 0 且 b = 0,圖像的亮區(qū)域變暗,暗區(qū)域變亮
? ? ?a = 1 且 b = 0,恒定變換,不變
? ? ?a = ?1 且 b = 255,圖像反轉(zhuǎn)。
在進(jìn)行圖像增強(qiáng)時(shí),上述的線(xiàn)性變換函數(shù)用的較多的就是圖像反轉(zhuǎn)了,根據(jù)上面的參數(shù),圖像反轉(zhuǎn)的變換函數(shù)為:s = 255 ? s。圖像反轉(zhuǎn)得到的是圖像的負(fù)片,能夠有效的增強(qiáng)在圖像暗區(qū)域的白色或者灰色細(xì)節(jié)。其效果如下:
圖像反轉(zhuǎn)的實(shí)現(xiàn)是比較簡(jiǎn)單的,在 OpenCV 中有對(duì) Mat 的運(yùn)算符重載,可以直接 Mat r = 255 - img 或者 ~img 來(lái)實(shí)現(xiàn)。
對(duì)數(shù)變換
對(duì)數(shù)變換的通用公式是:
s = clog ( 1 + r )
其中,c 是一個(gè)常數(shù),,假設(shè) r ≥ 0,根據(jù)上圖中的對(duì)數(shù)函數(shù)的曲線(xiàn)可以看出:對(duì)數(shù)變換,將源圖像中范圍較窄的低灰度值映射到范圍較寬的灰度區(qū)間,同時(shí)將范圍較寬的高灰度值區(qū)間映射為較窄的灰度區(qū)間,從而擴(kuò)展了暗像素的值,壓縮了高灰度的值,能夠?qū)D像中低灰度細(xì)節(jié)進(jìn)行增強(qiáng)。;從函數(shù)曲線(xiàn)也可以看出,反對(duì)數(shù)函數(shù)的曲線(xiàn)和對(duì)數(shù)的曲線(xiàn)是對(duì)稱(chēng)的,在應(yīng)用到圖像變換其結(jié)果是相反的,反對(duì)數(shù)變換的作用是壓縮灰度值較低的區(qū)間,擴(kuò)展高灰度值的區(qū)間。
基于 OpenCV 的實(shí)現(xiàn),其對(duì)數(shù)變換的代碼如下:
float pixels[256]; for (int i = 0; i < 256; i++) pixels[i] = log(1 + i); Mat imageLog(image.size(), CV_32FC3); for (int i = 0; i < image.rows; i++) { for (int j = 0; j < image.cols; j++) { imageLog.at(i, j)[0] = pixels[image.at(i, j)[0]]; imageLog.at(i, j)[1] = pixels[image.at(i, j)[1]]; imageLog.at(i, j)[2] = pixels[image.at(i, j)[2]]; } } //歸一化到0~255 normalize(imageLog, imageLog, 0, 255, CV_MINMAX); //轉(zhuǎn)換成8bit圖像顯示 convertScaleAbs(imageLog, imageLog);
這使用的對(duì)數(shù)函數(shù)的底為10。由于灰度變換是灰度值之間的一對(duì)一的映射,而灰度值區(qū)間通常為[0,255],所以在進(jìn)行灰度變換時(shí),通常使用查表法。也就是,現(xiàn)將每個(gè)灰度值的映射后的結(jié)果計(jì)算出來(lái),在變換時(shí),通過(guò)查表得到變換后的灰度值。執(zhí)行上面結(jié)果得到的結(jié)果如下:
左邊為原圖像,其拍攝環(huán)境較暗,無(wú)法分辨出很多的細(xì)節(jié);右邊為變換后的圖像,整個(gè)圖像明亮許多,也能分辨出原圖中處于暗區(qū)域的狗狗的更多細(xì)節(jié)。
對(duì)數(shù)變換,還有一個(gè)很重要的性質(zhì),能夠壓縮圖像像素的動(dòng)態(tài)范圍。例如,在進(jìn)行傅立葉變換時(shí),得到的頻譜的動(dòng)態(tài)范圍較大,頻譜值的范圍通常為[0,106][0,106],甚至更高。這樣范圍的值,顯示器是無(wú)法完整的顯示如此大范圍的灰度值的,因而許多灰度細(xì)節(jié)會(huì)被丟失掉。而將得到的頻譜值進(jìn)行對(duì)數(shù)變換,可以將其動(dòng)態(tài)范圍變換到一個(gè)合適區(qū)間,這樣就能夠顯示更多的細(xì)節(jié)。
冪律變換(伽馬變換)
s = crγ
其中 c 和 γ 為正常數(shù)。
伽馬變換的效果與對(duì)數(shù)變換有點(diǎn)類(lèi)似,當(dāng) γ >1 時(shí)將較窄范圍的低灰度值映射為較寬范圍的灰度值,同時(shí)將較寬范圍的高灰度值映射為較窄范圍的灰度值;當(dāng) γ < 1 時(shí),情況相反,與反對(duì)數(shù)變換類(lèi)似。其函數(shù)曲線(xiàn)如下:
當(dāng) γ < 1 時(shí),γ 的值越小,對(duì)圖像低灰度值的擴(kuò)展越明顯;當(dāng) γ >1 時(shí),γ 的值越大,對(duì)圖像高灰度值部分的擴(kuò)展越明顯。這樣就能夠顯示更多的圖像的低灰度或者高灰度細(xì)節(jié)。
伽馬變換主要用于圖像的校正,對(duì)灰度值過(guò)高(圖像過(guò)亮)或者過(guò)低(圖像過(guò)暗)的圖像進(jìn)行修正,增加圖像的對(duì)比度,從而改善圖像的顯示效果。
基于OpenCV的實(shí)現(xiàn):
float pixels[256]; for (int i = 0; i < 256; i++) pixels[i] = i * i *i; Mat imageLog(image.size(), CV_32FC3); for (int i = 0; i < image.rows; i++) { for (int j = 0; j < image.cols; j++) { imageLog.at(i, j)[0] = pixels[image.at(i, j)[0]]; imageLog.at(i, j)[1] = pixels[image.at(i, j)[1]]; imageLog.at(i, j)[2] = pixels[image.at(i, j)[2]]; } } //歸一化到0~255 normalize(imageLog, imageLog, 0, 255, CV_MINMAX); //轉(zhuǎn)換成8bit圖像顯示 convertScaleAbs(imageLog, imageLog);
這里選擇的參數(shù)為 c = 1 , γ = 3 ,來(lái)擴(kuò)展圖像的高灰度區(qū)域,其結(jié)果如下:
當(dāng)選擇參數(shù)為 c = 1 , γ = 0.4 , 來(lái)擴(kuò)展圖像的低灰度區(qū)域,其效果如下:
根據(jù)以上的結(jié)果,結(jié)合伽馬變換的函數(shù)曲線(xiàn)圖,做如下總結(jié):
γ >1 時(shí),會(huì)將低于某個(gè)灰度值K的灰度區(qū)域壓縮到較小的灰度區(qū)間,而將高于K的灰度區(qū)域擴(kuò)展到較大灰度區(qū)間。令L為灰度的最大值,k = 3/4L . 那么就有 [ 0 , 3/4L ] 的灰度區(qū)域映射到為 [ 0 , 1/8L ] 的輸出;而將 [ 3/4L , L ] 這部分高灰度區(qū)域映射到 [ 1/8L , L ] 區(qū)間。這樣變換的結(jié)果就是,低于K的灰度區(qū)域被壓縮到更低灰度區(qū)間,而較亮的高灰度區(qū)域的灰度值被擴(kuò)展到較大的灰度區(qū)間變的不那么亮,整體的效果就是圖像的對(duì)比度增加了,但是由于亮度區(qū)域被擴(kuò)展,也就不那么亮了。
γ < 1 時(shí),會(huì)將灰度值較小的低灰度區(qū)域擴(kuò)展到較寬的灰度區(qū)間,而將較寬的高灰度區(qū)域壓縮到較小的灰度區(qū)間。這樣變換的效果就是,低灰度區(qū)域擴(kuò)展開(kāi)來(lái),變亮;而寬的高灰度區(qū)域,被壓縮的較窄的區(qū)間,也變亮了,故變換后的整體效果是變亮了。
基于OpenCV的灰度變換實(shí)現(xiàn)
灰度變換屬于點(diǎn)對(duì)點(diǎn)的一一變換,在實(shí)現(xiàn)的時(shí)候,可以利用查表法。也就是實(shí)現(xiàn)將 [ 0 , 255 ] 區(qū)間的各個(gè)灰度值的變換后的值計(jì)算出來(lái),在變換的時(shí)候直接根據(jù)灰度值進(jìn)行查表得到變換后的結(jié)果。其實(shí)現(xiàn)如下:
///////////////////////////////////////////////////////////////////// // // 灰度線(xiàn)性變換函數(shù) // 參數(shù): // src,輸入原圖像 // dst,輸出圖像,類(lèi)型為CV_32F,大小及通道數(shù)與原圖像相同 // mapping,灰度映射表,可以根據(jù)不同的變換函數(shù),提前計(jì)算好圖像的灰度映射表 // //////////////////////////////////////////////////////////////////// void gray_trans(const Mat& src, Mat& dst,float* mapping) { int channels = src.channels(); if (channels == 1) { dst = Mat(src.size(), CV_32FC1); for (int i = 0; i < src.rows; i++) { float* p1 = dst.ptr(i); const uchar* p2 = src.ptr(i); for (int j = 0; j < src.cols; j++) p1[j] = mapping[p2[j]]; } } else if (channels == 3) { dst = Mat(src.size(), CV_32FC3); for (int i = 0; i < src.rows; i++) { float* p1 = dst.ptr(i); const uchar* p2 = src.ptr(i); for (int j = 0; j < src.cols * 3; j+=3) { p1[j] = mapping[p2[j]]; p1[j+1] = mapping[p2[j+1]]; p1[j+2] = mapping[p2[j+2]]; } } } }
其調(diào)用也比較簡(jiǎn)單,根據(jù)具體的灰度變換函數(shù),填充灰度映射表即可,以伽馬變換為例:
float pixels[256]; for (int i = 0; i < 256; i++) pixels[i] = powf(i, 1.5); Mat imageLog; gray_trans(image, imageLog, pixels);
總結(jié)
本文主要對(duì)圖像的幾種常見(jiàn)的灰度變換進(jìn)行了總結(jié)。
? ? 圖像反轉(zhuǎn),是圖像線(xiàn)性變換的一種,可以得到圖像負(fù)片,能夠有效的增強(qiáng)圖像的暗色區(qū)域中的白色或者灰色細(xì)節(jié)
? ? 對(duì)數(shù)變換,擴(kuò)展圖像中的低灰度區(qū)域,壓縮圖像中的高灰度區(qū)域,能夠增強(qiáng)圖像中的暗色區(qū)域的細(xì)節(jié);反對(duì)數(shù)變換與此相反。對(duì)數(shù)變換還有個(gè)重要作用是,能夠壓縮圖像灰度值的動(dòng)態(tài)范圍,在傅立葉變換中能夠顯示更多的變換后的頻譜細(xì)節(jié)。
? ? 伽馬變換,主要用于圖像的校正,根據(jù)參數(shù)γγ的選擇不同,能夠修正圖像中灰度過(guò)高( γ > 1)或者灰度過(guò)低( γ < 1)
評(píng)論