前言
在很多美顏相機(jī)啊,抖音啊,都會(huì)有一些放大眼睛的效果,今天就來(lái)實(shí)現(xiàn)如何放大眼睛。
思路
1、首先使用OpenCV定位到人臉
2、根據(jù)定位到的人臉去檢測(cè)人臉關(guān)鍵點(diǎn),進(jìn)而獲取到人眼睛的位置。
3、根據(jù)眼睛位置,對(duì)眼睛進(jìn)行放大。
實(shí)現(xiàn)
定位人臉
人臉的定位追蹤,在之前文章中已經(jīng)寫(xiě)過(guò)OpenCv實(shí)現(xiàn)人臉追蹤 當(dāng)時(shí)是在xCode上寫(xiě)的,把里面的代碼移植到Android中就可以了,這個(gè)是C寫(xiě)的,所以需要移植到JNI中。這里的人臉模型,我采用的是OpenCV中提供的,當(dāng)然也可以自己去訓(xùn)練模型。
檢測(cè)人臉關(guān)鍵點(diǎn)

人臉關(guān)鍵點(diǎn)的檢測(cè),有很多三方的sdk,比如說(shuō)face++等等,都是要收費(fèi)的,face++是檢測(cè)了68個(gè)關(guān)鍵點(diǎn),這68個(gè)關(guān)鍵點(diǎn)都不是隨意分布的,都是有規(guī)律的。如下圖:
但是像face++這種,都是需要收費(fèi)的,我從GitHub上找了一個(gè)免費(fèi)的叫SeetaFaceEngine它這個(gè)里面有三個(gè)模塊:人臉檢測(cè)模塊(SeetaFace Detection)、面部特征點(diǎn)定位模塊(SeetaFace Alignment)以及人臉特征提取與比對(duì)模塊(SeetaFace Identification)。這里我用到的是SeetaFace Alignment,用來(lái)檢測(cè)人臉的關(guān)鍵點(diǎn)。
它這里面并不是定位了68個(gè)關(guān)鍵點(diǎn),而是定位了5個(gè)關(guān)鍵點(diǎn),即左眼(0)、右眼(1)、鼻子(2)、嘴巴左邊(3)、嘴巴右邊(4),這個(gè)分布也是有規(guī)律的,并不是隨便的點(diǎn)。代碼如下:將定位到的人臉,送去進(jìn)行關(guān)鍵點(diǎn)的檢測(cè)


在創(chuàng)建一個(gè)數(shù)組,將關(guān)鍵點(diǎn)數(shù)組里的值賦值給它,在傳遞給java層
放大眼睛
這里是根據(jù)網(wǎng)上論文中的一個(gè)公式實(shí)現(xiàn)的,http://www.gson.org/thesis/warping-thesis.pdf, 大概在45頁(yè)左右有個(gè)這樣的描述,以及公式,就是根據(jù)這個(gè)來(lái)實(shí)現(xiàn)的。

這個(gè)公式是什么意思呢?這個(gè)公式求出的值是采集的改變后的點(diǎn)距離眼睛中心點(diǎn)的位置,rmax表示的是最大放大的區(qū)域,r表示原來(lái)的點(diǎn)距離眼睛中心點(diǎn)的位置,a表示的是放大系數(shù),所以當(dāng)a=0的時(shí)候,公式的結(jié)果就是r,也就是沒(méi)有變化,不放大。
原理是什么呢,就是在片元著色器,把眼睛周邊的需要放大的點(diǎn)取值成對(duì)應(yīng)的眼睛內(nèi)部的點(diǎn)的值,然后把這個(gè)值的坐標(biāo)賦值給gl_FragColor,這樣就完成了眼睛的放大;
片元著色器:

效果圖
