图像处理之让手心长出眼睛,其实嘴也可以
無圖像,不處理,先上效果圖。手上長嘴當(dāng)然也可以,不過感覺有點(diǎn)惡心 ~ 就不上那種圖了。
這里所采用的算法就是大名鼎鼎的泊松融合算法,它的應(yīng)用非常廣泛,除了上面這種手上長眼睛的效果,還可以實(shí)現(xiàn)“紋理拼接”、“精細(xì)摳圖”、“移花接木”等等效果。我之前已經(jīng)從純數(shù)學(xué)的角度討論過它的原理了。
但是,當(dāng)初給出的代碼僅僅是為了算法演示的目的,所以并未進(jìn)行優(yōu)化。可以說是最簡單、最原始的實(shí)現(xiàn)方法。然后,我寫完就扔一邊很久沒碰了。今天有朋友向我了解,我表示印象中用高斯法解大稀疏矩陣也可以實(shí)現(xiàn)對泊松方程的求解,但是當(dāng)初沒有深究。今天好奇心再次被喚起,想來再續(xù)前緣。沒想到一頓翻箱倒柜,還真找到些不錯(cuò)的資料。其中一篇感性角度理解該算法的文章感覺很不錯(cuò)。不僅介紹了算法的原理(而且完全不從數(shù)學(xué)角度,就從感性認(rèn)識談也一樣深刻),還談及了優(yōu)化的實(shí)現(xiàn)方法。今天我特別二次加工后與各位分享。
原文鏈接:http://eric-yuan.me/poisson-blending/
下面的圖基本都是盜的原文中的,原文是英文,我根據(jù)自己的理解翻譯+改編,希望能融合一些我個(gè)人的理解。
首先,讓我們從最最簡單的“一維”情況開始考慮。如下圖所示,我們的目標(biāo)是將左圖中紅色的部分copy到右圖中,這個(gè)時(shí)候左圖中紅色部分就相當(dāng)于是最開始圖中的“眼睛”,右圖就是一個(gè)手掌。
如果要做到天衣無縫,我們應(yīng)該保證哪些條件?這個(gè)我在過去的文章中討論過,總而言之,言而總之,就兩條:1)將眼睛融入手掌之后,眼睛和手掌相連的邊緣過渡要平滑(用圖像處理的術(shù)語說,就是梯度小)。2)眼睛內(nèi)部的自身紋理要最大程度保留,不能融合之后眼睛沒了,就剩手掌那肯定不行。
就我們當(dāng)前所面對的這個(gè)例子,其實(shí)就是要求:
其中f?是右圖中的“信號”,而+1、-1、+2、-1、-1是原圖(左圖)本來的梯度。那我們有沒有什么是已知的呢?有的!f1=6,f6=1,即融合邊界的信息我們已知。于是化簡有
然后根據(jù)費(fèi)馬定理,當(dāng)有極值時(shí),偏導(dǎo)數(shù)等于零,即
然后如果用矩陣形式來表示方程組便有
現(xiàn)在要解一個(gè)線性方程組,而且這個(gè)方程組還是稀疏的,顯然用高斯-塞德爾迭代法是非常不錯(cuò)的選擇,這也是泊松方法的原作者最初使用的求解方法。而且高斯法會(huì)比雅各比法快很多。更多高斯-塞德爾迭代法的內(nèi)容請見
Jacobi迭代法與Gauss-Seidel迭代法?_一九八網(wǎng)絡(luò)科技V客學(xué)院-IT技術(shù)博客
/baimafujinji/article/details/50582462
然后我們咔嚓一頓狂解,最后得到方程組的結(jié)為:f2=6,f3=4,f4=5,f5=3,這好像并不太直觀,于是用圖形來表示
哈啊!看出門道了嗎?首先,接合的地方過渡很自然(梯度小),內(nèi)部紋理保持的也不錯(cuò)(基本和原圖一致)。Yes, we get it!
然后呢?我們既然處理的對象是圖像,所以還得回到二維的情況來看看。其實(shí),你應(yīng)該理解,這個(gè)推廣的過程其實(shí)沒啥新鮮的東西。但它與你編程實(shí)現(xiàn)直接相關(guān)。下圖演示了我們將要開展的工作。數(shù)字方格是我要copy過來的像素點(diǎn),紅色表示接合邊緣。
跟一維的情況一樣,我們現(xiàn)在要解線性方程組?Ax = b,其中A是一個(gè)N×N的方陣,N是我們要copy的像素?cái)?shù)目,本題中N=10。我們用下面的偽代碼演示了創(chuàng)建一個(gè)所需的10×10方陣。
for i=1:row numberfor j=1:col numberif(i==j)matrix(i, j)=-4elif(adjacent(pixel(j), pixel(i)))matrix(i, j)=1elsematrix(i, j)=0endendend 最終我們生成的矩陣應(yīng)該是長成下面這個(gè)樣子(我之前以為原博文作者這個(gè)地方寫錯(cuò)了。直到我編碼實(shí)現(xiàn)的時(shí)候才發(fā)現(xiàn)其中另有玄妙。真是實(shí)踐出真知啊!在下一篇文章中,我會(huì)結(jié)合Matlab代碼來演示這個(gè)地方。):
在方程組?Ax = b中,b?是一個(gè)N元向量,它是由下面這個(gè)式子創(chuàng)建的
b[i] = div ( G( Source(x,y) ) ) + Neighbor(target i) ; ? ? ? ? ?i=1..N
其中G(·)是求梯度,散度由下面公式求得(這屬于經(jīng)典離散數(shù)值解,不做過多解釋,如果你感覺困惑可以看我前面的文章,已經(jīng)說得很詳細(xì)了)
div G = -4 f(x,y) + f(x-1,y) + f(x,y-1) + f(x+1,y) + f(x,y+1)
其中i的鄰域(Neighbor)指的是i的四鄰域點(diǎn)中屬于邊界的部分,例如從圖中可以看出
- Neighbor(pixel 1) 有三個(gè)點(diǎn): left, up, right;
- Neighbor(pixel 8) 有兩個(gè)點(diǎn): left, up;
- Neighbor(pixel 5) 有一個(gè)點(diǎn): up.
這里我還想根據(jù)Patrick的經(jīng)典論文之原文來對上面的結(jié)論做進(jìn)一步的解釋。其中,p是S中的一個(gè)元素,Np是點(diǎn)p位于S內(nèi)部的4鄰域點(diǎn)。<p,q>表示一個(gè)點(diǎn)對,其中q∈Np。Ω的邊界
請注意,S和Ω的所代表的意思我在前面的文章中已經(jīng)給出,請讀者參考之前的文章。令fp 代表p點(diǎn)處的f值。那么原來的優(yōu)化問題就變成了如下的離散形式:
vpq?是v((q+p)/2)在邊[p,q]方向上的投影,即
上述最優(yōu)化問題的解滿足
? ??(7)
這就是我們上面給出的那個(gè)公式。對于位于S中的Ω的邊界像素點(diǎn)p,|Np|<4,即邊界上點(diǎn)的鄰域點(diǎn)少于4個(gè),顯然邊界上的點(diǎn)p至少有一個(gè)鄰域點(diǎn)位于Ω內(nèi)部。然而,對于那些位于Ω內(nèi)部的像素點(diǎn)p而言,即Np∈Ω,等式右端的邊界項(xiàng)就不復(fù)存在了,即有
方程(7)是一個(gè)很大的稀疏矩陣,所以可以用經(jīng)典的迭代法進(jìn)行求解。作者指出他原文中的結(jié)果是采用高斯-塞德爾法得到的。
如果我們知道矩陣?A?和向量?b, 我們就可以根據(jù)x?=?A-1?*?b來計(jì)算向量x,這也就是目標(biāo)圖像中要被填充的部分像素。
總結(jié)
以上是生活随笔為你收集整理的图像处理之让手心长出眼睛,其实嘴也可以的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 基于直方图的图像增强算法(HE、CLAH
- 下一篇: 图像的泊松(Poisson)编辑、泊松融