最近一直沒有找到感興趣的研究課題,下了幾個最新的去霧的論文,隨便看了下,覺得都是為了寫論文而做的論文,沒有什么創新性,也就沒有想法去實現他們。偶爾看到了一些關於水下圖像增強方面的文章,閑來無聊試着去看看效果,不過也覺得非常讓人失望,似乎並沒有特別有效的算法。
就我看得幾篇文章而言,這類算法都不是從原理上、或者說某一個數學模型、抑或是某種先驗知識出發,而提出的算法,都是一種沒有什么特強的理論支持,只是通過一些實際的試驗而得到的一些過程而已。這些過程對於論文本身中提供的測試圖像都有着較為理想的處理效果,而一旦選擇一副其他性質的水下圖像,其結果往往難以令人滿意。因此,也就沒有類似於去霧算法界暗通道先驗那樣不可逾越的黃金文章了。
我看了三篇文章,第一篇是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 轉載請保留本行信息************************