實(shí)現(xiàn)《你的名字》同款濾鏡,python+opencv

好久沒有上簡(jiǎn)書,最近上來一看發(fā)現(xiàn)這篇文章閱讀量遠(yuǎn)超了其他的文章,還有評(píng)論提到說在講技術(shù)的時(shí)候賣萌不好。哈哈,當(dāng)時(shí)寫的時(shí)候完全沒想過會(huì)有人搜到看,只是為自己的作品留個(gè)念想,所以文風(fēng)比較散漫隨意。于是這次來小修了一遍,謝謝閱讀~



前很長(zhǎng)一段時(shí)間,時(shí)光相冊(cè)火了一個(gè)應(yīng)用《你的名字》同款濾鏡,一時(shí)間這種鮮艷靚麗的卡通天空濾鏡刷遍了QQ空間朋友圈。

時(shí)光相冊(cè)的效果是這樣的。

左:原圖,右:濾鏡圖

他們?cè)谛侣劜稍L中說自己和prisma一樣用到了深度學(xué)習(xí)的技術(shù),不過是用在了天空區(qū)域提取上。

我初步理解下就是:

1. 使用深度學(xué)習(xí)提取了天空區(qū)域

2. 蒙版替換了預(yù)設(shè)的卡通天空?qǐng)D片

3. 輔以傳統(tǒng)美圖濾鏡方法美化效果。

天空區(qū)域真的需要用深度學(xué)習(xí)來提取嗎?在知乎上逛了,下果然有人和我有相似的疑問。

我覺得深度學(xué)習(xí)真的很難把控,這是自己做著玩的小東西,所以我就用opencv實(shí)現(xiàn)了一個(gè)極簡(jiǎn)版=v=


首先確定編碼流程:

1). 實(shí)現(xiàn)天空提取檢測(cè)模塊

2). 實(shí)現(xiàn)無縫融合模塊

3). 實(shí)現(xiàn)日系色調(diào)濾鏡

4). 整合測(cè)試及聯(lián)調(diào)



PART1. 天空區(qū)域提取

嘗試了三種方法,兩種是來自論文的,一種是隨便寫寫的,從最終的平均質(zhì)量來看,還是拍腦袋決定的簡(jiǎn)單方法A的平均質(zhì)量更高。

方法A. 閾值分割,藍(lán)色消除

核心思想是將藍(lán)色作為天空進(jìn)行消除。利用HSV顏色模型做色調(diào)分離,首先將原圖轉(zhuǎn)換到HSV空間,并進(jìn)行藍(lán)色部分的選擇,然后做個(gè)閾值分割,從而使得藍(lán)色可以被分割走。只要我們選取到了合適的H值,那么就可以把藍(lán)色去掉。

下表是顏色對(duì)應(yīng)的HSV的值:

這種方案在天空較均勻,藍(lán)色較明顯時(shí)表現(xiàn)較好

我的效果(目前用的opencv里的copyto接口,傻乎乎的粘貼了卡通天空?qǐng)D去檢測(cè)到的區(qū)域)所以邊界還比較僵硬。

我的天空區(qū)域提取代碼:首先是cvtColor,給原圖從BGR轉(zhuǎn)HSV去,然后把hsv的三個(gè)通道split一下

用Inrange分出我們需要的藍(lán)色閾值區(qū)域。中值濾波一下消除雜點(diǎn),讓Mask看起來比較完整。跟著一個(gè)開操作,再濾波一下。其實(shí)這些都是我隨便定的,目的就是讓提取出的黑白Mask更完整一點(diǎn),別盡是小雜點(diǎn),我們只需要保證大致的準(zhǔn)確就行。把檢測(cè)區(qū)域存在mask里,做成一個(gè)黑白圖片。(用來提取天空region的mask),下面是這段文字的順序代碼描述。

B.《sky region detection in a single image for autonomous ground robot navigation》

和其他的方法不同,這個(gè)算法可以同時(shí)用于灰度圖和彩色圖。做法是:1、獲取圖像的梯度信息;2、根據(jù)能量函數(shù)優(yōu)化計(jì)算【梯度域的最優(yōu)分割閾值】,估計(jì)初始天空區(qū)域;3、最后一步后處理是為了細(xì)化前期天空區(qū)域的檢測(cè),比如途中沒有天空區(qū)域出現(xiàn),或天空對(duì)象伸出地面時(shí)。、

