偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

Android人臉檢測(cè)介紹

移動(dòng)開(kāi)發(fā) Android
自從Play Services 8.1中引入了Vision開(kāi)發(fā)庫(kù),開(kāi)發(fā)者可以方便地對(duì)視頻或圖像進(jìn)行人臉定位。只要有一張包含了人臉信息的圖片,你就可以收集每一張圖片上的人臉信息,例如人臉的位置、是否微笑、睜眼或者閉眼和他們具體的面部特征。這篇教程通過(guò)人臉檢測(cè)API對(duì)靜態(tài)圖片分析,識(shí)別圖片中的人物,同時(shí)對(duì)覆蓋圖形(overlaid graphics)進(jìn)行繪制。

自從Play Services 8.1中引入了Vision開(kāi)發(fā)庫(kù),開(kāi)發(fā)者可以方便地對(duì)視頻或圖像進(jìn)行人臉定位。只要有一張包含了人臉信息的圖片,你就可以收集每一張圖片上的人臉信息,例如人臉的位置、是否微笑、睜眼或者閉眼和他們具體的面部特征。

這些信息對(duì)于許多應(yīng)用來(lái)說(shuō)是非常有用的,例如一個(gè)相機(jī)應(yīng)用可以利用這些信息做到當(dāng)所有人都睜眼微笑的時(shí)候拍照,或者利用它增加一些搞笑效果,例如給照片中的人頭上添加一個(gè)獨(dú)角獸的角。不過(guò)大家要注意的是,這只能用來(lái)做人臉檢測(cè),而不是人臉識(shí)別。我們只能利用它檢測(cè)到人臉信息,但是不能通過(guò)它判斷兩張照片上的是否是同一個(gè)人。

這篇教程通過(guò)人臉檢測(cè)API對(duì)靜態(tài)圖片分析,識(shí)別圖片中的人物,同時(shí)對(duì)覆蓋圖形(overlaid graphics)進(jìn)行繪制。所有教程使用的代碼可以在GitHub上找到。 

 

 

 

1、項(xiàng)目配置

首先,為了將Vision庫(kù)添加到你的工程,你需要導(dǎo)入Play Services 8.1或者更高的版本進(jìn)入你的工程。本教程只導(dǎo)入Play Services Vision庫(kù)。打開(kāi)你工程中的build.gradle文件然后添加以下的編譯依賴節(jié)點(diǎn)代碼。

  1. compile 'com.google.android.gms:play-services-vision:8.1.0' 

當(dāng)你已經(jīng)在工程中包含了Play Services,就可以關(guān)閉工程中的build.gradle文件,然后打開(kāi) AndroidManifest.xml文件。在你的manifest文件中加入下列數(shù)據(jù)定義人臉檢測(cè)的依賴項(xiàng)。讓Vision庫(kù)知道你將會(huì)在應(yīng)用中使用它。

  1. <meta-data android:name="com.google.android.gms.vision.DEPENDENCIES"android:value="face"/> 

一旦完成了AndroidManifest.xml的配置,你就可以關(guān)閉這個(gè)文件。下一步,你需要?jiǎng)?chuàng)建一個(gè)新的類文件FaceOverlayView.java。這個(gè)類繼承自View類,用來(lái)進(jìn)行人臉檢測(cè)邏輯、顯示經(jīng)過(guò)分析的圖像和在圖像上繪制信息來(lái)說(shuō)明觀點(diǎn)等功能。

