什麼叫“摳圖”?顧名思義,所謂摳圖就是從一幅圖片中將某一部分截取出來,和另外的背景進行合成。不要小看這一工作,我們生活中的很多圖像製品都曾經經過這種加工,例如廣告等,需要設計人員將模特照片中的人像部分摳取出來,然後再和背景進行合成。事實上,摳圖在您的生活中也大有用武之地,尤其是隨著數碼相機、掃描儀等設備的普及,越來越多的人開始樂於對自己手中的照片進行各種各樣的“特殊處理”,譬如把自己的全身像摳取出來放到別的背景中,把戀人的單人照片進行摳圖後與自己的照片合成雙人照等等,都需要用到摳圖。
在過去,人們往往使用套索工具進行摳圖操作。作為Adobe公司的知名圖形處理軟件,PhotoShop可以對圖形進行非常精確的處理,無論要摳取的圖形有多複雜,也可以分毫不差地全部截取出來。但是,對於新手來說,PhotoShop的使用略嫌複雜,如果不經過一段時間的培訓和練習,用戶很難掌握操作的要領。為了將圖片中的某一部分取出來,用戶必須沿著對象的邊緣“剪”一圈,如果圖片本身有較多的棱角或者突起,工作的難度就會成倍增加。
與PhotoShop相比,Lazy Snapping的使用就要簡單多了,對於絕大多數圖形來說,隻需要三步,就可以將我們需要的內容截取出來。
摳圖三部曲
讓我們以一幅貓的照片為例來看看這款軟件是如何簡單易用的。首先,我們按住鼠標左鍵,在需要截取的目標——貓的身上,隨意劃條線,這條線既不必準確地沿著貓的身體邊沿部分,也不必要求什麼“橫平豎直”,隻要是畫在貓身上即可。然後,在貓的身邊,也就是我們不需要的背景上,點住鼠標右鍵劃一道。幾乎在我們劃完這條線的同時,圖片中貓的部分就被套在一個取景框中了。怎麼,還有一部分沒有被選中?沒關係,您隻要在需要選中的位置再按住鼠標左鍵劃幾下,該部分就可以被選中了。
如果圖形非常簡單的話,那麼隻需要做到這一步就可以“大功告成”了。但是現在我們的目標是一隻貓,其身體的邊沿存在少數不規則或者低對比度的邊緣,我們還需要進行第二步:微調。聽到“微調”這個詞,有的朋友可能認為會非常複雜。但事實上,這一步的操作依然非常簡單。您可以通過調節套住貓身體的取景框來更準確地選取要截取的圖片。如果您想更簡單,也可以選擇軟件的“brush”功能,在不夠準確的地方隨著邊界刷兩下,軟件就會自動將需要截取的目標圖形的邊界準確地勾畫出來。
完成第二步操作後,圖片中貓的部分已經基本上都被取景框選中了。但如果我們仔細觀察就會發現,在前景和背景顏色不同的時候,背景的顏色往往會滲透到前景上來。在使用PhotoShop摳圖的時候,這就需要做“羽化”操作,以盡量弱化這種情況,但在大多數情況下,羽化並不能完美地解決這一問題,往往需要將前景的邊界收縮,“割”掉那些被背景顏色滲透的部分,也就是說要損失一定的前景。而在Lazy Snapping中,這一操作步驟被極大地增強並簡化了,不論前景和背景的顏色對比度是高還是低,Lazy Snapping都可以非常準確地將前景的顏色清楚地分離出來,既不會缺少一部分,也不會讓背景的顏色滲透到前景中去。
不過,如果您細心觀察的話,就會發現,貓的胡須並沒有被選中。這是因為貓的胡須為半透明,而且又長又細,相互之間又比較分散,因此軟件難以自動將其選中。這時就需要用到第三步操作。這一步的操作更加簡單,我們隻要用鼠標在貓胡須部位隨意塗抹兩下,將胡須部位覆蓋住,這些胡須就會被選中了。當然,嚴格地說,這並不是第三步操作的主要功能,軟件設計者之所以為軟件添加這一功能,其實更主要地是為了更好地完成前景和背景顏色的分離(Coherent Matting)。
Lazy Snapping的基礎:Graph Cut
Graph Cut技術是圖論中的一個概念,也是Lazy snapping這款軟件的核心技術。在軟件的第一步和第二步操作中,對前景的輪廓計算和對細節部分進行修補的操作,都是基於該技術進行的。
首先,當一張圖被導入到Lazy snapping中時,軟件會自動采用一種被稱為“水線(watershed)”的算法對該圖進行處理。
所謂水線,通俗地說,就是把一張圖像的梯度圖想像成為一片凹凸不平的山地,其中,顏色變化小的區域就是山脊,而顏色變化劇烈的區域就是山窪。我們知道,每一個山窪周圍必然都是一圈山脊,如果在每一個山窪的最低點打一個洞,然後通過這個洞向山窪裏注水,則經過一段時間之後,相鄰山窪裏的水必然會越過山脊連接到一起。兩個山窪之間的水連接在一起的這條線,就是水線。通過這些水線,軟件就可以把圖片分為大小不等的若幹“碎片”。我們可以注意到,每一個區域中的顏色基本上都是相同的。
為什麼要先對圖片進行“水線”處理呢?因為我們知道,在計算機中,每一幅圖都是由無數個像素點構成的,當軟件需要分辨出圖像的前景和背景時,就需要對圖像中的所有像素點進行分析,這樣一來工作量會成立方級數增加,大大減緩處理的速度。而采用了“水線”處理之後,圖像中需要分析的就是那些被分割出的區域了,其數量比像素點要少數十倍,從而大大加快了軟件的處理速度。
接下來,就該是用戶需要做的工作了——通過劃線,告訴計算機哪些是我們想要的前景,而哪些是我們不想要的背景。如果從像素點的角度來看,一旦我們在圖像上畫了一條線,則這條線經過的像素點被我們稱為“種子點”,這些“種子點”所涉及到的區域,則被稱為“種子區域”。接下來,我們就需要借助這些“種子區域”將圖片分為“前景區域”和“背景區域”兩大塊。利用Graph Cut優化算法,圖片上所有區域會被賦予惟一的屬性,不屬於“前景區域”就一定會屬於“背景區域”。
在經過“水線”處理後的圖片中,我們把相鄰的區域連接在一起。而接下來Graph Cut優化算法要做的,就是嚐試將每個非“種子區域”分別與“前景區域”(或“背景區域”)之間的通路“打斷”。如果全部通路都可以被打斷,則軟件猜測該區域不屬於“前景區域”,反之則可能屬於。這樣,經過一番運算後,軟件就可以將圖形分為“前景區域”和“背景區域”兩大部分了,也就將我們所需要的前景的大致輪廓勾勒了出來。
Graph Cut 優化的準則,考慮了每一個區域的顏色與種子區域之間的顏色相似性,顏色越像“前景區域”就越可能被分在前景。同時它也考慮了相鄰區域的顏色差別,顏色差別越大這兩個區域越可能被分開。這個優化問題可以用圖論中極大流(極小割)的方法很快解決。
對於一張結構較為簡單的圖形來說,如果其前景和背景的對比非常明顯,且前景的形狀較為簡單,則經過前麵的處理後,前景圖形就已經被“摳”出來了。不過,如果圖片的內容較為複雜,且前景和背景之間的對比度不是很明顯的話,則需要對圖片進行進一步的微調。
所謂進一步處理,其實就是將前景與背景之間的“邊界”清晰地確定下來。由於在此之前我們已經確定了前景的大致輪廓,因此在這裏我們隻對前景和背景相交處的邊界附近進行處理,也就是已經確定好的“前景區域”和“背景區域”之間的那一塊地帶。
要說明的是,在前一步操作中,軟件通過“水線”算法將圖像分為一塊塊區域以加快處理的速度。而現在,由於要對圖像的邊緣部分進行調整,軟件處理的對象又變成了像素而不再是區域,以滿足處理精度方麵的要求。