這個(gè)我實(shí)現(xiàn)了,測(cè)試時(shí)很容易檢測(cè)出奇奇怪怪的東西。可能是我寫的不對(duì),如果最終要求是70%圖能看,那么還是A方法好一些。

C.《一種基于灰度閾值的天地背景輪廓線提取方法》

針對(duì)天地背景輪廓線具有波動(dòng)起伏、邊緣模糊及輪廓邊緣灰度值變化緩慢的特點(diǎn),采用灰度閾值方法,實(shí)現(xiàn)了多種天地背景邊緣輪廓提取

天地背景圖像通常包括天空區(qū)域和地表區(qū)域,常見的有天空海面、天空平原、天空山地、天空沙漠等景物圖像。在攝錄遠(yuǎn)距離天地背景圖像時(shí),背景圖像除了噪聲增大外,還會(huì)因大氣湍流等因素影響而產(chǎn)生抖動(dòng)或起伏,這種現(xiàn)象在背景邊緣輪廓附近尤為明顯。其結(jié)果造成圖像輪廓邊緣模糊、波動(dòng)起伏,圖像邊緣區(qū)域灰度值變化呈現(xiàn)連續(xù)緩慢變化狀態(tài),導(dǎo)致建立在微分理論基礎(chǔ)上的傳統(tǒng)經(jīng)典圖像邊緣檢測(cè)算法對(duì)天地背景圖像的邊緣輪廓提取失效。

同上,可能是我寫的不對(duì),如果最終要求是70%圖能看,那么還是草率決定的A方法好一些。


無縫融合

在展示方法A效果的時(shí)候,我用copyto函數(shù)進(jìn)行的融合,那融合效果十分僵硬,邊緣一看就是摳圖貼上去的,這種看起來就很沒品并外行的效果,咱們是必須拒絕的。

那么怎么做融合才能無縫?這里我了解的方法中和時(shí)光相冊(cè)效果最像的是一個(gè)叫【泊松融合】的方法。seamlessClone這個(gè)泊松函數(shù)在Opencv2里沒有,所以我重新去下opencv3。下來opencv3后,發(fā)現(xiàn)報(bào)錯(cuò)提示我Numpy跟不上版本,本來裝的是Numpy1.9,說要升級(jí)到10以上。然后跑去sourceforge里補(bǔ)了一個(gè)numpy 1.10.2。當(dāng)環(huán)境配好之后,seamlessClone就自己通了。詳細(xì)代碼是這樣的:

其實(shí)完全就是調(diào)用用seamlessClone這個(gè)函數(shù)么,前期需要做一些準(zhǔn)備工作。找出邊緣,給出定位(確定要把卡通圖貼在什么位置、按什么比例縮放后再貼)

然后調(diào)用seamlessClone,按api上要求的給他傳他要的那些參數(shù)就Ok了。這里選的融合方式是normal_clone,不清楚原因,只是把選項(xiàng)都試了試這個(gè)效果最好。

這個(gè)變化真真是超明顯的。下面放對(duì)比圖,左邊是沒有seamlessclone的,右邊是seamlessClone的??梢钥醋筮叺臉涞拈g隙(好明顯的異樣感),右邊是用seamlessclone之后,瞬間就無痕了。

這樣看起來右邊就已經(jīng)挺自然的了。不過還缺了點(diǎn)“動(dòng)漫感”,為什么呢,因?yàn)闆]有調(diào)色。


調(diào)色濾鏡

其實(shí)這玩意卡了我很久,因?yàn)閴焊鶝]在網(wǎng)上看到“教教我怎么做濾鏡”這樣的教程。一搜一大把都是用著那些很基本的函數(shù)弄來弄去,都是些很丑很土氣的濾鏡效果

那么多美圖應(yīng)用都提供了什么“和風(fēng)濾鏡”,“小清新濾鏡”,“午后陽光濾鏡”,Blabla…………

有木有人可以告訴我他們都是咋做的?

我唯一的參考資料就是只需 4 步,手把手教你如何實(shí)現(xiàn)濾鏡功能

謝謝大神,雖然完全沒有感受到手把手的教(擦淚),但是連猜帶蒙的我還是給整出來了。

就讓我來手把手的教大家一下(擦淚)。

