實(shí)戰(zhàn):從噪聲成因到工程落地)
簡介圖像去噪是計(jì)算機(jī)視覺中的經(jīng)典問題但紅外圖像因成像鏈路復(fù)雜噪聲遠(yuǎn)非簡單的高斯白噪聲。固定圖案噪聲、條紋噪聲、壞元與隨機(jī)噪聲疊加導(dǎo)致通用去噪算法常失效。理解噪聲成因是算法選型的前提傳統(tǒng)方法如兩點(diǎn)校正、全變分、低秩分解擅長抑制結(jié)構(gòu)化噪聲而深度學(xué)習(xí)模型如DnCNN、FFDNet則更擅長處理隨機(jī)噪聲但需注意位深、歸一化與感受野等細(xì)節(jié)。在工程實(shí)踐中數(shù)據(jù)構(gòu)造、壞元替換、訓(xùn)練策略與指標(biāo)評估同等重要PSNR與SSIM之外還需結(jié)合邊緣保持度和條紋抑制程度。從論文復(fù)現(xiàn)到方案落地需要針對真實(shí)紅外場景進(jìn)行適配與優(yōu)化才能讓去噪增強(qiáng)真正服務(wù)于監(jiān)控、檢測等應(yīng)用。 如果你手里也攥著一份《紅外圖像去噪增強(qiáng)算法論文和代碼合集》大概率有兩種心態(tài)一種是覺得撿到寶了終于不用一篇篇翻論文、一個(gè)個(gè)倉庫找代碼另一種是解壓之后反而有點(diǎn)懵——論文幾十篇代碼項(xiàng)目五六個(gè)不知道從哪看起也不知道哪個(gè)方案真正適合自己手頭的紅外數(shù)據(jù)。我屬于后者而且前前后后折騰了幾個(gè)月才把“下載資源”變成“能跑的成果”。這篇內(nèi)容就是把這些篩選、復(fù)現(xiàn)、調(diào)優(yōu)的過程整理出來給同樣在做紅外圖像去噪增強(qiáng)的同學(xué)一個(gè)參考。我的應(yīng)用場景是紅外監(jiān)控相機(jī)采集到的視頻幀序列白天夜間都在用圖像里既有固定條紋噪聲又有隨時(shí)間變化的隨機(jī)噪聲同時(shí)還需要盡量保留畫面里的細(xì)小目標(biāo)邊緣。這些需求聽起來和普通圖像去噪差不多但真正跑起來發(fā)現(xiàn)紅外圖像的水比想象中深得多。下面先花點(diǎn)篇幅把紅外噪聲的成因講清楚因?yàn)楹芏嗨惴ㄟx型的失誤根本不是算法本身不行而是對噪聲模型理解不到位。1. 紅外圖像為什么這么“臟”噪聲成因決定算法選型1.1 探測器響應(yīng)不一致帶來的固定圖案噪聲紅外圖像和可見光圖像最本質(zhì)的區(qū)別在于它的成像鏈路不是“光子打到傳感器——轉(zhuǎn)換電荷——讀出成圖”這么簡單而是紅外輻射先經(jīng)過光學(xué)系統(tǒng)再由焦平面陣列FPA上的探測器像元轉(zhuǎn)換成電信號。焦平面陣列上幾萬到幾百萬個(gè)像元每個(gè)像元的光電響應(yīng)特性都不可能完全一致這就導(dǎo)致面對均勻輻射場景時(shí)最終圖像上不同像元的灰度值各不相同。這種差異在原始圖像上就表現(xiàn)為固定圖案噪聲Fixed Pattern NoiseFPN。FPN最典型的一種表現(xiàn)是豎條紋——行方向一致、列方向不一致或者反過來。你可以把它理解成每個(gè)像元天生自帶一個(gè)“固定偏見”有些像元偏向讀出高一點(diǎn)有些偏向讀出低一點(diǎn)。因?yàn)檫@種偏置和增益在短時(shí)間內(nèi)基本不變所以叫“固定”圖案噪聲但它會(huì)不會(huì)隨溫度、曝光時(shí)間漂移呢會(huì)這就牽扯出另一個(gè)問題——兩點(diǎn)校正。1.2 兩點(diǎn)校正能解決什么不能解決什么紅外行業(yè)里最經(jīng)典的非均勻性校正方法就是兩點(diǎn)校正也叫兩點(diǎn)定標(biāo)校正。原理不復(fù)雜假設(shè)每個(gè)像元的響應(yīng)是線性的那么只需要用兩個(gè)不同溫度的均勻黑體輻射源做標(biāo)定測出每個(gè)像元在低溫端和高溫端的響應(yīng)就能求出每個(gè)像元的增益和偏置然后對每個(gè)像元做一個(gè)線性映射把整個(gè)陣列的響應(yīng)拉齊。公式長這樣y_ corrected (x - offset) / gain其中 gain 和 offset 分別由高溫端和低溫端響應(yīng)算出來gain (mean_high - mean_low) / (resp_high - resp_low) offset mean_low - gain * resp_low但兩點(diǎn)校正有個(gè)尷尬之處它假設(shè)響應(yīng)是線性且穩(wěn)定的。真實(shí)場景中探測器響應(yīng)會(huì)隨工作時(shí)間、內(nèi)部溫度、輻射強(qiáng)度變化而漂移所以定標(biāo)完一段時(shí)間后FPN又會(huì)慢慢顯形。這就意味著兩點(diǎn)校正只是預(yù)處理里的第一步后續(xù)去噪增強(qiáng)算法仍然有很大的發(fā)揮空間。1.3 隨機(jī)噪聲、壞元與條紋噪聲除了固定的非均勻性紅外圖像還有隨機(jī)噪聲成分暗電流噪聲即使沒有光照射像元內(nèi)部熱激發(fā)也會(huì)產(chǎn)生電信號曝光時(shí)間越長越明顯。讀出噪聲模擬信號轉(zhuǎn)數(shù)字信號過程中的電子噪聲和電路設(shè)計(jì)強(qiáng)相關(guān)。光子散粒噪聲到達(dá)焦平面的紅外光子數(shù)量本身有隨機(jī)漲落在低照度場景尤其明顯。壞元問題也躲不開。焦平面陣列出廠時(shí)就有一定比例的壞點(diǎn)有些像元永遠(yuǎn)輸出一個(gè)極大或極小值。如果壞元不處理后面所有基于卷積的去噪算法都會(huì)在壞元位置反復(fù)產(chǎn)生偽影。所以正規(guī)處理流程里壞元掩碼bad pixel mask通常和去噪算法是配合使用的。下面這張表可以幫你快速梳理紅外噪聲的類型和區(qū)別噪聲類型生成原因時(shí)域特性空域特性固定圖案噪聲FPN像元響應(yīng)不一致基本不變隨溫度緩慢漂移固定條紋或塊狀條紋噪聲列電路讀出差異恒定單列方向的豎條紋壞元工藝缺陷恒定異常擴(kuò)散成點(diǎn)狀偽影隨機(jī)噪聲暗電流、讀出、散粒時(shí)變近似高斯分布1/f噪聲電路低頻漂移隨時(shí)間緩慢變化低頻背景起伏正因?yàn)榧t外噪聲是多源疊加、且有很大一部分是結(jié)構(gòu)化的條紋、固定圖案所以通用可見光去噪算法直接搬過來往往效果不佳。這不是算法不行而是噪聲模型對不上。1.4 為什么普通去噪算法在紅外圖上經(jīng)常失效跑過自然圖像去噪的人應(yīng)該對高斯白噪聲假設(shè)很熟悉DnCNN、FFDNet這類模型訓(xùn)練時(shí)加的也是高斯噪聲。但真實(shí)紅外圖像里噪聲不是單純的高斯白噪聲它含有強(qiáng)烈的列方向相關(guān)性也就是條紋。你拿一個(gè)針對高斯噪聲訓(xùn)練好的CNN去處理紅外圖條紋根本去不干凈因?yàn)槟P蛪焊鶝]有學(xué)到“沿列方向的相關(guān)性”這種東西。另一個(gè)容易被忽略的點(diǎn)是紅外圖像的位深經(jīng)常是14bit或16bit而普通網(wǎng)絡(luò)訓(xùn)練時(shí)用的是8bit歸一化到[0,1]的圖像。直接讀入短整型數(shù)據(jù)再歸一化如果方式不對很容易把對比度壓到很小的范圍里模型什么都學(xué)不到。這些坑放到后面專門講這里先記住一句話認(rèn)清紅外圖像的噪聲特征比盲目堆模型重要得多。2. 去噪增強(qiáng)算法的兩條技術(shù)路線與選型邏輯2.1 傳統(tǒng)路線濾波、全變分、稀疏與低秩傳統(tǒng)紅外去噪增強(qiáng)算法路線其實(shí)挺多的但核心都圍繞一個(gè)思路對圖像做某種先驗(yàn)假設(shè)然后在先驗(yàn)約束下還原干凈圖像??臻g域?yàn)V波是最直接的中值濾波對孤立壞元和脈沖噪聲有效雙邊濾波能在去噪的同時(shí)保留邊緣但遇到大范圍條紋噪聲就無能為力。引導(dǎo)濾波的效果比雙邊濾波穩(wěn)定一些尤其是用原圖自身做引導(dǎo)時(shí)可以在保持邊緣的同時(shí)平滑平坦區(qū)域。不過這些局部濾波器的問題是它們沒有顯式建?!皸l紋噪聲沿列分布”這個(gè)特點(diǎn)。全變分TV模型是另一個(gè)經(jīng)典方向。TV模型的假設(shè)是干凈圖像的分片光滑piecewise smooth然后用圖像的梯度L1范數(shù)作為正則項(xiàng)來抑制噪聲。對于紅外條紋去除有一種改進(jìn)思路是在TV正則中加入列方向的梯度約束比如min_u ||u - f||_2^2 λ * (||?x u||_1 ||?y u||_1)其中?x和?y分別代表水平和垂直方向的梯度。因?yàn)闂l紋噪聲主要在列方向垂直條紋所以可以適當(dāng)加大水平方向梯度的懲罰權(quán)重。但TV模型有個(gè)副作用它容易把弱紋理也一并抹掉導(dǎo)致圖像變得“塑料感”很強(qiáng)這在紅外細(xì)節(jié)觀察場景下是不能接受的。稀疏表示和低秩矩陣方法在學(xué)術(shù)論文里很好看。低秩模型的核心思想是把紅外圖像按列或者按塊排列成矩陣干凈的背景部分是低秩的而條紋噪聲是稀疏的這樣就可以用魯棒主成分分析RPCA或低秩稀疏分解把條紋分離出來。這種方法在條紋噪聲固定、背景結(jié)構(gòu)簡單的場景下效果很驚艷但計(jì)算量大且對復(fù)雜的強(qiáng)紋理背景不太友好容易把紋理誤判成噪聲。BM3D算是傳統(tǒng)算法的巔峰之作它把相似塊聚合、協(xié)同濾波、維納濾波這些操作組合在一起在自然圖像去噪里統(tǒng)治了很多年。對紅外圖像BM3D表現(xiàn)也不錯(cuò)但因?yàn)樗€是基于“噪聲是高斯分布的”這一假設(shè)處理?xiàng)l紋類結(jié)構(gòu)噪聲時(shí)依然力不從心好一點(diǎn)的策略是先用列均值補(bǔ)償或去條帶預(yù)處理再用BM3D。2.2 深度路線CNN、Transformer與自監(jiān)督深度學(xué)習(xí)路線基本已經(jīng)是當(dāng)前紅外去噪增強(qiáng)的主流了。DnCNN是最樸素的起點(diǎn)它用殘差學(xué)習(xí)的方式讓網(wǎng)絡(luò)去預(yù)測噪聲而不是直接輸出干凈圖像這個(gè)思路在紅外圖像的隨機(jī)噪聲部分很有效。FFDNet在DnCNN基礎(chǔ)上加了噪聲水平參數(shù)作為輸入相當(dāng)于讓網(wǎng)絡(luò)知道當(dāng)前噪聲大概有多大處理非均勻噪聲時(shí)更靈活。專門針對紅外條紋噪聲的工作也不少。常見做法是在網(wǎng)絡(luò)結(jié)構(gòu)里加入列方向注意機(jī)制或者直接用一個(gè)輔助分支去預(yù)測條紋分量。比如有的模型把輸入圖像分成“背景部分”和“條紋部分”兩條分支讓它學(xué)習(xí)一個(gè)可加分離有的用空洞卷積擴(kuò)大感受野因?yàn)闂l紋往往是跨越整個(gè)列方向的大尺度結(jié)構(gòu)感受野小了根本捕捉不到。Transformer結(jié)構(gòu)近兩年也進(jìn)入了紅外圖像領(lǐng)域。因?yàn)門ransformer的全局注意力機(jī)制天然適合捕捉長距離依賴而條紋噪聲恰恰具有全局列相關(guān)性。但Transformer的問題是計(jì)算量大顯存占用高在紅外監(jiān)控這種實(shí)時(shí)性要求高的場景里落地比較困難。還有一個(gè)很現(xiàn)實(shí)的問題深度學(xué)習(xí)方法需要大量成對的“干凈圖—帶噪圖”訓(xùn)練數(shù)據(jù)。紅外圖標(biāo)注成本高干凈參考圖很難獲取。所以自監(jiān)督和半監(jiān)督方法開始受到重視。比如用噪聲圖自身來構(gòu)造監(jiān)督信號利用噪聲的空間獨(dú)立性讓網(wǎng)絡(luò)隱式學(xué)會(huì)去噪。這類方法在真實(shí)紅外數(shù)據(jù)上有潛力但現(xiàn)階段效果還是不如有監(jiān)督方法穩(wěn)定。2.3 面對一個(gè)真實(shí)項(xiàng)目怎么選路線選路線本質(zhì)上是在“效果”“速度”“數(shù)據(jù)量”“算力”四個(gè)維度里做權(quán)衡。如果手頭是實(shí)時(shí)性要求高的嵌入式平臺且只需要應(yīng)付固定場景我的建議是先做兩點(diǎn)校正壞元替換空間域?yàn)V波的經(jīng)典組合跑通流程、滿足幀率需求再考慮是否引入深度學(xué)習(xí)。如果是要追求極致畫質(zhì)且離線處理那就直接上深度學(xué)習(xí)方法優(yōu)先選擇針對紅外噪聲做過專門設(shè)計(jì)的模型而不是拿自然圖像模型硬套。如果數(shù)據(jù)量很小或者根本沒有成對數(shù)據(jù)那傳統(tǒng)算法仍然是最穩(wěn)妥的起點(diǎn)尤其是條紋噪聲嚴(yán)重的場景低秩分解和TV類方法很能打。下面這張表是我個(gè)人經(jīng)驗(yàn)里的選型參考場景首選方案備選方案理由嵌入式實(shí)時(shí)處理兩點(diǎn)校正壞元替換雙邊/引導(dǎo)濾波簡化版CNN模型量化算力有限傳統(tǒng)方案穩(wěn)定離線高畫質(zhì)、有GPU專門針對紅外的CNN/Transformer去噪BM3D去條帶預(yù)處理效果上限更高條紋噪聲嚴(yán)重低秩稀疏分解/去條帶模型帶列注意力的CNN條紋是結(jié)構(gòu)化噪聲需專門建模無成對數(shù)據(jù)自監(jiān)督去噪/盲去噪TV稀疏表示無法訓(xùn)練有監(jiān)督模型通用快速驗(yàn)證FFDNet或DnCNN直接試BM3D代碼現(xiàn)成快出基線這個(gè)表不是絕對標(biāo)準(zhǔn)但它能幫你少走很多彎路。我見過太多人一上來就想用最好的Transformer模型結(jié)果數(shù)據(jù)、算力都跟不上反而被一個(gè)FFDNet的baseline打趴。3. 論文合集怎么讀從“堆材料”到“跑通方案”的轉(zhuǎn)化3.1 先給論文分個(gè)類你下載的論文合集里可能混著各種方向的文獻(xiàn)不要從頭到尾按順序讀先分類。我拿到合集之后會(huì)先把論文分成四類基礎(chǔ)理論類講紅外成像原理、噪聲來源、非均勻性校正理論的這類是要打的底子。傳統(tǒng)算法類TV、稀疏、低秩、BM3D、去條帶模型的用來理解經(jīng)典思路。深度學(xué)習(xí)方法類DnCNN、FFDNet、Transformer去噪、自監(jiān)督去噪的這是主要復(fù)現(xiàn)對象。評估與分析類講評價(jià)指標(biāo)、測試數(shù)據(jù)集、對比實(shí)驗(yàn)的用來確定驗(yàn)收標(biāo)準(zhǔn)。分類之后按“先理論再經(jīng)典再深度最后評估”的順序讀。不要一上來就死磕Transformer的數(shù)學(xué)公式先建立整體認(rèn)知再逐個(gè)擊破。3.2 一篇論文要從哪里開始看我讀論文的經(jīng)驗(yàn)是標(biāo)題和摘要只用來判斷相關(guān)性真正決定要不要花時(shí)間細(xì)讀的是“方法框架圖”和“損失函數(shù)”。方法框架圖能讓你一眼看出輸入是什么、中間經(jīng)過幾個(gè)分支、輸出是什么——這比看公式快得多。如果框架圖里只有輸入輸出但是中間結(jié)構(gòu)復(fù)雜那這篇論文大概率改的是網(wǎng)絡(luò)骨架如果框架圖和普通圖像去噪網(wǎng)絡(luò)沒區(qū)別但損失函數(shù)里多了一項(xiàng)“條紋損失”或“梯度損失”那它大概率改的是訓(xùn)練目標(biāo)而不是結(jié)構(gòu)。這兩個(gè)方向一個(gè)對應(yīng)復(fù)現(xiàn)成本高一個(gè)對應(yīng)復(fù)現(xiàn)成本低??磽p失函數(shù)時(shí)要把每一項(xiàng)在紙上寫出來拆解成代碼里對應(yīng)的tensor運(yùn)算。比如總損失L L_rec λ * L_stripe你就要理解L_stripe是在什么特征上算的是用原圖減掉平滑圖得到的條紋分量還是網(wǎng)絡(luò)中間層的輸出。3.3 代碼復(fù)現(xiàn)的第一步不是訓(xùn)練是跑通推理拿到一個(gè)開源代碼我的步驟永遠(yuǎn)是搭建環(huán)境安裝依賴把README里的requirements裝齊。找一個(gè)已經(jīng)訓(xùn)練好的權(quán)重文件跑測試腳本復(fù)現(xiàn)論文里的結(jié)果。觀察輸入輸出格式確認(rèn)圖像是否需要?dú)w一化、是否需要轉(zhuǎn)成YCbCr色彩空間。用自己的一張紅外圖替代測試圖看輸出是否正常。跑通了推理才開始研究訓(xùn)練腳本。這一步看似簡單但特別重要。因?yàn)楹芏嗾撐淖髡甙l(fā)布的代碼是“能跑通就行”的版本環(huán)境配置非常隨緣PyTorch版本、CUDA版本都可能存在兼容問題。先跑通推理至少能驗(yàn)證代碼本身是否能正常工作也能觀察到模型的實(shí)際輸出形態(tài)。3.4 訓(xùn)練腳本里的關(guān)鍵參數(shù)怎么調(diào)訓(xùn)練腳本里常見的參數(shù)無外乎這些batch_sizelearning_ratenum_epochspatch_size優(yōu)化器Adam還是SGD學(xué)習(xí)率調(diào)度策略數(shù)據(jù)路徑在這些參數(shù)里patch_size對紅外圖像尤其重要。因?yàn)榧t外噪聲特別是條紋具有全局長程相關(guān)性patch尺寸如果太小比如只有32×32網(wǎng)絡(luò)可能根本看不到完整的條紋結(jié)構(gòu)。個(gè)人經(jīng)驗(yàn)是紅外去噪任務(wù)的patch_size最好在128以上甚至256。代價(jià)是顯存占用直線上升這時(shí)batch_size就要相應(yīng)調(diào)小。學(xué)習(xí)率我個(gè)人建議Adam起步時(shí)設(shè)為1e-4到3e-4這個(gè)范圍然后配合CosineAnnealing或StepLR做衰減。純用固定學(xué)習(xí)率訓(xùn)練后期loss容易震蕩導(dǎo)致輸出圖像出現(xiàn)周期性亮暗變化。這些參數(shù)論文里基本都會(huì)寫但真正跑的時(shí)候還得根據(jù)顯存、數(shù)據(jù)類型、任務(wù)難易程度做二次調(diào)整。我自己踩過最大的坑是把可見光去噪論文里的patch size直接照搬到紅外場景結(jié)果條紋根本去不干凈后來才發(fā)現(xiàn)是感受野不夠和網(wǎng)絡(luò)無關(guān)。4. 數(shù)據(jù)準(zhǔn)備與訓(xùn)練細(xì)節(jié)紅外圖像專屬的“隱形門檻”4.1 單通道數(shù)據(jù)必須處理到位紅外圖像絕大多數(shù)是單通道灰度圖但很多開源代碼默認(rèn)是處理三通道RGB的。直接拿灰度圖喂進(jìn)三通道模型要么報(bào)錯(cuò)要么需要把灰度圖復(fù)制成三通道再輸入。復(fù)制的做法雖然能跑通但會(huì)浪費(fèi)約2/3的計(jì)算量而且網(wǎng)絡(luò)會(huì)把三個(gè)通道的關(guān)系當(dāng)成有效特征去學(xué)習(xí)實(shí)在是不劃算。更合理的做法是修改網(wǎng)絡(luò)第一層的輸入通道數(shù)為1原來Conv2d(3, 64, kernel_size3)改成Conv2d(1, 64, kernel_size3)。如果代碼用的是預(yù)訓(xùn)練權(quán)重改通道數(shù)后第一層權(quán)重?zé)o法加載需要其他層加載預(yù)訓(xùn)練權(quán)重、第一層重新初始化。4.2 位深和歸一化一個(gè)被瘋狂忽略的坑紅外圖像常見位深有8bit、14bit、16bit但很多模型的訓(xùn)練數(shù)據(jù)集是8bit自然圖像。如果你直接把16bit原始數(shù)據(jù)除以255得到的數(shù)據(jù)范圍是0到257而不是0到1模型會(huì)認(rèn)為輸入分布完全不一樣訓(xùn)練極難收斂。正確的做法是把訓(xùn)練數(shù)據(jù)統(tǒng)一處理到目標(biāo)位深范圍。要么在數(shù)據(jù)加載時(shí)把單張圖的動(dòng)態(tài)范圍拉伸到[0,1]要么把所有訓(xùn)練數(shù)據(jù)統(tǒng)一裁剪到某個(gè)百分比截?cái)喾秶?。我自己常用的做法是先統(tǒng)計(jì)整個(gè)數(shù)據(jù)集灰度的0.5%和99.5%分位數(shù)做線性拉伸后再歸一化。這能最大程度避免個(gè)別極端亮像素比如高溫?zé)嵩窗颜麖垐D的動(dòng)態(tài)范圍壓扁。如果源數(shù)據(jù)本身是8bit那直接除以255即可如果是14bit就除以16383如果是16bit就除以65535。這里要注意的是有些數(shù)據(jù)集的中值會(huì)偏移比如12bit有效數(shù)據(jù)存在16bit容器里這時(shí)直接除以65535會(huì)讓圖像偏暗正確的做法是除以4095。4.3 合成噪聲數(shù)據(jù)怎么造才貼近真實(shí)如果沒有成對數(shù)據(jù)最常見的做法是先用干凈的紅外圖疊加模擬噪聲。模擬噪聲不能只加高斯白噪聲要盡可能還原紅外噪聲的構(gòu)成。我的合成策略通常是生成一個(gè)穩(wěn)定的列方向條紋分量幅值隨機(jī)但每條列獨(dú)立。疊加一個(gè)高斯隨機(jī)噪聲標(biāo)準(zhǔn)差取圖像全局標(biāo)準(zhǔn)差的0.01到0.05。隨機(jī)播撒壞元比例控制在0.01%到0.1%之間。模擬探測器響應(yīng)不均勻給每個(gè)像素乘一個(gè)接近1的隨機(jī)增益系數(shù)。這里有個(gè)細(xì)節(jié)條紋噪聲不一定都是完全豎向的因?yàn)橄鄼C(jī)震動(dòng)或電路行讀出延時(shí)可能出現(xiàn)輕微傾斜。合成數(shù)據(jù)時(shí)也可以對條紋做小幅度的旋轉(zhuǎn)或偏移增加模型對真實(shí)場景的魯棒性。4.4 數(shù)據(jù)增強(qiáng)與訓(xùn)練策略訓(xùn)練紅外去噪模型數(shù)據(jù)增強(qiáng)依然是有效的但要注意不能破壞噪聲的結(jié)構(gòu)。常見的旋轉(zhuǎn)、翻轉(zhuǎn)、隨機(jī)裁剪都可以用但如果你處理的是條紋噪聲翻轉(zhuǎn)時(shí)條紋方向會(huì)改變水平翻轉(zhuǎn)后豎條紋還是會(huì)保持一致方向因?yàn)樗椒D(zhuǎn)只在水平方向鏡像豎條紋仍然是豎條紋這個(gè)沒問題但旋轉(zhuǎn)90度會(huì)把豎條紋變成橫條紋這在真實(shí)場景里幾乎不會(huì)出現(xiàn)。所以如果你想保持對條紋方向建模的一致性旋轉(zhuǎn)增強(qiáng)最好只用0度和180度。90度和270度會(huì)引入“橫向條紋”這個(gè)分布外數(shù)據(jù)訓(xùn)練時(shí)反而會(huì)困惑模型。另外我自己訓(xùn)練時(shí)會(huì)采用“先小patch粗訓(xùn)、后大patch精訓(xùn)”的兩階段策略。第一階段用64×64的patch快速迭代先讓網(wǎng)絡(luò)學(xué)到基本去噪能力第二階段換到128或192尺寸繼續(xù)訓(xùn)練讓網(wǎng)絡(luò)適配更大感受野下的條紋結(jié)構(gòu)。這樣做比直接訓(xùn)練大patch更快收斂顯存壓力也小很多。5. 效果評估必須同時(shí)看兩個(gè)維度指標(biāo)和眼睛5.1 PSNR和SSIM為什么會(huì)騙人幾乎所有人拿到代碼的第一件事就是算PSNR和SSIM這兩個(gè)指標(biāo)也確實(shí)是最通用的。但紅外圖像去噪增強(qiáng)場景里它們的局限性很明顯。PSNR是基于逐像素誤差的指標(biāo)它對“整體噪聲水平降低”很敏感但對“邊緣是否清晰”“紋理是否真實(shí)”并不敏感。一個(gè)輕微的模糊處理反而可能因?yàn)槠交嗽肼暥嵘齈SNR但圖像細(xì)節(jié)就沒了。對紅外圖像應(yīng)用來說如果目標(biāo)是觀察人物輪廓、檢測小目標(biāo)那PSNR偏高但邊緣糊掉的模型實(shí)際價(jià)值很低。SSIM考慮了亮度、對比度和結(jié)構(gòu)三個(gè)維度比PSNR更人性化一些但對結(jié)構(gòu)噪聲條紋也不夠敏感。因?yàn)镾SIM是在局部窗口內(nèi)比較結(jié)構(gòu)信息而條紋是貫穿全圖的全局結(jié)構(gòu)逐窗口計(jì)算時(shí)條紋對每個(gè)窗口的貢獻(xiàn)都微乎其微最后匯總出來的SSIM可能依然很高但視覺上條紋依然明顯。所以只用PSNR和SSIM做評判很容易得出“某個(gè)模型效果不錯(cuò)”的錯(cuò)誤結(jié)論。我見過一個(gè)模型在去噪測試集上PSNR比baseline高1.5dB但實(shí)際看圖時(shí)條紋反而更明顯了只是隨機(jī)噪聲減少了——這就是指標(biāo)誤導(dǎo)人的典型案例。5.2 紅外圖像需要額外關(guān)注的評價(jià)維度除了PSNR和SSIM我建議至少補(bǔ)三個(gè)維度一是邊緣保持度??梢杂肅anny算子或Sobel算子提取去噪前后的邊緣圖看邊緣響應(yīng)的強(qiáng)度和連續(xù)性是否得到保留。也可以在圖像里手動(dòng)選一條明顯的目標(biāo)輪廓橫截面比較原始圖像、噪聲圖像、去噪圖像在該截面上的灰度曲線觀察邊緣是變陡峭了還是變平緩了。二是條紋抑制程度。最直觀的辦法是取一張方差很小的均勻區(qū)域計(jì)算去噪后的圖像在該區(qū)域的列均值曲線。如果列均值波動(dòng)很大說明條紋還殘留著。定量一點(diǎn)可以計(jì)算列均值曲線的標(biāo)準(zhǔn)差去噪前后對比一下就知道條紋被壓下去多少。三是目標(biāo)可檢測性。如果去噪是為了后續(xù)做目標(biāo)檢測或跟蹤那應(yīng)該把去噪模塊接在檢測流程里做一個(gè)端到端的A/B測試。比如在同一個(gè)紅外視頻序列上跑檢測算法統(tǒng)計(jì)檢測率、虛警率、平均檢測置信度這些指標(biāo)遠(yuǎn)比單純PSNR更能說明問題。下面是我常用的一個(gè)評估表模板評估項(xiàng)具體方法好結(jié)果表現(xiàn)整體噪聲水平PSNR、噪聲標(biāo)準(zhǔn)差數(shù)值高噪聲標(biāo)準(zhǔn)差低結(jié)構(gòu)保持SSIM、邊緣強(qiáng)度邊緣清晰無偽影條紋殘留均勻區(qū)域列均值曲線曲線平滑無周期波動(dòng)模糊程度拉普拉斯響應(yīng)方差數(shù)值不顯著下降目標(biāo)可檢測性接檢測模型A/B測試檢測率提升虛警率不增5.3 主觀評價(jià)不是玄學(xué)要有對照流程主觀視覺評價(jià)雖然聽著主觀但要做得規(guī)范也是有方法的。我個(gè)人的做法是取5到10組典型紅外場景每組都包括“低對比度場景”“高溫目標(biāo)場景”“強(qiáng)條紋場景”“低噪聲場景”然后按統(tǒng)一縮放比例拉出一組去噪前后的對比圖放成同一窗口尺寸重點(diǎn)觀察四個(gè)區(qū)域細(xì)節(jié)邊緣、均勻背景、高溫目標(biāo)和天空背景。評價(jià)時(shí)不需要讓算法作者自己看找兩三個(gè)同事盲評順序打亂每一組里隨機(jī)顯示原圖和不同算法的輸出讓評價(jià)者挑出“最舒服的圖”和“細(xì)節(jié)最多的圖”。最后統(tǒng)計(jì)被選次數(shù)。這個(gè)方法雖然簡陋但比一個(gè)人盯著PSNR看有說服力得多。6. 實(shí)測踩過的坑論文和代碼都不會(huì)告訴你的經(jīng)驗(yàn)6.1 兩點(diǎn)校正后的殘余條紋比不校正還難處理這是我最早掉進(jìn)去的坑。原始紅外圖直接做深度學(xué)習(xí)去噪效果還不錯(cuò)但做了兩點(diǎn)校正之后再輸入模型反而出現(xiàn)了一些奇怪的帶狀偽影。分析后發(fā)現(xiàn)兩點(diǎn)校正會(huì)在圖像里留下一種“修正過度的邊緣”因?yàn)槊總€(gè)像元的增益和偏置是獨(dú)立估計(jì)的相鄰像元校正后可能出現(xiàn)不連續(xù)的跳變。這類殘余條紋和原始噪聲分布不一樣也不是簡單的高斯噪聲模型看到這種輸入時(shí)容易把校正痕跡當(dāng)成圖像內(nèi)容去保留導(dǎo)致出現(xiàn)“偽邊緣”。后來我的做法是在仿真訓(xùn)練數(shù)據(jù)里同時(shí)加入“兩點(diǎn)校正后的殘余條紋”作為一種噪聲類型讓模型見過這種情況效果改善非常明顯。6.2 壞元沒替換訓(xùn)練數(shù)據(jù)被帶歪如果把帶有大量壞元的圖像直接輸入網(wǎng)絡(luò)訓(xùn)練網(wǎng)絡(luò)會(huì)傾向于把壞元位置的異常值當(dāng)成真實(shí)細(xì)節(jié)去學(xué)習(xí)導(dǎo)致生成階段在壞元位置出現(xiàn)亮點(diǎn)或暗點(diǎn)。解決方案很簡單但很多人會(huì)忽略訓(xùn)練前先做壞元掩碼檢測把壞元位置的像素用周圍像素中值替換再把壞元掩碼記錄下來作為輔助信息。推理階段也要處理壞元否則訓(xùn)練時(shí)處理的輸入分布和部署時(shí)不一致模型性能會(huì)跳水。一個(gè)比較快的壞元檢測方法是對同一場景采集多幀圖像計(jì)算每幀的均值圖然后看每個(gè)像素在時(shí)域上的標(biāo)準(zhǔn)差。正常像元的時(shí)域標(biāo)準(zhǔn)差應(yīng)該服從一個(gè)集中分布壞元?jiǎng)t表現(xiàn)出明顯的離群值。跑一個(gè)簡單的置信區(qū)間判斷就能把壞元揪出來。6.3 訓(xùn)練loss不降反而圖像越來越模糊這是深度去噪模型很常見的“偽收斂”現(xiàn)象loss在下降但視覺上圖像越來越模糊。原因通常是訓(xùn)練目標(biāo)里過度強(qiáng)調(diào)了像素級重建損失網(wǎng)絡(luò)選擇了“求穩(wěn)”策略即把每個(gè)位置的像素盡可能拉向局部均值這樣能顯著降低均方誤差但圖像細(xì)節(jié)也被抹平了。解決方法是給損失函數(shù)加上感知損失或結(jié)構(gòu)相似性損失。比如L L_pixel λ * (1 - SSIM(clean, output))或者加一個(gè)梯度損失讓網(wǎng)絡(luò)在邊緣位置的梯度響應(yīng)和干凈圖盡量一致L_grad L1(?output, ?clean)加了這個(gè)約束之后模型會(huì)在“抹平細(xì)節(jié)”和“保留梯度”之間找一個(gè)平衡點(diǎn)輸出圖像明顯更銳利。λ的設(shè)置需要根據(jù)噪聲水平調(diào)整噪聲大時(shí)λ可以小一點(diǎn)噪聲小時(shí)λ可以大一點(diǎn)。我一般先在0.1到0.3之間試。6.4 推理時(shí)間比你想象的長問題往往出現(xiàn)在歸一化把網(wǎng)絡(luò)部署到實(shí)際流程里時(shí)經(jīng)常遇到“離線測試速度很快聯(lián)調(diào)時(shí)特別慢”的情況。查來查去結(jié)果不是網(wǎng)絡(luò)變慢了而是數(shù)據(jù)預(yù)處理里的歸一化操作沒有向量化用的是逐像素循環(huán)拖慢了整體速度。正常的做法應(yīng)該是利用numpy或PyTorch的廣播機(jī)制一次性完成。比如# 錯(cuò)誤的做法逐像素循環(huán)歸一化 for i in range(h): for j in range(w): image[i, j] (image[i, j] - min_val) / (max_val - min_val) # 正確的做法利用矩陣廣播 image (image - min_val) / (max_val - min_val)這種小問題在實(shí)際部署中非常常見但因?yàn)閳?bào)錯(cuò)不明顯排查起來特別浪費(fèi)時(shí)間。另一個(gè)類似的問題是把圖像從GPU顯存拷貝到CPU內(nèi)存的操作也會(huì)吃掉大量延遲能留在GPU上的盡量別搬回來。6.5 模型輸出出現(xiàn)網(wǎng)格偽影用基于卷積的模型處理紅外圖像時(shí)偶爾會(huì)在輸出圖上看到規(guī)則的網(wǎng)格狀偽影尤其是16bit圖像縮放到8bit顯示時(shí)更明顯。這個(gè)問題的根源通常是反卷積層的棋盤效應(yīng)或者是數(shù)據(jù)增強(qiáng)里的隨機(jī)裁剪步長和卷積極步長重疊導(dǎo)致的。處理方案一般有三種第一種是把反卷積層替換成亞像素卷積PixelShuffle第二種是給棋盤偽影的頻率區(qū)間做一個(gè)頻域懲罰第三種是在網(wǎng)絡(luò)輸出后加一個(gè)小的高斯低通濾波。哪個(gè)方案最有效取決于偽影的嚴(yán)重程度但最穩(wěn)定的還是從網(wǎng)絡(luò)結(jié)構(gòu)上解決——用PixelShuffle替代轉(zhuǎn)置卷積基本能消除這類問題。6.6 訓(xùn)練和部署環(huán)境不一致導(dǎo)致結(jié)果漂移還有一個(gè)很容易被忽略的問題訓(xùn)練時(shí)模型處理的是歸一化到[0,1]的數(shù)據(jù)部署時(shí)把輸入圖像用不同的方式歸一化模型輸出自然對不上。紅外設(shè)備的SDK往往直接輸出原始數(shù)據(jù)位深也不固定如果不在前端做統(tǒng)一的歸一化處理模型換一個(gè)相機(jī)就失靈。我的建議是把數(shù)據(jù)預(yù)處理寫成一個(gè)獨(dú)立模塊固定成唯一入口訓(xùn)練、驗(yàn)證、部署都走同一個(gè)函數(shù)輸入輸出格式徹底統(tǒng)一。不要在每個(gè)腳本里各寫一套預(yù)處理邏輯否則后期排查起來非常酸爽。7. 一點(diǎn)個(gè)人體會(huì)把注意力放在數(shù)據(jù)集和評價(jià)環(huán)節(jié)如果讓我給剛接觸紅外圖像去噪增強(qiáng)的朋友一個(gè)最真誠的建議那就是不要在算法上卷太早先把數(shù)據(jù)集和評價(jià)環(huán)節(jié)做扎實(shí)。跑通一個(gè)開源模型不難難的是想清楚“我的真實(shí)場景里噪聲長什么樣我的目標(biāo)到底是什么”然后圍繞目標(biāo)設(shè)計(jì)數(shù)據(jù)、選擇模型、制定指標(biāo)。我個(gè)人的體會(huì)是一次高質(zhì)量的紅外去噪項(xiàng)目推進(jìn)大約三分之一的時(shí)間花在數(shù)據(jù)清洗和噪聲建模上三分之一花在效果評估和業(yè)務(wù)驗(yàn)證上真正拿來調(diào)模型結(jié)構(gòu)的時(shí)間反而不到三分之一。一開始我也覺得這個(gè)比例不合理后來發(fā)現(xiàn)當(dāng)數(shù)據(jù)分布接近真實(shí)、評估標(biāo)準(zhǔn)足夠客觀時(shí)模型調(diào)優(yōu)的邊界會(huì)變得非常清晰很多“玄學(xué)”問題都會(huì)變成確定性問題。另一個(gè)建議是多保留幾組“金標(biāo)準(zhǔn)”圖每組圖都覆蓋不同的典型場景和噪聲程度每次改進(jìn)算法都拿同一組圖去跑對比而不是零散地看幾張。長期積累下來這套圖集就是你的私有benchmark比任何公開數(shù)據(jù)集都更貼合你的業(yè)務(wù)。最后關(guān)于紅外圖像去噪增強(qiáng)算法論文和代碼合集這個(gè)資源我強(qiáng)烈建議你把它當(dāng)成一個(gè)起點(diǎn)而不是答案。論文里的方法值得復(fù)現(xiàn)代碼里的結(jié)構(gòu)值得跑通但是最后落到你具體業(yè)務(wù)里的一定是一個(gè)經(jīng)過了數(shù)據(jù)適配、評估驗(yàn)證和工程優(yōu)化的定制方案。把別人的代碼跑起來只是第一步能讓它在真實(shí)紅外場景里穩(wěn)定輸出有效圖像才算真正把這件事做透了。本文還有配套的精品資源點(diǎn)擊獲取