書名: 深入理解OpenCV:實(shí)用計(jì)算機(jī)視覺項(xiàng)目解析(原書第3版)作者名: (美)羅伊·希爾克羅特(Roy Shilkrot) (西)大衛(wèi)·米蘭·埃斯克里瓦(David Millán Escrivá)本章字?jǐn)?shù): 2752字更新時間: 2020-04-14 14:50:58
1.3 皮膚變色器的實(shí)現(xiàn)
無須去檢測皮膚顏色和所在的區(qū)域,只需使用OpenCV的floodFill()函數(shù)即可,該函數(shù)類似于大多數(shù)圖像處理軟件中的顏料桶工具。我們知道屏幕中間區(qū)域就是皮膚像素(因?yàn)橐笥脩魧⑺麄兊哪樂旁谥虚g)。為了將整個人臉變成綠色皮膚,只需對圖像中心位置的像素進(jìn)行綠色漫水填充,這樣做總能讓人臉的某些部分變成綠色。實(shí)際上,顏色、飽和度和亮度在臉部的不同部位可能會有所不同,這會使漫水填充很少覆蓋面部的所有像素,除非將其閾值設(shè)為很低以至于覆蓋人臉以外的不想要的像素。為了解決這個問題,可在圖像中心區(qū)域不采用單個的漫水填充,而是對人臉區(qū)域中6個不同的皮膚像素點(diǎn)進(jìn)行漫水填充。
OpenCV的floodFill()函數(shù)有一個很好的特性,它會將漫水填充的效果繪制到新的圖像中而不(直接)修改輸入圖像。這一特性可得到一幅掩碼圖像,該圖像用來調(diào)整皮膚像素的顏色而不必改變亮度和飽和度,產(chǎn)生比所有皮膚都為綠色像素的圖像(這會導(dǎo)致重要臉部細(xì)節(jié)丟失)更為逼真的圖像。
在RGB顏色空間改變皮膚顏色效果并不好,因?yàn)楦淖兤つw顏色需要改變臉部圖像的亮度,但皮膚顏色不允許變化太大,而RGB無法從色彩中分離亮度。解決該問題的方法之一是采用HSV顏色空間,因?yàn)樗軐⒘炼扰c色彩(色調(diào))以及色度(飽和度)分開。不幸的是,HSV將色調(diào)值包裹在紅色周圍,又因?yàn)槠つw大多是紅色的,這就意味著需要同時使用<10%和>90%的色調(diào)值,因?yàn)樵谶@里它們都是紅色。所以,我們可使用Y’CrCb顏色空間(OpenCV中的YUV空間的變種)來解決此問題。Y’CrCb顏色空間不僅能將顏色和亮度分開,而且對于通常的皮膚顏色,其取值只有一種。注意,實(shí)際上對于大多數(shù)相機(jī)而言,其圖像和視頻在轉(zhuǎn)換成RGB前都使用某種YUV類型作為顏色空間,所以在很多情形下可直接得到Y(jié)UV圖像,無須自己轉(zhuǎn)換。
由于我們想獲得像卡通畫一樣的外星人模式,可對圖像進(jìn)行卡通化之后再用外星人濾波器。換言之,可使用由雙邊濾波器產(chǎn)生的縮小顏色圖像和全尺寸的邊緣掩碼。皮膚檢測通常在低分辨率下工作較好,因?yàn)樗c分析高分辨率像素的近鄰的平均值等價(或者可看作是用低頻信號代替高頻噪聲信號)。接下來的工作是在對圖像進(jìn)行縮放后進(jìn)行的,其縮放大小與用雙邊濾波器處理圖像時一樣(即只取圖像一半的寬度和高度)。下面先將繪畫圖像轉(zhuǎn)換為YUV:

我們還需要縮小邊緣掩碼,使其與繪畫圖像的比例相同。當(dāng)存儲一幅單獨(dú)的掩碼圖像時,若用OpenCV的floodFill()函數(shù)會遇到困難,即掩碼圖像應(yīng)在整個圖像周圍用1個像素作邊界,若輸入圖像大小為W×H個像素,則單獨(dú)的掩碼圖像大小為(W運(yùn)算符2)×(H運(yùn)算符2)個像素。但floodFill()函數(shù)也允許初始化邊緣掩碼來確保漫水填充算法不會越界。使用這一特性,可防止漫水填充的區(qū)域擴(kuò)展到人臉外面。因此,需要提供兩幅掩碼圖像:一幅的邊緣掩碼大小為W×H,另一幅則因?yàn)榘藞D像的邊界,所以大小為(W運(yùn)算符2)×(H運(yùn)算符2),邊緣掩碼相同。可讓多個cv::Mat對象(或頭部)引用同一數(shù)據(jù),或者甚至可讓一個cv::Mat對象引用另一個cv::Mat圖像的區(qū)域。因此,無須分配兩個分離的圖像,然后復(fù)制邊緣掩碼給它們,只需分配一個包含邊界的掩碼圖像并創(chuàng)建一個額外的大小為W×H的cv::Mat頭部(這僅是在沒有邊界的情況下引用漫水填充掩碼中的感興趣區(qū)域)。換句話說,僅僅只有一個(W運(yùn)算符2)×(H運(yùn)算符2)大小的像素?cái)?shù)組,但有兩個cv::Mat對象,其中一個引用整個(W運(yùn)算符2)×(H運(yùn)算符2)大小的圖像,另一個引用圖像中間大小為W×H的區(qū)域:

整個邊緣掩碼有強(qiáng)邊緣也有弱邊緣(如下圖的左圖所示),但我們只想要強(qiáng)邊緣,所以將采用二值化閾值法來過濾(效果見下圖的中圖)。為了在邊緣之間加入一些間隙,我們將結(jié)合形態(tài)算子dilate()和erode()來消除一些間隙(也稱為關(guān)閉算子),結(jié)果見下圖的右圖:

