字圖像縮放插值算法實(shí)現(xiàn)與性能對(duì)比)
簡介這是一份面向電子信息工程、計(jì)算機(jī)視覺等專業(yè)本科生的數(shù)字圖像處理畢業(yè)論文資料以數(shù)字圖像縮放技術(shù)為核心研究課題適合正在準(zhǔn)備畢業(yè)設(shè)計(jì)或需要了解圖像插值算法實(shí)現(xiàn)的學(xué)習(xí)者參考。壓縮包內(nèi)僅含1個(gè)doc文檔約2.05MB完整收錄了畢業(yè)設(shè)計(jì)任務(wù)書、論文目錄、摘要及各章節(jié)正文涵蓋數(shù)字電視視頻格式、數(shù)學(xué)插值理論、MATLAB仿真環(huán)境應(yīng)用等內(nèi)容。論文重點(diǎn)研究了最近鄰域插值、雙線性插值、雙三次插值等經(jīng)典算法并通過MATLAB編程實(shí)現(xiàn)圖像縮放實(shí)驗(yàn)對(duì)比分析了各算法的性能與運(yùn)算量讀者可從中獲取完整的論文框架、算法實(shí)現(xiàn)思路與實(shí)驗(yàn)對(duì)比方法。目前已有907人學(xué)習(xí)下載對(duì)于需要撰寫圖像處理方向畢業(yè)論文或?qū)W習(xí)MATLAB圖像縮放編程的讀者具有較高的參考價(jià)值。1. 從一份本科畢設(shè)看圖像縮放為什么插值算法是數(shù)字電視的隱形地基很多人第一次接觸數(shù)字圖像處理都是從一份本科畢業(yè)設(shè)計(jì)開始的。這份題為“數(shù)字圖像縮放技術(shù)研究”的論文專業(yè)是電子信息工程完成時(shí)間在 2006 年前后正文完整覆蓋了從數(shù)字電視視頻格式、數(shù)學(xué)插值理論、MATLAB 編程實(shí)現(xiàn)到傳統(tǒng)與改進(jìn)縮放算法性能對(duì)比的全過程。它解決的核心問題很具體不同分辨率的視頻信號(hào)如何在終端設(shè)備上統(tǒng)一顯示。手機(jī)、液晶電視、等離子屏的固有分辨率各不相同信號(hào)源卻可能是 1080i、720P 或 1080P中間必須經(jīng)過分辨率變換。適合誰看正在做圖像處理方向畢設(shè)的本科生、剛?cè)胄凶鲲@示或視頻算法的工程師以及想用 MATLAB 快速驗(yàn)證插值算法效果的人。這份論文不是空泛的綜述它有算法推導(dǎo)、有代碼實(shí)現(xiàn)、有實(shí)驗(yàn)對(duì)比能直接拿來當(dāng)復(fù)現(xiàn)模板。2. 三種經(jīng)典插值算法的 MATLAB 實(shí)現(xiàn)從最近鄰到雙三次2.1 最近鄰插值最快但最容易出鋸齒最近鄰插值的邏輯最簡單目標(biāo)像素的灰度值直接取源圖像中距離最近的像素值。數(shù)學(xué)上就是四舍五入取整沒有權(quán)重計(jì)算。在 MATLAB 里可以用imresize的nearest參數(shù)直接調(diào)用但畢設(shè)要求自己編寫程序?qū)崿F(xiàn)所以需要手動(dòng)計(jì)算坐標(biāo)映射。% 最近鄰插值實(shí)現(xiàn) function output nearest_interp(input, scale) [h, w] size(input); new_h round(h * scale); new_w round(w * scale); output zeros(new_h, new_w, like, input); for i 1:new_h for j 1:new_w % 計(jì)算源圖像中的對(duì)應(yīng)坐標(biāo) src_i round(i / scale); src_j round(j / scale); % 邊界保護(hù) src_i min(max(src_i, 1), h); src_j min(max(src_j, 1), w); output(i, j) input(src_i, src_j); end end end這段代碼的核心在round(i / scale)這一行。scale是縮放倍數(shù)大于 1 是放大小于 1 是縮小。round決定了取哪個(gè)最近像素。邊界保護(hù)用min(max(...))防止索引越界這是新手最容易翻車的地方——放大時(shí)最后一個(gè)像素的坐標(biāo)可能超出源圖尺寸。最近鄰的優(yōu)點(diǎn)是運(yùn)算量極小每個(gè)目標(biāo)像素只做一次除法和一次取整缺點(diǎn)是放大后邊緣鋸齒明顯縮小后容易丟失細(xì)節(jié)。在數(shù)字電視里它一般只用于對(duì)實(shí)時(shí)性要求極高、對(duì)畫質(zhì)要求不高的場景。2.2 雙線性插值用四個(gè)鄰居做加權(quán)平均雙線性插值在水平和垂直兩個(gè)方向上分別做線性插值目標(biāo)像素的值由源圖像中相鄰的四個(gè)像素加權(quán)得到。權(quán)重取決于目標(biāo)點(diǎn)與四個(gè)鄰居的距離。這個(gè)算法在 MATLAB 里同樣可以手動(dòng)實(shí)現(xiàn)核心是計(jì)算浮點(diǎn)坐標(biāo)后取上下左右四個(gè)整數(shù)坐標(biāo)。% 雙線性插值實(shí)現(xiàn) function output bilinear_interp(input, scale) [h, w] size(input); new_h round(h * scale); new_w round(w * scale); output zeros(new_h, new_w, like, input); for i 1:new_h for j 1:new_w % 浮點(diǎn)坐標(biāo) src_i i / scale; src_j j / scale; % 四個(gè)鄰居的整數(shù)坐標(biāo) i1 floor(src_i); i2 min(i1 1, h); j1 floor(src_j); j2 min(j1 1, w); i1 max(i1, 1); j1 max(j1, 1); % 距離權(quán)重 di src_i - i1; dj src_j - j1; % 雙線性加權(quán) output(i, j) (1-di)*(1-dj)*input(i1, j1) ... (1-di)*dj*input(i1, j2) ... di*(1-dj)*input(i2, j1) ... di*dj*input(i2, j2); end end end參數(shù)說明di和dj是目標(biāo)點(diǎn)在源圖網(wǎng)格中的小數(shù)部分范圍在 0 到 1 之間。四個(gè)權(quán)重系數(shù)之和恒為 1保證亮度不偏移。雙線性插值比最近鄰平滑很多但會(huì)引入輕微的模糊因?yàn)楸举|(zhì)上它是一個(gè)低通濾波器。運(yùn)算量大約是最近鄰的 4 倍左右每像素需要 4 次乘法和若干次加減。在 2006 年的硬件條件下這個(gè)運(yùn)算量對(duì)實(shí)時(shí)視頻縮放已經(jīng)有壓力了所以論文里專門做了運(yùn)算量對(duì)比。2.3 雙三次插值16 個(gè)鄰居加三次核函數(shù)雙三次插值用源圖像中 4×4 鄰域的 16 個(gè)像素做加權(quán)權(quán)重由三次多項(xiàng)式核函數(shù)決定。MATLAB 的imresize默認(rèn)就是雙三次但畢設(shè)要求自己寫。核心是構(gòu)造三次卷積核常用的核函數(shù)是% 雙三次插值核函數(shù)Keys 核a -0.5 function w cubic_kernel(x, a) x abs(x); if x 1 w (a2)*x^3 - (a3)*x^2 1; elseif x 2 w a*x^3 - 5*a*x^2 8*a*x - 4*a; else w 0; end end然后在行列兩個(gè)方向分別做一維三次卷積。完整實(shí)現(xiàn)需要四層循環(huán)運(yùn)算量是雙線性的 4 倍以上。優(yōu)點(diǎn)是邊緣保持更好放大后細(xì)節(jié)更銳利缺點(diǎn)是計(jì)算量大且核函數(shù)參數(shù)a的選擇會(huì)影響銳度和振鈴效應(yīng)。論文里對(duì)這三種算法的插值核函數(shù)做了數(shù)學(xué)形態(tài)分析指出計(jì)算量差異主要來自參與加權(quán)的像素?cái)?shù)量和核函數(shù)階數(shù)。提示手動(dòng)實(shí)現(xiàn)時(shí)注意圖像類型。如果是uint8加權(quán)計(jì)算前要轉(zhuǎn)成double算完再轉(zhuǎn)回去否則會(huì)因整數(shù)截?cái)喈a(chǎn)生嚴(yán)重誤差。3. 四種改進(jìn)縮放算法的實(shí)現(xiàn)思路與性能對(duì)比3.1 近鄰插值與鄰域取平均結(jié)合的縮小算法傳統(tǒng)插值在縮小圖像時(shí)有一個(gè)致命問題直接按比例采樣會(huì)跳過大量源像素導(dǎo)致高頻信息丟失出現(xiàn)摩爾紋。論文里給出的改進(jìn)思路是先對(duì)源圖像做鄰域取平均把多個(gè)像素合并成一個(gè)再做最近鄰插值。這樣相當(dāng)于先做了一次低通濾波再降采樣。% 鄰域取平均縮小 function output area_average_shrink(input, scale) [h, w] size(input); new_h round(h * scale); new_w round(w * scale); output zeros(new_h, new_w, like, input); block_h h / new_h; block_w w / new_w; for i 1:new_h for j 1:new_w % 計(jì)算源圖中對(duì)應(yīng)的塊范圍 r1 floor((i-1)*block_h) 1; r2 min(floor(i*block_h), h); c1 floor((j-1)*block_w) 1; c2 min(floor(j*block_w), w); % 塊內(nèi)取平均 block input(r1:r2, c1:c2); output(i, j) mean(block(:)); end end end這個(gè)算法的關(guān)鍵是block_h和block_w的計(jì)算。當(dāng)縮放倍數(shù)不是整數(shù)時(shí)每個(gè)目標(biāo)像素對(duì)應(yīng)的源塊大小可能不同邊界處理要格外小心。論文里的實(shí)驗(yàn)表明這種算法在縮小場景下比直接最近鄰插值減少了混疊但運(yùn)算量隨縮放倍數(shù)增加而上升。3.2 Ferguson 曲面插值用曲面擬合做圖像放大Ferguson 曲面是一種參數(shù)曲面通過四個(gè)角點(diǎn)和切向量來定義。論文把它引入圖像縮放思路是把圖像局部區(qū)域看作一個(gè)曲面用 Ferguson 曲面片擬合后再采樣。數(shù)學(xué)推導(dǎo)比雙三次復(fù)雜但核心是用 Hermite 插值基函數(shù)構(gòu)造混合矩陣。% Ferguson 曲面插值的簡化實(shí)現(xiàn)單通道 function output ferguson_interp(input, scale) [h, w] size(input); new_h round(h * scale); new_w round(w * scale); output zeros(new_h, new_w, like, input); for i 1:new_h for j 1:new_w src_i i / scale; src_j j / scale; % 取 2x2 鄰域 i1 max(floor(src_i), 1); j1 max(floor(src_j), 1); i2 min(i1 1, h); j2 min(j1 1, w); % 局部坐標(biāo) u src_i - i1; v src_j - j1; % Hermite 基函數(shù) h00 2*u^3 - 3*u^2 1; h10 u^3 - 2*u^2 u; h01 -2*u^3 3*u^2; h11 u^3 - u^2; % 簡化加權(quán)完整版需計(jì)算切向量 output(i, j) h00*input(i1, j1) h01*input(i2, j1) ... h10*input(i1, j2) h11*input(i2, j2); end end end實(shí)際論文里的 Ferguson 實(shí)現(xiàn)需要估計(jì)每個(gè)角點(diǎn)的切向量通常用相鄰像素差分來近似。這個(gè)算法的優(yōu)點(diǎn)是曲面擬合能更好地保持圖像的光滑性缺點(diǎn)是切向量估計(jì)對(duì)噪聲敏感運(yùn)算量也比雙三次大。3.3 帶系數(shù)自適應(yīng)插值與邊緣定向插值論文還研究了兩種更貼近實(shí)際應(yīng)用的改進(jìn)算法。帶系數(shù)自適應(yīng)插值根據(jù)局部梯度動(dòng)態(tài)調(diào)整插值系數(shù)在平坦區(qū)域用雙線性在邊緣區(qū)域加大邊緣方向的權(quán)重。邊緣定向插值則先做邊緣檢測判斷邊緣方向后沿邊緣方向插值避免跨邊緣插值造成的模糊。% 簡化邊緣定向插值根據(jù)梯度選擇插值方向 function output edge_directed_interp(input, scale) [h, w] size(input); new_h round(h * scale); new_w round(w * scale); output zeros(new_h, new_w, like, input); for i 1:new_h for j 1:new_w src_i i / scale; src_j j / scale; i1 max(floor(src_i), 1); j1 max(floor(src_j), 1); i2 min(i1 1, h); j2 min(j1 1, w); % 計(jì)算水平和垂直梯度 gx abs(input(i1, j2) - input(i1, j1)); gy abs(input(i2, j1) - input(i1, j1)); % 梯度小的方向權(quán)重更大 if gx gy output(i, j) 0.7*input(i1, j1) 0.3*input(i1, j2); else output(i, j) 0.7*input(i1, j1) 0.3*input(i2, j1); end end end end這個(gè)簡化版只做了方向選擇完整版還需要在選定方向上做線性插值。論文的實(shí)驗(yàn)數(shù)據(jù)表明邊緣定向插值在邊緣區(qū)域的 PSNR 比雙線性高 1 到 2 dB但運(yùn)算量增加約 30%。3.4 多幀圖像融合提高分辨率論文最后一類改進(jìn)算法走的是另一條路不靠單幀插值而是用多幀低分辨率圖像融合出一幀高分辨率圖像。核心技術(shù)是運(yùn)動(dòng)估計(jì)和共軛梯度優(yōu)化。這個(gè)方向已經(jīng)超出了傳統(tǒng)插值的范疇屬于超分辨率重建。論文里給出了基于共軛梯度算法的融合流程但實(shí)現(xiàn)復(fù)雜度較高適合作為進(jìn)階研究方向。算法運(yùn)算量相對(duì)最近鄰邊緣保持適用場景最近鄰1×差實(shí)時(shí)預(yù)覽雙線性4×中通用縮放雙三次16×好高質(zhì)量放大邊緣定向20×很好邊緣敏感場景多幀融合50×以上極好超分辨率重建4. 避坑與排查MATLAB 圖像縮放實(shí)驗(yàn)中的五個(gè)血淚教訓(xùn)4.1 圖像類型轉(zhuǎn)換導(dǎo)致灰度值截?cái)喱F(xiàn)象用uint8圖像直接做加權(quán)插值結(jié)果出現(xiàn)大面積純黑或純白。原因uint8的乘法會(huì)飽和到 255加權(quán)系數(shù)小于 1 時(shí)結(jié)果被截?cái)酁?0。解決計(jì)算前用double(input)轉(zhuǎn)換計(jì)算完再用uint8(output)轉(zhuǎn)回中間不要混用類型。4.2 坐標(biāo)映射公式寫反導(dǎo)致圖像鏡像現(xiàn)象放大后的圖像左右或上下顛倒。原因把src_i i / scale寫成了src_i i * scale或者行列索引弄反。解決記住目標(biāo)坐標(biāo)除以縮放倍數(shù)得到源坐標(biāo)放大時(shí)scale 1源坐標(biāo)范圍小于目標(biāo)坐標(biāo)范圍。4.3 邊界索引越界導(dǎo)致程序崩潰現(xiàn)象放大到邊緣時(shí) MATLAB 報(bào)Index exceeds matrix dimensions。原因floor(src_i) 1在最后一個(gè)像素處超出圖像尺寸。解決所有索引計(jì)算后加min(max(idx, 1), dim)保護(hù)或者對(duì)源圖像做邊界填充。4.4 循環(huán)順序影響緩存命中率現(xiàn)象同樣的算法別人跑 2 秒自己跑 20 秒。原因MATLAB 是列優(yōu)先存儲(chǔ)外層循環(huán)應(yīng)該遍歷列內(nèi)層遍歷行。如果寫反了緩存命中率急劇下降。解決把for i放外層、for j放內(nèi)層或者直接用向量化操作替代循環(huán)。4.5 用imresize對(duì)比時(shí)忽略了抗鋸齒現(xiàn)象自己寫的雙線性結(jié)果和imresize對(duì)不上。原因imresize在縮小默認(rèn)開啟抗鋸齒會(huì)先做低通濾波。解決對(duì)比時(shí)用imresize(input, scale, bilinear, Antialiasing, false)關(guān)閉抗鋸齒或者在自己的算法里也加上預(yù)濾波。注意論文里的實(shí)驗(yàn)數(shù)據(jù)是在特定圖像集上得到的換一組圖像后 PSNR 排名可能變化。不要迷信單一指標(biāo)要同時(shí)看主觀效果和運(yùn)算時(shí)間。5. 從畢設(shè)到工程把縮放算法封裝成可復(fù)用函數(shù)的三個(gè)技巧第一個(gè)技巧是參數(shù)化核函數(shù)。不要把雙三次的核函數(shù)寫死在循環(huán)里而是抽成獨(dú)立函數(shù)用函數(shù)句柄傳入。這樣換核函數(shù)時(shí)只改一個(gè)參數(shù)不用動(dòng)主循環(huán)。我一般會(huì)定義kernel (x) cubic_kernel(x, -0.5)然后在插值函數(shù)里調(diào)用kernel(di)。這樣同一套插值框架可以跑最近鄰、雙線性、雙三次和自定義核。第二個(gè)技巧是預(yù)計(jì)算權(quán)重表。當(dāng)縮放倍數(shù)固定時(shí)每個(gè)目標(biāo)像素的權(quán)重只取決于小數(shù)部分而小數(shù)部分只有有限種取值??梢灶A(yù)先算好權(quán)重矩陣循環(huán)里直接查表避免重復(fù)計(jì)算核函數(shù)。對(duì)于 512×512 放大到 1024×1024預(yù)計(jì)算能把雙三次的耗時(shí)降低 40% 左右。% 預(yù)計(jì)算權(quán)重表示例 function weights precompute_weights(scale, kernel, max_dist) % max_dist: 核函數(shù)支持半徑雙三次為 2 n 1000; % 小數(shù)部分離散化精度 weights zeros(n, 2*max_dist); for k 1:n frac (k-1) / n; for d -max_dist1:max_dist weights(k, dmax_dist) kernel(frac - d); end end end第三個(gè)技巧是用meshgrid和向量化替代雙重循環(huán)。MATLAB 的循環(huán)性能一直被人詬病把坐標(biāo)計(jì)算全部向量化后雙線性插值可以做到接近imresize的速度。核心是把for i 1:new_h和for j 1:new_w替換成矩陣運(yùn)算用interp2的思路構(gòu)造查詢點(diǎn)。驗(yàn)證方法很簡單拿一張標(biāo)準(zhǔn)測試圖分別用自己寫的函數(shù)和imresize跑一遍計(jì)算 PSNR 和 SSIM。如果 PSNR 差距在 0.5 dB 以內(nèi)說明實(shí)現(xiàn)基本正確。再換幾張不同內(nèi)容的圖看邊緣區(qū)域有沒有異常振鈴或模糊。最后用tic和toc記錄耗時(shí)和論文里的運(yùn)算量分析對(duì)照。從那以后我每次做圖像縮放實(shí)驗(yàn)都強(qiáng)制走一遍“類型轉(zhuǎn)換檢查 → 邊界保護(hù) → 向量化驗(yàn)證 → 指標(biāo)對(duì)比”的流程再也沒出現(xiàn)過整圖變黑或者跑一晚上出不來結(jié)果的情況。希望幫到你。本文還有配套的精品資源點(diǎn)擊獲取