首先,有一張(被公認(rèn)很標(biāo)準(zhǔn)的)色卡圖,當(dāng)原始顏色映射表,左圖是原始顏色表,右圖是對(duì)應(yīng)著某個(gè)色彩濾鏡“比如和風(fēng)”的濾鏡色卡表。

這兩個(gè)色卡表說是表,其實(shí)就是圖片,就是一堆有RGB通道的像素點(diǎn)集。

我說下濾鏡的思想:

? ? ? ? 要給一張圖片刷濾鏡,遍歷它的每個(gè)像素點(diǎn),比如坐標(biāo)(0,0)的像素點(diǎn),它的顏色是(123,132,231)先在表1查顏色(123,132,231)對(duì)應(yīng)的色卡表位置(坐標(biāo)),再去表二查出對(duì)位坐標(biāo)的新的顏色值(RGB)替換掉當(dāng)前像素點(diǎn)的顏色(RGB)?;径际亲孕心X補(bǔ)出來的思路,原始色卡說白了就是一堆數(shù)值,一堆有規(guī)律的數(shù)值。

我們需要跟著輸入圖的各個(gè)像素點(diǎn)上的RGB值,找到它位于原始色卡的坐標(biāo)。那么就是要找到原始色卡每個(gè)點(diǎn)的RGB值和它的坐標(biāo)的對(duì)應(yīng)關(guān)系。這個(gè)原石色卡表當(dāng)然是有規(guī)律的,它每個(gè)坐標(biāo)上的RGB數(shù)值都是和坐標(biāo)掛鉤的,是有規(guī)則的。

經(jīng)過一段時(shí)間的歸納總結(jié)我推出來了映射公式:(AB二維是坐標(biāo),xyz是三個(gè)顏色通道)

A = y/4 + (x/32)*64

B = z/4 + ((x%32)/4)*64

這個(gè)公式我驗(yàn)證了完全正確,用網(wǎng)上給出的一個(gè)示例色卡,能刷出濾鏡色如下。

是不是看起來挺高級(jí)?有點(diǎn)美圖秀秀的feel了吧!

可能有人想問??右邊那個(gè)對(duì)應(yīng)新濾鏡的色卡是怎么來的?

答:我在網(wǎng)上下載的。(好吧,專業(yè)的濾鏡制作公司應(yīng)該會(huì)需要藝術(shù)家?設(shè)計(jì)師來做那張色卡)這是藝術(shù)范疇了我等程序猿只要知道怎么怎么進(jìn)行映射,怎么寫代碼轉(zhuǎn)換風(fēng)格就可以了。不過,畢竟是沖著實(shí)現(xiàn)你的名字同款濾鏡的目標(biāo)做的。那你的名字同款色調(diào)也是必須的。

那么我來介紹一下我制作右側(cè)色卡的方法把。。

……

感覺說出來會(huì)很丟人。

……

但不失為一個(gè)好辦法。

【把左側(cè)的原始色卡存到手機(jī)里,放到任意一個(gè)美圖應(yīng)用里 “刷一下” ,刷哪個(gè)濾鏡,就出哪個(gè)濾鏡的色卡。等于是復(fù)刻色卡】

如果是盈利性質(zhì)的這樣做肯定是不行的,應(yīng)該讓設(shè)計(jì)師設(shè)計(jì),咱們宅著自己練技術(shù)玩,這方法還不錯(cuò)。

下面是我對(duì)色卡操作的代碼:

整合前三塊

最后就是簡(jiǎn)單的加法,把前三塊串起來就Ok了

可以大概看看最終效果,我覺得還挺夢(mèng)幻的,不過因?yàn)樘炜仗崛〉乃惴ㄌ?jiǎn)單,所以有些圖片的天空的表現(xiàn)很辣雞就是了。。Just for fun!

嘿嘿嘿我要寫簡(jiǎn)書當(dāng)然是放好看的效果了。至于不好看的,就不展示了

批量測(cè)試的結(jié)果(100張圖):

好看的結(jié)果普遍在50%左右,能看(不保證好看)的結(jié)果在80%以上。不能看的在15%左右。不能看圖就是固定的幾張,都是因?yàn)樘炜諈^(qū)域提取出錯(cuò)了(多選/少選)。如果想做成專業(yè)應(yīng)用,在天空區(qū)域提取這步肯定不能像我寫的方法A這么隨意。

以上。

謝謝閱讀~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容