研究去霧算法有一段時間了,看了很多論文,最終還是覺得何凱明的去霧相關論文最靠譜:
何凱明主頁:http://kaiminghe.com/
暗通道透霧:Single Image Haze Removal
有些圖像處理后感覺自己實現的透霧效果不如作者的效果好。
造成此差異的原因大概是:
①自己的實現有不到位的地方。
②透霧處理后的曝光方式不一樣,由於暗通道方法透霧后會出現圖像偏暗的情況,所以需要曝光處理,但作者的論文中沒有提到他自己用了什么方法。
另外,我在實現過程中其中傳播圖的細化用的是Guided Image Filtering,也試過均值等其他濾波方式,但是很明顯引導濾波的效果更好,原因就是濾波后邊緣效應,據說雙邊濾波的保邊效果不錯,但是自己沒有實現過,大致了解了一下雙邊濾波的快速算法,大概估計其流程比引導濾波會更耗時,加上自己較忙,所以也沒有繼續研究了,希望有實現雙邊濾波的朋友曝一下處理效果及處理時間。
此文沒有介紹關於暗通道的一些流程,但是博客園就不止一篇文章介紹其去霧算法,所以偷個懶直接加個鏈接,感興趣的朋友推薦看看以下文章以及下面的評論。
http://www.cnblogs.com/Imageshop/p/3281703.html;
http://www.cnblogs.com/celerychen/archive/2013/03/23/2976792.html;
另外我現在還存在以下問題:
①目前我實現過的透霧算法都有其自身的缺陷,何凱明的算法也有處理效果不理想的情況。
就目前自己實現的透霧算法中,還沒有一種能夠適應各種雨霧霾圖像的處理,有研究圖像透霧
的朋友歡迎發表你的看法及心得。
②雖然引導濾波的效果用於傳輸圖的細化效果較好,但是實時性遠遠不夠,
單單引導濾波而言,自己期望能達到的效率是,在配置一般的電腦上能夠實時處理(20ms以內)720P灰度圖像。
希望做過並行處理:GPU加速、異構編程、或FPGA等朋友報一下你們有沒有處理過一些圖像濾波(均值、中值、雙邊、甚至引導濾波等等)的加速。能加速到什么程度,這一點很重要。如果我要做相關加速工作需要了解哪些知識,可否推薦一些資料。
下面是我這里的處理效果【如果顯示器偏小,請按 “Ctrl+鼠標滾輪” 縮小頁面進行查看】
這些圖像是經過“暗通道透霧”+“后期曝光處理”兩步完成的。曝光處理用的方法簡單所以效率很高。
關於曝光補償,感興趣的朋友可以看下下面貼出的代碼。如果你有更好的曝光處理方法,能告之當然更好。
如果發現你的實現出來效果更好,請曝圖,我這里好做參考繼續改進,當然,能告之方法自然更好。
不好意思:全部代碼及應用不方便上傳,下面貼出Gama校正調整圖像亮度的代碼,請參考
//圖像的伽馬矯正 void CreateGamaTab(unsigned char* gamaTab, float gama) { float fT = 0; for(int i=0; i<256; i++) { fT = (i+0.5f)/255; fT = (float)pow(fT, gama); int iT = fT*255; if(iT>255) { iT = 255; } else if(iT<0) { iT = 0; } gamaTab[i] = iT; } } //圖像亮度調整 void IMG_GamaCorrection( unsigned char* pSrc, //源圖像數據 unsigned char* pDst, //目標圖像數據,如果為NULL,會直接改變pSrc int width, int height, int stride, //每一行數據字節數 int iChannels, //例如 1=灰度圖 3=RGB24 4=RGB32 double fGama //大致區間 0.1 - 5.0 1.0時沒有變化 低於1.0變暗,高於1.0變亮 ) { //創建查找表 unsigned char GamaTab[256] = {0}; CreateGamaTab(GamaTab, 1/fGama); //*****注意這里有除1操作******* int x,y; unsigned char* pS; unsigned char* pD; if(pDst != NULL) //結果保存在pDst { if(iChannels == 1)//單通道圖像 { for(y=0; y<height; y++) { pS = pSrc + y*stride; pD = pDst + y*stride; for(x=0; x<width; x++) { pD[0] = GamaTab[pS[0]]; pS+=iChannels; pD+=iChannels; } } } else//多通道彩色 { for(y=0; y<height; y++) { pS = pSrc + y*stride; pD = pDst + y*stride; for(x=0; x<width; x++) { pD[0] = GamaTab[pS[0]]; pD[1] = GamaTab[pS[1]]; pD[2] = GamaTab[pS[2]]; pS+=iChannels; pD+=iChannels; } } } } else //直接改變原圖 { if(iChannels == 1)//單通道圖像 { for(y=0; y<height; y++) { pS = pSrc + y*stride; for(x=0; x<width; x++) { pS[0] = GamaTab[pS[0]]; pS+=iChannels; } } } else//多通道彩色 { for(y=0; y<height; y++) { pS = pSrc + y*stride; for(x=0; x<width; x++) { pS[0] = GamaTab[pS[0]]; //gama校正 pS[1] = GamaTab[pS[1]]; //gama校正 pS[2] = GamaTab[pS[2]]; //gama校正 pS+=iChannels; } } } } }