整理的比較好的影象去霧演算法

整理的比較好的影象去霧演算法

2016.03,24 再補充幾個搜尋到的資料:

論文的翻譯,不太好,湊合看   http://wenku.baidu.com/link?url=SwSoHn-7IfxY7pp-VEway9fRMM5AOlc1j2xvIQytUivfqSSHm-j5moJVr3EYDOUblLo-VMDOF2sxCvNGYgFBUNJ4-zIhBEJTwn7ATfXcO7q

論文的原文: http://wenku.baidu.com/view/5391746365ce0508773213b9.html

用opencv實現的,有程式碼和詳細的解釋,但是效率非常低,程式碼有很大的改進空間,僅作參考吧

http://www.cnblogs.com/changkaizhao/p/3266798.html

1 首先是何博士2009年在CVPR上的一篇paper

轉自

http://blog.csdn.net/baimafujinji/article/details/27206237?ticket=ST-264104-uEM9GFfaos96lqSCMO4R-passport.csdn.net

論文中解釋為什麼能用暗通道來去霧:在不包括天空的絕大部分區域性區域,總會存在一些我們稱之為“dark pixels”的畫素,至少有一個顏色通道具備很低的強度值。在被霧干擾的影象裡,這些暗畫素的強度值會被大氣中的白光成分所充斥而變得較高。 因此,這些暗畫素能夠直接用來評估霧光的透射資訊

          方程右邊的第一項J(x)t(x) 叫做直接衰減項,第二項A(1-t(x)) 則是大氣光成分。直接衰減項描述的是景物光線在透射媒介中經衰減後的部分,而大氣光則是由前方散射引 起的,會導致景物顏色的偏移。

現在結果已經比較細膩了,但是顯然影象有些暗。何博士在論文中也有提及直接暗通道演算法的結果會是比較暗的。下一篇文章中,我們將給出在MATLAB中實現的原始碼,並對過暗的影象增加曝光和自動色階,從而得到完美的去霧影象。

補充:http://www.cnblogs.com/Imageshop/category/535365.html

何的演算法效果以及普遍的實用性都比其他的去霧演算法要好,而主要的問題就是其速度還是不夠快,有著太多的浮點計算。鑑於此,作者也多次試著對程式碼進行深層次的優化,包括SSE處理、並行執行等,但由於演算法本身的順序執行,無法全程並行,偶爾一個小函式可以並行,但由於其本身執行就特別快,比如不要5ms,你去用並行演算法可能耗時還會大一些。因此,一直沒有什麼大的進步,對於一副1024*768的彩圖進行去霧需要90ms,這肯定無法滿足需求。

     最近,在思考,既然暗通道去霧的透射率圖比其他的演算法都來的精細,如果適當的降低一點點其精度,其去霧的效果理論上應該不會有太大的區別,於是我想到了一種方式,即求取透射率的時候不是對原圖進行求取,而是先對原圖進行下采樣,比如縮小為原圖的1/4,計算出小圖的透射率,之後在通過插值的方式的獲取原圖大概的透射率,則應該也可以獲得效果。經過實踐,這種方式大大的提高了執行速度,而且效果和原始的方案基本一致,對於1024*768的影象大約只需要(I3CPU)30ms了,如果進一步取1/9的縮放,則只需要大約20ms,完全可以滿足工業實時性要求高的場合。

    當然,如果你的縮小系數不是特別大的話,比如縮小為原來的0.5大小,可能兩次縮放所用的耗時還抵消了計算小圖的透射率圖所換來的盈利,因此必須合理選擇這個下取樣率。

    要實現這樣的速度,當然還是需要很高的優化技巧的,這些東西還是有所保留比較好。

2Optimized contrast enhancement for real-time image and video dehazing

    這個演算法的原理來自於文章《Optimized contrast enhancement for real-time image and video dehazing》,作者是韓國人。

      這個演算法也是基於大氣散射模型:

          

   和現在一些常見的去霧文章有明顯的不同的是,這篇文章的並不是基於暗通道原理的,也不是把重點強調在透射率圖的細化上,而是提出了一種新的得到粗透射率圖的方法。並且文章分別講到了靜態影象和視訊影象的去霧,這裡我只研究了靜態圖的去霧。

      對於透射率圖,文章提出了一個cost function,這個cost function是基於以下兩點考慮的:

      1、對於有霧影象,其整體的對比比較低,因此去霧後的對比度要儘量的高,文中給出了三種測評一幅影象對比度的方式,這裡選用的是第一種:

                    

    公式具體的意義可見論文。注意上面的公式都是對去霧圖進行的處理。

  2、 由於對比度得到增強,可能會導致部分畫素的調整值超出了0和255的範圍,這樣就會造成資訊的損失以及視覺上的瑕疵。因此提出了一個資訊量損失的計算公式:

                                                

     一個好的透射率圖應該使得總的損失最小:

                                      

       其中Lamda值用於控制對比度和資訊損失之間的重要性。

            進行上述過程還有一個重要的前提就是:對於一小塊影象,我們認為他的透射率是一樣的,以下作者提供的程式碼表面了這一點:

