到圖像質(zhì)量評(píng)價(jià))
簡(jiǎn)介一套面向水下圖像處理研究者的MATLAB仿真資源聚焦暗通道先驗(yàn)與顏色校正包含暗通道先驗(yàn)、折射率計(jì)算、顏色校正三個(gè)核心子模塊能夠有效改善水下圖像偏色與模糊問(wèn)題適合圖像處理方向的學(xué)生、科研人員及工程師參考學(xué)習(xí)。資源共16個(gè)文件以6個(gè).m腳本為主覆蓋暗通道求取、透射率計(jì)算、顏色校正、主測(cè)試等關(guān)鍵步驟另含5張實(shí)驗(yàn)圖像、2張算法流程圖、2份PDF說(shuō)明及1份MD文檔整體僅2.35MB結(jié)構(gòu)緊湊。目前已有800人學(xué)習(xí)使用。壓縮包內(nèi)提供完整可運(yùn)行的仿真代碼、算法流程圖及配套論文讀者可對(duì)照代碼逐步理解暗通道先驗(yàn)參數(shù)獲取、折射率計(jì)算與顏色校正的銜接邏輯并結(jié)合輸出圖像與質(zhì)量評(píng)價(jià)結(jié)果直觀驗(yàn)證恢復(fù)效果便于在此基礎(chǔ)上進(jìn)行算法改進(jìn)或論文實(shí)驗(yàn)復(fù)現(xiàn)。1. 水下圖像為什么發(fā)藍(lán)發(fā)綠先把退化模型說(shuō)清楚第一次拿到水下視頻的工程師都會(huì)問(wèn)同一個(gè)問(wèn)題為什么畫(huà)面發(fā)藍(lán)或發(fā)綠紅色去哪了答案不在相機(jī)參數(shù)而在水體本身。藍(lán)綠光波長(zhǎng)短、穿透力強(qiáng)紅光在 3 米左右深度衰減大半更深處幾乎為零。所以水下顏色校正是通道能量缺失的補(bǔ)償不是普通白平衡能解決的色溫漂移。標(biāo)題把「水下暗通道」「水下顏色校正」「圖像質(zhì)量評(píng)價(jià)」放在一起本質(zhì)上是一條完整鏈路先用暗通道模型的物理假設(shè)估計(jì)透射率再做通道補(bǔ)償還原顏色最后用客觀指標(biāo)確認(rèn)校正效果。這套流程不挑硬件普通 RGB 相機(jī)拍的 underwaterimage 就能跑適合做水下機(jī)器人視覺(jué)、海洋工程檢測(cè)和水下攝影后期的人。2. 水下暗通道先驗(yàn)從大氣去霧到水下改寫(xiě)的核心原理2.1 為什么暗通道在水下不能直接照搬暗通道先驗(yàn)最初是給大氣去霧用的核心假設(shè)是無(wú)霧自然圖像的局部區(qū)域里至少有一個(gè)通道的像素值趨近于零。基于這個(gè)假設(shè)單張圖像就能估計(jì)透射率和背景光反解出清晰圖像。大氣成像模型寫(xiě)作I_c(x) J_c(x) · t_c(x) A_c · (1 - t_c(x))其中 c 是通道索引J 是恢復(fù)后的輻射度t 是透射率A 是背景光。水下模型形式一樣但關(guān)鍵差異在透射率大氣里 t 只跟距離有關(guān)水下 t 還跟波長(zhǎng)強(qiáng)相關(guān)——紅光衰減最快、透射率最低藍(lán)綠光透射率高。所以水下暗通道改寫(xiě)時(shí)要么逐通道估計(jì)透射率要么先把通道差異拉平再共用一張透射率圖。工程上多數(shù)選后者逐通道估計(jì)的計(jì)算量翻三倍肉眼差異很小。直接照搬大氣版本還有一個(gè)坑紅通道幾乎全滅把紅通道納入暗通道最小值計(jì)算會(huì)把紅色物體、沙地這類本來(lái)就偏紅的區(qū)域誤判成濃霧區(qū)透射率被壓得過(guò)低恢復(fù)出來(lái)的圖發(fā)紫、發(fā)藍(lán)。常見(jiàn)做法是把暗通道計(jì)算限制在藍(lán)綠兩個(gè)通道上或者先對(duì)紅通道做補(bǔ)償再算。2.1.1 紅通道補(bǔ)償?shù)暮?jiǎn)便公式算暗通道之前先用吸收比例做通道補(bǔ)償comp_r(x) I_r(x) α · (avg_g - avg_r) · (1 - I_r(x) / bit_depth)α 是補(bǔ)償強(qiáng)度取 0.3~0.8avg_g 和 avg_r 是綠、紅通道的全局均值。式子的含義是紅通道缺失的能量按像素亮度比例補(bǔ)回——暗部補(bǔ)得多亮部補(bǔ)得少避免高光區(qū)域顏色過(guò)沖。補(bǔ)完后紅通道才具備參與暗通道計(jì)算的資格。2.2 水下暗通道的 OpenCV 實(shí)現(xiàn)從暗通道圖到透射率下面是一套能直接跑的 Python 實(shí)現(xiàn)只依賴 OpenCV 和 NumPyimport cv2 import numpy as np def red_channel_compensation(img, alpha0.5): b, g, r cv2.split(img.astype(np.float32)) avg_g, avg_r g.mean(), r.mean() r r alpha * (avg_g - avg_r) * (1.0 - r / 255.0) return cv2.merge([b, g, np.clip(r, 0, 255)]) def dark_channel(img, patch15): # 通道間取最小值再做最小值濾波得到暗通道圖 dark img.min(axis2) kernel cv2.getStructuringElement(cv2.MORPH_RECT, (patch, patch)) return cv2.erode(dark, kernel) def background_light(img, dark): h, w dark.shape top int(h * w * 0.001) flat_dark dark.ravel() flat_img img.reshape(-1, img.shape[2]) idx np.argpartition(flat_dark, -top)[-top:] return flat_img[idx].mean(axis0) def transmission(dark, background, w0.95): b, g, r background # 按背景光歸一化后取暗通道反解透射率 norm np.minimum(np.minimum(dark / (b 1e-6), dark / (g 1e-6)), dark / (r 1e-6)) return 1.0 - w * norm這段代碼的四個(gè)步驟依次是red_channel_compensation先做紅通道補(bǔ)償讓紅通道參與暗通道計(jì)算時(shí)不至于拉偏背景光的估計(jì)。dark_channel對(duì)每個(gè)像素取三通道最小值再用cv2.erode做矩形最小值濾波得到暗通道圖。background_light取暗通道最亮的前 0.1% 像素回原圖取這些位置的均值當(dāng)背景光。transmission按衰減模型反解透射率w是保留少量霧感的系數(shù)。需要注意background_light必須接收補(bǔ)償后的圖像否則背景光會(huì)偏向綠色水體本身導(dǎo)致整張圖的透射率被均勻壓低。透射率圖如果噪聲明顯可以疊加一步引導(dǎo)濾波做邊緣保持平滑OpenCV 的edgePreservingFilter可以直接替代參數(shù)里 sigma 取 30~60 效果比較穩(wěn)。2.2.1 透射率偏低與噪點(diǎn)放大的處理恢復(fù)場(chǎng)景輻照度時(shí)透射率要加下限t0J(x) (I(x) - A) / max(t(x), t0) At0 取 0.1~0.25。如果恢復(fù)出的圖明顯偏暗偏紅多半是w太大把透射率壓太狠如果噪點(diǎn)特別多是t0太小或者 patch 過(guò)小導(dǎo)致邊緣透射率過(guò)估計(jì)。2.3 patch 大小與背景光策略的參數(shù)對(duì)照表patch 尺寸直接決定暗通道的稀疏程度。patch 太小會(huì)把細(xì)節(jié)誤當(dāng)霧透射率噪聲大patch 太大暗通道偏亮透射率整體偏低圖像發(fā)暗。參數(shù)推薦范圍場(chǎng)景說(shuō)明patch 尺寸15~251080p 圖像取 20 以上低分辨率取 15w保留霧感系數(shù)0.85~0.95霧感重的視頻取 0.95較清源取 0.85t0透射率下限0.1~0.25噪點(diǎn)敏感場(chǎng)景取 0.25alpha紅通道補(bǔ)償0.3~0.8水深大于 5 米取 0.8淺水取 0.33. 水下顏色校正白平衡、灰度世界與顏色補(bǔ)償?shù)穆涞貐?shù)3.1 三套方法怎么選水下暗通道解決的是霧感和對(duì)比度顏色偏色得靠顏色校正。常見(jiàn)的 underwaterCorrection 管線里顏色校正有三條路線灰度世界白平衡、基于分位數(shù)的通道拉伸、基于吸收系數(shù)的物理補(bǔ)償。灰度世界假設(shè)場(chǎng)景平均反射是中性灰三通道均值應(yīng)當(dāng)相等。它最怕的場(chǎng)景是海底大片綠色藻類或開(kāi)闊藍(lán)色水體——這個(gè)時(shí)候均值本身就是主題色校正完反而偏紅。白平衡變體適合大多數(shù)淺水場(chǎng)景速度快、參數(shù)少但深水里紅通道幾乎歸零時(shí)單純縮放無(wú)能為力。實(shí)際項(xiàng)目里我按深度分流5 米內(nèi)先用灰度世界白平衡再做對(duì)比度拉伸5 米以上先用第 2 章的暗通道管線恢復(fù)輻照度再做物理補(bǔ)償。物理補(bǔ)償依據(jù)是水對(duì)不同波長(zhǎng)吸收系數(shù)不同紅通道衰減最快、補(bǔ)償量最大。補(bǔ)償后飽和度會(huì)偏高需要配合 CLAHE 做局部亮度均衡。3.2 灰度世界白平衡的 OpenCV 實(shí)現(xiàn)def gray_world_white_balance(img, scale_limit2.0): b, g, r cv2.split(img.astype(np.float32)) avg (b.mean() g.mean() r.mean()) / 3.0 scale [] for c in (b, g, r): s avg / (c.mean() 1e-6) # 限制縮放因子防止純色水體導(dǎo)致單通道過(guò)沖 scale.append(np.clip(s, 1.0 / scale_limit, scale_limit)) out cv2.merge([np.clip(c * s, 0, 255) for c, s in zip((b, g, r), scale)]) return out.astype(np.uint8)這段代碼的核心是每個(gè)通道乘一個(gè)全局縮放因子讓三通道均值向共同均值靠攏。scale_limit是容易被忽略的參數(shù)在均勻純色水體里綠通道均值異常高紅通道縮放因子會(huì)被推到 3 倍以上clip 到 255 后高光細(xì)節(jié)全部丟失。把縮放因子限制在 0.5~2.0 范圍內(nèi)顏色校正不足也比過(guò)沖好后續(xù)還可以用其他手段補(bǔ)。3.3 顏色補(bǔ)償?shù)膹?qiáng)度和邊界參數(shù)對(duì)照表走暗通道管線后殘余的偏色用補(bǔ)償公式微調(diào)。補(bǔ)償不要做滿做滿會(huì)泛紅紅通道溢出后沙地和魚(yú)群的顏色都失真。參數(shù)推薦值作用調(diào)大后的副作用補(bǔ)償強(qiáng)度 α0.3~0.6控制紅通道補(bǔ)回能量泛紅、綠植顏色失真CLAHE clipLimit2.0~4.0限制局部對(duì)比度放大噪點(diǎn)被放大CLAHE tileGridSize8×8局部直方圖均衡窗口窗口過(guò)小出現(xiàn)塊狀偽影縮放因子上下限0.5~2.0防止顏色過(guò)沖限制過(guò)窄校正不足4. 水下圖像質(zhì)量評(píng)價(jià)UCIQE、UIQM 與對(duì)比度指標(biāo)的計(jì)算4.1 為什么水下不能只看 PSNR 和 SSIMPSNR 和 SSIM 都需要參考圖水下增強(qiáng)領(lǐng)域絕大多數(shù)場(chǎng)景沒(méi)有 ground truth——你不可能在同一物理位置拍一張清晰版本。所以無(wú)參考指標(biāo)才是水下圖像質(zhì)量評(píng)價(jià)的主戰(zhàn)場(chǎng)。常用的無(wú)參考指標(biāo)有三類UCIQE水下彩色圖像質(zhì)量評(píng)價(jià)、UIQM水下圖像質(zhì)量度量、以及信息熵和對(duì)比度這類基礎(chǔ)統(tǒng)計(jì)量。UCIQE 的出發(fā)點(diǎn)是給水下圖像人眼敏感的退化維度打分色偏、模糊、低對(duì)比度。UIQM 更進(jìn)一步模仿人眼視覺(jué)系統(tǒng)的感知屬性分成色彩度、清晰度、對(duì)比度三個(gè)子得分再加權(quán)。實(shí)際使用中 UCIQE 對(duì)色偏更敏感UIQM 對(duì)清晰度更敏感兩個(gè)一起報(bào)才有說(shuō)服力。4.2 UCIQE 的輕量實(shí)現(xiàn)UCIQE 是三個(gè)分量的加權(quán)線性組合UCIQE c1 · σ_chroma c2 · conl c3 · μ_sat其中 σ_chroma 是色度標(biāo)準(zhǔn)差conl 是亮度對(duì)比度亮度高低分位的差μ_sat 是飽和度均值。權(quán)重取論文常用值 c10.4680、c20.2745、c30.2576。實(shí)現(xiàn)如下def uciqe(img): lab cv2.cvtColor(img, cv2.COLOR_BGR2LAB).astype(np.float32) l, a, b cv2.split(lab) # 色度a、b 通道的幅值 chroma np.sqrt(a**2 b**2) sigma_chroma chroma.std() # 對(duì)比度亮度通道 1% 與 99% 分位的差 lo, hi np.percentile(l, [1, 99]) conl hi - lo mu_sat chroma.mean() / 255.0 return 0.4680 * sigma_chroma 0.2745 * conl 0.2576 * mu_sat這套實(shí)現(xiàn)里飽和度μ_sat用色度均值近似嚴(yán)格說(shuō)飽和度要按亮度歸一化但工程上兩個(gè)量高度相關(guān)用色度算更快。單張 1080p 圖像在 CPU 上不到 20 毫秒可以放進(jìn)視頻流里逐幀評(píng)估。UIQM 的實(shí)現(xiàn)相對(duì)繁瑣網(wǎng)上有開(kāi)源的 MATLAB 和 Python 版本直接用原作者的子得分權(quán)重即可不建議自己調(diào)權(quán)重——那會(huì)讓不同論文的對(duì)比失去意義。4.2.1 指標(biāo)對(duì)比時(shí)的基線怎么定跑評(píng)價(jià)之前定好對(duì)比基線至關(guān)重要原始圖、暗通道恢復(fù)圖、暗通道加顏色校正圖三個(gè)一起算 UCIQE記錄每組參數(shù)下的分?jǐn)?shù)變化。注意 UCIQE 不是越高越好過(guò)度校正導(dǎo)致飽和度溢出時(shí)數(shù)值反而升高這時(shí)必須抽幀人眼確認(rèn)。4.3 指標(biāo)怎么讀才不是自欺欺人單個(gè) UCIQE 數(shù)值沒(méi)有絕對(duì)意義它的價(jià)值在相對(duì)比較。常見(jiàn)做法是同一張圖把增強(qiáng)前后的分?jǐn)?shù)放一起看提升幅度同時(shí)跑 UIQM 驗(yàn)證一致性。如果 UCIQE 漲了 15% 但 UIQM 掉了說(shuō)明色彩增強(qiáng)過(guò)頭、清晰度受損需要回調(diào)顏色補(bǔ)償強(qiáng)度。反過(guò)來(lái)UCIQE 幾乎不動(dòng)但 UIQM 明顯上漲說(shuō)明這步操作主要貢獻(xiàn)在去霧提清晰度顏色的賬還沒(méi)算完。5. 從水下暗通道到顏色校正再回到質(zhì)量評(píng)價(jià)的一體化驗(yàn)證最后講一個(gè)把整條鏈路串起來(lái)的小技巧讓質(zhì)量評(píng)價(jià)指標(biāo)反過(guò)來(lái)驅(qū)動(dòng)參數(shù)搜索而不是調(diào)完參數(shù)再看指標(biāo)這樣能省掉大量肉眼試錯(cuò)。def evaluate_stage(img, alpha): comp red_channel_compensation(img, alpha) dark dark_channel(comp, patch20) bg background_light(comp, dark) t transmission(dark, bg) restored (comp - bg) / np.maximum(t, 0.2) bg restored np.clip(restored, 0, 255).astype(np.uint8) wb gray_world_white_balance(restored) return uciqe(wb), wb best_score, best_result 0, None for alpha in [0.1, 0.3, 0.5, 0.7]: score, result evaluate_stage(img, alpha) if score best_score: best_score, best_result score, result這個(gè)循環(huán)把 alpha 當(dāng)成待搜索變量用 UCIQE 當(dāng)損失函數(shù)幾次迭代就能找到當(dāng)前幀的最優(yōu)補(bǔ)償強(qiáng)度。逐幀搜索不建議用在視頻流上每 30 幀采樣一次、參數(shù)再平滑過(guò)渡否則幀間閃爍會(huì)非常明顯。兩個(gè)容易踩的坑。第一個(gè)是順序先做紅通道補(bǔ)償為暗通道服務(wù)恢復(fù)場(chǎng)景輻照度之后再白平衡。順序顛倒白平衡會(huì)拖偏透射率估計(jì)恢復(fù)出的圖對(duì)比度不足。第二個(gè)是精度中間結(jié)果必須保持 float32cv2.merge前檢查通道數(shù)和 dtypeuint8 截?cái)鄷?huì)讓暗通道最小值計(jì)算出現(xiàn)隱性誤差整張圖發(fā)灰還找不到原因。本文還有配套的精品資源點(diǎn)擊獲取