今天首次接觸了圖像編輯中的seam carving知識,感覺挺神奇的。雖然我自己可能理解的不是很深刻,但是記錄下來,總是好的。
seam carving直接翻譯過來是“線裁剪”的意思。它的主要用途是對圖像進行縮放。不同於傳統的按比例縮放圖像的方式,seam carving的是內容感知的,它充分考慮了圖像中像素的重要性,通過刪除或增加seam線來實現圖像尺寸的調整。它在縮放不是特別大的情況下,能夠很好的保護圖像中的顯著物體。
具體來說,seam carving定義了穿過整幅圖像的像素線(即seam),它是由圖像中最低能量的像素組成的。如左下圖中畫出了一個橫向的seam和一個縱向的seam。
接下來需要說明的是,seam的形成。seam是有圖像中,最不重要的像素組成的。因此,首先要對圖像中的像素點的重要性進行定義。給定一幅n x m的圖像I,它的能量函數定義為:
在一幅圖像中,某一像素點的能量越大,則它也越重要。換言之,像素的能量越小,它在圖像中就越不重要。seam線(或縫合線)就是由圖像中那些不重要的像素點組成的。
對於上述n x m 的圖像I, 一個豎直的seam線定義如下:
這個公式乍看起來很復雜,其實際的意義很容易理解。式中i表示第 i 行,即像素的縱坐標, x(i)表示第 i 行中的某個像素的橫坐標值。也就是說,一個豎直的seam線包含 n 行(圖像是 n 行乘 m 列的),每行中取出一個像素點。而后面的約束表示的意思是相鄰兩行的像素點之間是相鄰的(八連通領域),這樣限制的作用是,去掉seam線之后,畫面看起來不會出現很跳躍的感覺,直觀表示如下圖所示,(i,j)的前一點只能來自(i-1,j-1),(i-1,j),(i-1,j+1)中的某一點。
對於給定的能量函數 e( I ),可以將縫合線的代價函數定義:
當前要選擇的縫合線即為代價函數值最小的縫合線。設當前狀態下最優的縫合線為 S*:
應當利用動態規划(Dynamic Programming)來求解尋找最低代價的、豎直的、八連通的縫合線上所有像素點的問題。設將當前圖像的累積最小能量存儲在 M 矩陣里,而將圖像的能量函數值存儲在 NRG 矩陣里。然后把能量函數 NRG 的首行作為 M 的首行初始值。把當前行的能量函數值加上 M [i 1][ j 1]、M [i 1][ j]和M [i 1][ j1]中的最小值作為 M 下一行的值。通過存儲以前計算的結果,可以對縫合線進行多次計算。下面以計算豎直縫合線為例來說明該算法。可以利用下式來填充 M 來計算最優縫合線: