最近一直沒有找到感興趣的研究課題,下了幾個最新的去霧的論文,隨便看了下,覺得都是為了寫論文而做的論文,沒有什麼創新性,也就沒有想法去實現他們。偶爾看到了一些關於水下影象增強方面的文章,閒來無聊試著去看看效果,不過也覺得非常讓人失望,似乎並沒有特別有效的演算法。
就我看得幾篇文章而言,這類演算法都不是從原理上、或者說某一個數學模型、抑或是某種先驗知識出發,而提出的演算法,都是一種沒有什麼特強的理論支援,只是通過一些實際的試驗而得到的一些過程而已。這些過程對於論文字身中提供的測試影象都有著較為理想的處理效果,而一旦選擇一副其他性質的水下影象,其結果往往難以令人滿意。因此,也就沒有類似於去霧演算法界暗通道先驗那樣不可逾越的黃金文章了。
我看了三篇文章,第一篇是Underwater Image Enhancement Using an Integrated Colour Model,07年的文章,演算法的細路很簡單,借用文章中的一副流程圖來說明下:
很簡單的步驟,首先是進行對比度拉昇,可以看成是類似於PS中的自動對比度,接著將處理後的影象轉換到HSI顏色空間,在對S和I分量進行拉昇,之後再將HSI空間的資料轉換到RGB空間得到最終的影象。在百度上搜尋誰下影象增強,能搜尋到一個相關的專利,見http://www.google.com/patents/CN102930512A?cl=zh,這個專利的內容其實也沒啥新意,一樣的就是在HSI空間將S和I分量用其他的方式進行了拉昇和處理,還是發明專利,呵呵,大家都知道國內專利是怎麼回事。
這篇論文對演算法部分的描述還是過於簡單,雖然對比度拉昇給了個公式,但並沒有明確的說明S和I分量的具體處理流程,他給的兩篇參考文獻對應的網站也無法開啟了,因此無法對原始的演算法進行驗證,我用GIMP的對比度拉昇 + HSV拉昇未能達到論文中的效果。
第二篇和第三篇都是用的影象融合的方式來處理的,分別是Enhancing Underwater Images and Videos by Fusion以及Effective Single Underwater Image Enhancement by Fusion,後一篇是國內合工大和中科大的作者寫的,很明顯可以看得出模仿的筆跡 。
其實這種通過融合的方式也很簡單,就是先找兩種演算法得到對原圖兩種不同程度的增強的結果,然後選擇好一個融合係數的計算公式,再進行拉普拉斯金字塔融合,從而提取更好的結果。Enhancing Underwater Images and Videos by Fusion這篇文章就是選用了白平衡的結果(記為I1)作為融合的物件一, 用對I1進行雙邊濾波+CALHE之類的演算法處理的結果(記為I2)作為融合的物件2。標準的拉普拉斯融合的融合演算法一般有:最大值、最小值、平均值,這裡則修改為某一種權重係數的融合,最後進行拉普拉斯融合。
因此,這個演算法的處理結果的好壞性完全取決於融合的物件,即兩個前處理演算法。但是同樣存在的問題就是演算法的普遍適應性,某一種前處理對某一類合適,對其他的就不一定了。
我這裡經過一些實驗,也提出一種前處理演算法,這個演算法的效果可以在GIMP的顏色--》自動--》色調均化中看到。
雖然GIMP是一個類似PS的軟體,但兩者的色調均化效果完全不同,檢視GIMP的程式碼就能知道這是為什麼了,我這裡貼出GIMP的這個演算法的核心程式碼部分:
static void equalize_lut_setup (GimpLut *lut, GimpHistogram *hist, gint n_channels) { gint i, k, j; hist_lut_struct hlut; gdouble pixels_per_value; gdouble desired; gdouble sum, dif; g_return_if_fail (lut != NULL); g_return_if_fail (hist != NULL); /* Find partition points */ pixels_per_value = gimp_histogram_get_count (hist, GIMP_HISTOGRAM_VALUE, 0, 255) / 256.0; for (k = 0; k < n_channels; k++) { /* First and last points in partition */ hlut.part[k][0] = 0; hlut.part[k][256] = 256; /* Find intermediate points */ j = 0; sum = (gimp_histogram_get_channel (hist, k, 0) + gimp_histogram_get_channel (hist, k, 1)); for (i = 1; i < 256; i++) { desired = i * pixels_per_value; while (sum < desired && j < 256) { j++; sum += gimp_histogram_get_channel (hist, k, j + 1); } /* Nearest sum */ dif = sum - gimp_histogram_get_channel (hist, k, j); if ((sum - desired) > (dif / 2.0)) hlut.part[k][i] = j; else hlut.part[k][i] = j + 1; } } gimp_lut_setup (lut, (GimpLutFunc) equalize_lut_func, &hlut, n_channels); }
void gimp_lut_setup (GimpLut *lut, GimpLutFunc func, void *user_data, gint nchannels) { guint i, v; gdouble val; if (lut->luts) { for (i = 0; i < lut->nchannels; i++) g_free (lut->luts[i]); g_free (lut->luts); } lut->nchannels = nchannels; lut->luts = g_new (guchar *, lut->nchannels); for (i = 0; i < lut->nchannels; i++) { lut->luts[i] = g_new (guchar, 256); for (v = 0; v < 256; v++) { /* to add gamma correction use func(v ^ g) ^ 1/g instead. */ val = 255.0 * func (user_data, lut->nchannels, i, v/255.0) + 0.5; lut->luts[i][v] = CLAMP (val, 0, 255); } } }
gimp的程式碼看起來相當晦澀的,但是實際上上述演算法要描述的意思很簡單,就是我希望我調整後的影象的直方圖在每個色階上的分佈概率都是一樣的。其實這個過程就可以看成是直方圖規定化的一個過程,舉例如下:
原 圖 處理後的圖
原圖B/G/R對應的直方圖 待匹配的直方圖 處理後的直方圖
可見處理後的直方圖已儘量向帶匹配的模式靠近,但不可能完全一樣。
用這個過程處理了幾幅論文中帶的水下影象,效果如下:
最後一幅圖在Enhancing Underwater Images and Videos by Fusion一文中的效果是非常棒的,主要是過度的很自然,這個應該融合在其作用吧。
融合這種處理方式確實一個值得推廣的想法,因此那篇論文才會成為2012的CVPR論文之一的。
*********************************作者: laviewpbt 時間: 2014.4.6 聯絡QQ: 33184777 轉載請保留本行資訊************************