for(nY=0; nY<nHei; nY =m_nTBlockSize)
{
for(nX=0; nX<nWid; nX =m_nTBlockSize)
{
fTrans = NFTrsEstimationPColor(pnImageR, pnImageG, pnImageB, pnImageRP, pnImageGP, pnImageBP, pfTransmissionP, __max(nX, 0), __max(nY, 0), nWid, nHei);
for(nYstep=nY; nYstep<nY m_nTBlockSize; nYstep  )
{
for(nXstep=nX; nXstep<nX m_nTBlockSize; nXstep  )
{
pfTransmission[nYstep*nWid nXstep] = fTrans;
}
}
}
}

  其中的NFTrsEstimationPColor是用來估計一個塊的最佳透射率值,作者在程式設計時,是將透射率按照0.1的間距進行取樣,然後找到使得上式最小值得那個透射率作為這個塊的透射率。

nEndX = __min(nStartX m_nTBlockSize, nWid); // End point of the block
nEndY = __min(nStartY m_nTBlockSize, nHei); // End point of the block
nNumberofPixels = (nEndY-nStartY)*(nEndX-nStartX);    
fTrans = 0.3f;    // Init trans is started from 0.3
nTrans = 427;    // Convert transmission to integer 
for(nCounter=0; nCounter<7; nCounter  )
{
nSumofSLoss = 0;
nLossCount = 0;
nSumofSquaredOuts = 0;
nSumofOuts = 0;
for(nY=nStartY; nY<nEndY; nY  )
{
for(nX=nStartX; nX<nEndX; nX  )
{
nOut = ((pnImageY[nY*nWid nX] - m_nAirlight)*nTrans   128*m_nAirlight)>>7; // (I-A)/t   A --> ((I-A)*k*128   A*128)/128
nSquaredOut = nOut * nOut;
if(nOut>255)
{
nSumofSLoss  = (nOut - 255)*(nOut - 255);
nLossCount  ;
}
else if(nOut < 0)
{
nSumofSLoss  = nSquaredOut;
nLossCount  ;
}
nSumofSquaredOuts  = nSquaredOut;
nSumofOuts  = nOut;
}
}
fMean = (float)(nSumofOuts)/(float)(nNumberofPixels);  
fCost = m_fLambda1 * (float)nSumofSLoss/(float)(nNumberofPixels) 
- ((float)nSumofSquaredOuts/(float)nNumberofPixels - fMean*fMean); 
if(nCounter==0 || fMinCost > fCost)
{
fMinCost = fCost;
fOptTrs = fTrans;
}
fTrans  = 0.1f;
nTrans = (int)(1.0f/fTrans*128.0f);
}

  朋友們有沒有看到上面的程式碼中的最小透射率是0.3,我個人認為這個只能夠有效的避免天空部位被過增強。

      文中提到了這個方法也可以看成是何凱明的暗通道去霧演算法的一個更廣義的定義。

     在這個文章,還提出了另外一個和其他演算法不同的東西,就是全域性大氣光A的獲取,其主要原理是: the variance of pixel values is generally low in hazy regions, e.g. sky. 具體的操作流程是:

       we first divide an input image into four rectangular regions. We then define the score of each region as the average pixel value subtracted by the standard deviation of the pixel values within the region. Then, we select
the region with the highest score and divide it further into four smaller regions.We repeat this process until the size of the selected region is smaller than a pre-specified threshold. Within the selected region, we choose the color vector, which minimizes
the distance ||(R,G,B) -(255,255,255)||as the atmospheric light. By minimizing the distance from the pure white vector(255,255,255), we attempt to choose the atmospheric light that is as bright as possible.

  結合上述描述以及論文配套的程式碼可以很容易的理解這裡的道理。論文的配套程式碼的實現也很好。

  具體的流程還是請各位仔細的閱讀論文及其程式碼,經過我自己的優化和實踐,這個演算法確實能得到很不錯的效果,在速度上也能夠達到實時。

      在貼一些效果圖(有的時候只有看到這些圖,才很有成就感)。

 

 

 論文及原作者的程式碼下載地址:http://mcl.korea.ac.kr/projects/dehazing/#userconsent# (這個原始碼是OPENCV寫的)