現(xiàn)在,我們開(kāi)始增加成員變量并實(shí)現(xiàn)構(gòu)造函數(shù)。這個(gè)Bitmap(位圖)對(duì)象用來(lái)存儲(chǔ)將要被分析的位圖數(shù)據(jù),SparseArray數(shù)組用來(lái)存儲(chǔ)在圖像中發(fā)現(xiàn)的人臉信息。

  1. public class FaceOverlayView extends View { 
  2. private Bitmap mBitmap; 
  3. private SparseArray&lt;Face&gt; mFaces; 
  4. public FaceOverlayView(Context context) { 
  5. this(context, null); 
  6. public FaceOverlayView(Context context, AttributeSet attrs) { 
  7. this(context, attrs, 0); 
  8. public FaceOverlayView(Context context, AttributeSet attrs, int defStyleAttr) { 
  9. super(context, attrs, defStyleAttr); 
  10.  

然后,我們?cè)贔aceOverlayView類中增加一個(gè)setBitmap(Bitmap bitmap)函數(shù),現(xiàn)在我們只通過(guò)這個(gè)函數(shù)存儲(chǔ)位圖對(duì)象,一會(huì)將用這個(gè)方法來(lái)分析位圖數(shù)據(jù)。

  1. public void setBitmap( Bitmap bitmap ) { 
  2. mBitmap = bitmap; 
  3.  

接下來(lái),我們需要一張位圖圖片。我已經(jīng)在GitHub上的示例工程中添加了一張,當(dāng)然你可以使用任何一張你喜歡的圖片,然后看看它到底可不可行。當(dāng)你選好圖片后,把它放到res/raw目錄下。本教程假定圖片的名字叫face.jpg。

當(dāng)你把圖片放到res/raw目錄后,打開(kāi)res/layout/activity_main.xml文件。在這個(gè)布局文件中引用一個(gè)FaceOverlayView對(duì)象,使它在MainActivity中顯示出來(lái)。

  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <com.tutsplus.facedetection.FaceOverlayView 
  3. xmlns:android="http://schemas.android.com/apk/res/android" 
  4. android:id="@+id/face_overlay" 
  5. android:layout_width="match_parent" 
  6. android:layout_height="match_parent" />  

定義完布局文件后,打開(kāi)MainActivity然后在onCreate()函數(shù)中引用一個(gè)FaceOverlayView的實(shí)例。通過(guò)輸入流從raw文件夾中讀入face.jpg并轉(zhuǎn)成位圖數(shù)據(jù)。在擁有了位圖數(shù)據(jù)之后,你就可以通過(guò)調(diào)用FaceOverlayView的setBitmap方法在自定義視圖中設(shè)置位圖了。

  1. public class MainActivity extends AppCompatActivity { 
  2. private FaceOverlayView mFaceOverlayView; 
  3. @Override 
  4. protected void onCreate(Bundle savedInstanceState) { 
  5. super.onCreate(savedInstanceState); 
  6. setContentView(R.layout.activity_main); 
  7. mFaceOverlayView = (FaceOverlayView) findViewById( R.id.face_overlay ); 
  8. InputStream stream = getResources().openRawResource( R.raw.face ); 
  9. Bitmap bitmap = BitmapFactory.decodeStream(stream); 
  10. mFaceOverlayView.setBitmap(bitmap); 
  11.  

2、檢測(cè)人臉

現(xiàn)在你的工程已經(jīng)設(shè)置好了,是時(shí)候來(lái)開(kāi)始檢測(cè)人臉了。在setBitmap( Bitmap bitmap )方法中定義一個(gè)FaceDetector對(duì)象。我們可以通過(guò)用FaceDetector中的構(gòu)造器來(lái)實(shí)現(xiàn),通過(guò)FaceDetector.Builder你可以定義多個(gè)參數(shù)來(lái)控制人臉檢測(cè)的速度和FaceDetector生成的其他數(shù)據(jù)。

具體的設(shè)置取決于你的應(yīng)用程序的用途。如果開(kāi)啟了面部特征搜索,那么人臉檢測(cè)的速度回變得很慢。在大多數(shù)程序設(shè)計(jì)中,每一件事都有它的優(yōu)缺點(diǎn)。如果想要了解關(guān)于FaceDetector.Builder的更多信息,你可以通過(guò)查找安卓開(kāi)發(fā)者網(wǎng)站的官網(wǎng)文檔獲得。

  1. FaceDetector detector = new FaceDetector.Builder( getContext() ) 
  2. .setTrackingEnabled(false
  3. .setLandmarkType(FaceDetector.ALL_LANDMARKS) 
  4. .setMode(FaceDetector.FAST_MODE) 
  5. .build();  

你需要檢查FaceDetector是否是可操作的。每當(dāng)用戶***次在設(shè)備上使用人臉檢測(cè),Play Services服務(wù)需要加載一組小型本地庫(kù)去處理應(yīng)用程序的請(qǐng)求。雖然這些工作一般在應(yīng)用程序啟動(dòng)之前就完成了,但是做好失敗處理同樣是必要的。

如果FaceDetector是可操作的,那么你需要將位圖數(shù)據(jù)轉(zhuǎn)化成Frame對(duì)象,并通過(guò)detect函數(shù)傳入用來(lái)做人臉數(shù)據(jù)分析。當(dāng)完成數(shù)據(jù)分析后,你需要釋放探測(cè)器,防止內(nèi)存泄露。***調(diào)用invalidate()函數(shù)來(lái)觸發(fā)視圖刷新。

  1. if (!detector.isOperational()) { 
  2. //Handle contingency 
  3. else { 
  4. Frame frame = new Frame.Builder().setBitmap(bitmap).build(); 
  5. mFaces = detector.detect(frame); 
  6. detector.release(); 
  7. invalidate();  

現(xiàn)在你已經(jīng)在圖片中發(fā)現(xiàn)了人臉信息,并可以使用了。例如,你可以沿著檢測(cè)出的每一張臉畫一個(gè)框。在invalidate()函數(shù)調(diào)用之后,我們可以在OnDraw(Canvas canvas)函數(shù)中添加所有必要的邏輯。我們需要確保位圖和人臉數(shù)據(jù)是有效的,在那之后畫布上畫出位圖數(shù)據(jù),然后再沿著每張臉的方位畫一個(gè)框。

因?yàn)椴煌脑O(shè)備的分辨率不同,你需要通過(guò)控制位圖的縮放尺寸來(lái)保證圖片總是能被正確顯示出來(lái)。

  1. @Override 
  2. protected void onDraw(Canvas canvas) { 
  3. super.onDraw(canvas); 
  4. if ((mBitmap != null) &amp;&amp; (mFaces != null)) { 
  5. double scale = drawBitmap(canvas); 
  6. drawFaceBox(canvas, scale); 
  7.  

drawBitmap(Canvas canvas)方法會(huì)將圖像自適應(yīng)大小的畫在畫布上,同時(shí)返回一個(gè)正確的縮放值供你使用。

  1. private double drawBitmap( Canvas canvas ) { 
  2. double viewWidth = canvas.getWidth(); 
  3. double viewHeight = canvas.getHeight(); 
  4. double imageWidth = mBitmap.getWidth(); 
  5. double imageHeight = mBitmap.getHeight(); 
  6. double scale = Math.min( viewWidth / imageWidth, viewHeight / imageHeight ); 
  7. Rect destBounds = new Rect( 0, 0, (int) ( imageWidth * scale ), (int) ( imageHeight * scale ) ); 
  8. canvas.drawBitmap( mBitmap, null, destBounds, null ); 
  9. return scale; 
  10.  

drawFaceBox(Canvas canvas, double scale)方法會(huì)更有趣,被檢測(cè)到人臉數(shù)據(jù)以位置信息的方式存儲(chǔ)到mFaces中,這個(gè)方法將基于這些位置數(shù)據(jù)中的寬、高在檢測(cè)到的人臉位置畫一個(gè)綠色的矩形框。

你需要定義自己的繪畫對(duì)象,然后從你的SparseArray數(shù)組中循環(huán)的找出位置、高度和寬度信息,再利用這些信息在畫布上畫出矩形。

  1. private void drawFaceBox(Canvas canvas, double scale) { 
  2. //paint should be defined as a member variable rather than 
  3. //being created on each onDraw request, but left here for 
  4. //emphasis. 
  5. Paint paint = new Paint(); 
  6. paint.setColor(Color.GREEN); 
  7. paint.setStyle(Paint.Style.STROKE); 
  8. paint.setStrokeWidth(5); 
  9. float left = 0; 
  10. float top = 0; 
  11. float right = 0; 
  12. float bottom = 0; 
  13. forint i = 0; i &lt; mFaces.size(); i++ ) { 
  14. Face face = mFaces.valueAt(i); 
  15. left = (float) ( face.getPosition().x * scale ); 
  16. top = (float) ( face.getPosition().y * scale ); 
  17. right = (float) scale * ( face.getPosition().x + face.getWidth() ); 
  18. bottom = (float) scale * ( face.getPosition().y + face.getHeight() ); 
  19. canvas.drawRect( lefttopright, bottom, paint ); 
  20.  

這時(shí)運(yùn)行你的應(yīng)用程序,你會(huì)發(fā)現(xiàn)每張被檢測(cè)到的人臉都被矩形包圍著。值得注意的是,現(xiàn)在我們所使用的人臉檢測(cè)API版本非常新,所以它不一定能檢測(cè)到所有的人臉。你可以通過(guò)修改FaceDetector.Builder中的配置,使它獲得到更多的信息,但是我不能保證這一定會(huì)起作用。 

 

 

 

3、理解面部特征

面部特征指的是臉上的一些特殊點(diǎn)。人臉檢測(cè)API不是依靠面部特征來(lái)檢測(cè)一張人臉,而是在檢測(cè)到人臉之后才能檢測(cè)面部特征。這就是為什么檢測(cè)面部特征是一個(gè)可選的設(shè)置,我們可以通過(guò)FaceDetector.Builder開(kāi)啟。

你可以把這些面部特征信息做為一個(gè)附加的信息來(lái)源,例如需找模特的眼睛在哪里,這樣就可以在應(yīng)用中做相應(yīng)的處理了。有十二種面部特征是可能被檢測(cè)出來(lái)的: 左右眼 左右耳朵 左右耳垂 鼻子 左右臉頰 左右嘴角 嘴

面部特征的檢測(cè)取決于檢測(cè)的角度。例如,有人側(cè)對(duì)著的話,那么只能檢測(cè)到他的一個(gè)眼睛,這意味著另一只眼睛不會(huì)被檢測(cè)到。下表概述了哪些面部特征應(yīng)該檢測(cè)到(Y是基于臉部的歐拉角(左或右))。

歐拉角 Y 可見(jiàn)的標(biāo)志
< -36° 左眼、左嘴角、左耳朵、鼻子、左臉頰
-36° to -12° 左嘴角、鼻子、下嘴角、右眼、左眼、左臉頰、左耳垂
-12° to 12° 右眼、左眼、鼻子、左臉頰、右臉頰、左嘴角、右嘴角、下嘴角
12° to 36° 右嘴角、鼻子、下嘴角、左眼、右眼、右臉頰、右耳垂
> 36° 右眼、右嘴角、右耳朵、鼻子、右臉頰
 

如果在人臉檢測(cè)中,你已經(jīng)開(kāi)啟了面部特征檢測(cè),那么你可以很容易地使用面部特征信息。你只需要調(diào)用getLandmarks()函數(shù)獲得一個(gè)面部特征列表就可以了,你可以直接使用它。

在本教程中,你可以利用一個(gè)新的函數(shù)drawFaceLandmarks(Canvas canvas, double scale)在人臉檢測(cè)中檢測(cè)出的每一個(gè)面部特征上畫一個(gè)小圓圈,在onDraw(canvas canvas)函數(shù)中,用drawFaceLandmarks替換drawFaceBox。該方法以每個(gè)面部特征點(diǎn)的位置為中心,自適應(yīng)位圖大小,用一個(gè)圓圈把面部特征點(diǎn)圈起來(lái)。

  1. private void drawFaceLandmarks( Canvas canvas, double scale ) { 
  2. Paint paint = new Paint(); 
  3. paint.setColor( Color.GREEN ); 
  4. paint.setStyle( Paint.Style.STROKE ); 
  5. paint.setStrokeWidth( 5 ); 
  6. forint i = 0; i &lt; mFaces.size(); i++ ) { 
  7. Face face = mFaces.valueAt(i); 
  8. for ( Landmark landmark : face.getLandmarks() ) { 
  9. int cx = (int) ( landmark.getPosition().x * scale ); 
  10. int cy = (int) ( landmark.getPosition().y * scale ); 
  11. canvas.drawCircle( cx, cy, 10, paint ); 

 

調(diào)用該方法之后,您應(yīng)該看到如下圖所示的畫面,面部特征點(diǎn)被綠色的小圓圈圈起來(lái)。 

 

 

 

4、額外的面部數(shù)據(jù)

人臉的位置和面部特征信息是非常有用的,除此之外,我們?cè)趹?yīng)用中還可以通過(guò)Face的內(nèi)置方法獲得人臉檢測(cè)的更多信息。通過(guò)getIsSmilingProbability()、getIsLeftEyeOpenProbability()和getIsRightEyeOpenProbability()方法的返回值(范圍從0.0到1.0)我們可以判斷人的左右眼是否睜開(kāi),是否微笑。當(dāng)數(shù)值越接近于1.0那么可能性也就越大。

你也可以通過(guò)人臉檢測(cè)獲得Y和Z軸的歐拉值,Z軸的歐拉值是一定會(huì)返回的,如果你想接收到X軸的值,那么你必須在檢測(cè)時(shí)使用一個(gè)準(zhǔn)確的模式,下面是一個(gè)如何或者這些值的例子。

  1. private void logFaceData() { 
  2. float smilingProbability; 
  3. float leftEyeOpenProbability; 
  4. float rightEyeOpenProbability; 
  5. float eulerY; 
  6. float eulerZ; 
  7. forint i = 0; i &lt; mFaces.size(); i++ ) { 
  8. Face face = mFaces.valueAt(i); 
  9. smilingProbability = face.getIsSmilingProbability(); 
  10. leftEyeOpenProbability = face.getIsLeftEyeOpenProbability(); 
  11. rightEyeOpenProbability = face.getIsRightEyeOpenProbability(); 
  12. eulerY = face.getEulerY(); 
  13. eulerZ = face.getEulerZ(); 
  14. Log.e( "Tuts+ Face Detection""Smiling: " + smilingProbability ); 
  15. Log.e( "Tuts+ Face Detection""Left eye open: " + leftEyeOpenProbability ); 
  16. Log.e( "Tuts+ Face Detection""Right eye open: " + rightEyeOpenProbability ); 
  17. Log.e( "Tuts+ Face Detection""Euler Y: " + eulerY ); 
  18. Log.e( "Tuts+ Face Detection""Euler Z: " + eulerZ ); 

 

結(jié)論

在本教程中,你已經(jīng)學(xué)會(huì)了Play Services Vision庫(kù)中的一個(gè)主要組件:人臉檢測(cè)。你現(xiàn)在知道了如何在一張靜態(tài)圖片中檢測(cè)到人臉、如何收集人臉的信息并找到每個(gè)人臉的重要面部特征。

用你學(xué)到的這些東西,可以給自己的圖像應(yīng)用增加一個(gè)有意思的特性,在視頻中跟蹤人臉,或者做任何你能想到的事情。 

責(zé)任編輯:龐桂玉 來(lái)源: 安卓開(kāi)發(fā)精選
相關(guān)推薦

2012-04-30 20:24:43

Android API

2020-12-30 08:20:04

人臉檢測(cè)Retina FacemobileNet

2024-06-12 12:57:12

2024-04-15 00:00:01

GoogleAndroid機(jī)器學(xué)習(xí)

2024-07-18 00:00:25

PyTorch神經(jīng)網(wǎng)絡(luò)

2018-01-23 09:17:22

Python人臉識(shí)別

2019-03-27 15:10:02

開(kāi)源人臉檢測(cè)庫(kù)

2018-05-08 14:25:22

Pythondlib人臉檢測(cè)

2015-02-10 10:08:59

JavaScript

2018-05-02 15:41:27

JavaScript人臉檢測(cè)圖像識(shí)別

2024-04-03 09:48:28

人臉檢測(cè)識(shí)別JS開(kāi)源

2018-07-10 15:50:29

2022-04-05 20:54:21

OpenCVPython人臉檢測(cè)

2020-11-11 07:25:08

人臉識(shí)別AI人工智能

2013-08-26 10:53:26

人臉檢測(cè)API

2020-11-02 11:24:52

算法人臉識(shí)別技術(shù)

2018-03-12 16:42:11

華為云

2023-08-16 08:07:36

2014-04-15 17:03:00

2012-12-26 13:41:08

Android開(kāi)發(fā)dispatchTou
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)