我們可以在下圖中看到應(yīng)用閾值化和形態(tài)算子的結(jié)果,第一幅圖是輸入邊緣圖,第二幅是經(jīng)過閾值化濾波器得到的圖像,最后一幅是經(jīng)過膨脹和侵蝕形態(tài)濾波器的圖像:

如前所述,我們希望對臉部周圍的許多像素點(diǎn)使用漫水填充算法,從而確保包含了整個人臉圖像的各種顏色和色調(diào)。我們選擇鼻子、臉頰和前額周圍的六個點(diǎn),如下面屏幕截圖的左側(cè)所示。注意,這些值取決于前面繪制的臉部輪廓:

現(xiàn)在,僅需要為漫水填充找到一些好的下界和上界。注意,漫水填充算法基于Y’CrCb顏色空間,因此基本上可以決定亮度、紅色分量、藍(lán)色分量變化多少。我們希望允許包括陰影、高亮、反射在內(nèi)的亮度變化較大,但不希望顏色變化很大:

調(diào)用floodFill()函數(shù)時,除了存儲外部掩碼需要指定參數(shù)FLOODFILL_MASK_ONLY外,其他參數(shù)默認(rèn):

下圖左邊有六個漫水填充的位置(見小圓圈),右邊圖像顯示生成的外部掩碼,其中皮膚為灰色,邊緣為白色。注意右圖已針對本書進(jìn)行了修改,以便使皮膚像素(值為1)清晰可見:

圖像變量mask(上面的右圖為它對應(yīng)的圖像)包含以下的值:
●值為255的邊緣像素
●值為1的皮膚像素
●其余值為0的像素
其間,變量edgeMask僅包含邊緣像素(值為255)。因此為了得到皮膚像素,可從變量中移除邊緣:

變量mask現(xiàn)在僅包含值為1的皮膚像素和值為0的非皮膚像素。為了改變原圖的皮膚顏色和亮度,可使用帶有皮膚掩碼的cv::add()函數(shù)來增加原始BGR圖像中的綠色成分:

下圖展示了左邊的原圖和右邊最終的外星人卡通圖,其中臉部至少有六個部分是綠色的了!

請注意,我們已經(jīng)使皮膚看起來更綠,但也更亮(看起來像一個在黑暗中發(fā)光的外星人)。如果你只想改變膚色而不使它更亮,可以使用其他顏色更改方法,例如將綠色分量加到70,同時紅色和藍(lán)色分量減少70,或者使用cvtColor(src,dst,"CV_BGR2HSV_FULL")將圖像轉(zhuǎn)換成HSV顏色空間,并調(diào)整色度和飽和度。
降低素描圖像的隨機(jī)椒鹽噪聲
大多數(shù)智能手機(jī)的微型相機(jī)、樹莓派相機(jī)模塊和一些攝像頭都有明顯的圖像噪聲。這通常可以接受,但對于5×5的Laplacian邊緣濾波器則影響很大。邊緣掩碼(素描模式顯示)經(jīng)常會有很多黑色小斑點(diǎn),它們被稱為椒鹽噪聲,由白色背景上相鄰的幾個黑色像素組成。我們已經(jīng)在使用中值濾波器了,通常強(qiáng)度足以去除椒鹽噪聲,但現(xiàn)有情況下則可能不夠強(qiáng)。因?yàn)檫吘壯诖a大多為帶著一些黑色邊緣(值為0)的純白色背景(值為255)和噪點(diǎn)(值也為0)。我們可使用標(biāo)定的閉形態(tài)算子,但那會消除很多邊緣。因此,本項(xiàng)目采用一個自定義濾波器,用于刪除被白色像素完全包圍的小黑色區(qū)域像素。這樣可以消除很多噪聲,同時對實(shí)際的邊緣影響不大。
我們將掃描圖像中的黑色像素,在每個黑色像素處,我們將檢查它周圍5×5正方形區(qū)域的邊界像素是否為白色,如果它們都為白色,則說明有一個黑色噪聲小島,可用白色像素來填充整個塊以去除黑色小島。為了簡化5×5濾波器,可忽略掉圖像周圍邊框的兩個像素,并保持其原樣。
下圖左邊的原始圖像來自Android平板電腦,中間圖像為素描模式,帶有椒鹽噪聲的小黑點(diǎn),右圖顯示了使用上述方法刪除椒鹽噪聲的結(jié)果,皮膚看起來干凈了很多:

為方便起見,我們封裝了名為removePepperNoise()的函數(shù)來處理圖像,其代碼如下:


就這樣了!反復(fù)測試你的應(yīng)用程序,直到準(zhǔn)備好移植到嵌入式設(shè)備!
- Instant Vert.x
- IBM Lotus Notes 8.5 User Guide: LITE
- SolidWorks2014基礎(chǔ)實(shí)例教程
- Cinema 4D電商美工與視覺設(shè)計(jì)案例教程(培訓(xùn)教材版)
- Quickstart Apache Axis2
- Python Testing: Beginner's Guide
- Liferay Portal Systems Development
- Photoshop CS6中文版基礎(chǔ)與實(shí)例教程(第6版)
- PKPM 2010結(jié)構(gòu)分析從入門到精通
- Unreal Development Kit Beginner's Guide
- WordPress MU 2.8: Beginner's Guide
- Apache CXF Web Service Development
- 中文版Flash CC實(shí)例教程
- 案例學(xué):Photoshop電商美工設(shè)計(jì)
- Photoshop CC中文版案例培訓(xùn)教程