建立一個Android應用程式以使用Firebase ML識別面部輪廓
Firebase ML Kit 是一組本地和基於雲的API,用於向移動應用程式新增機器學習功能,最近已得到增強,可支援面部輪廓檢測。由於這個強大的功能,您不再需要在檢測面部時將自己限制為近似矩形。相反,您可以使用大量座標來準確描述檢測到的面部和麵部標誌的形狀,例如眼睛,嘴脣和眉毛。
這使您可以輕鬆建立人工智慧應用程式,可以執行復雜的計算機視覺相關任務,如交換面部,識別情緒或應用數字化妝。
在本教程中,我將向您展示如何使用ML Kit的面部輪廓檢測功能來建立可以突出顯示照片中面部的Android應用程式。
先決條件
要充分利用本教程,您必須具有以下許可權:
- 最新版本的 Android Studio
- 執行Android API級別23或更高級別的裝置
1.配置專案
由於ML Kit是Firebase平臺的一部分,因此您需要一個Firebase專案才能在Android Studio專案中使用它。要建立一個,請轉到“ 工具”>“Firebase” 以啟動Firebase助手。
接下來,開啟“ 分析” 部分,然後按“ 連線” 按鈕。在彈出的對話方塊中,鍵入新Firebase專案的名稱,選擇您所在的國家/地區,然後按“ 連線” 按鈕。

連線到Firebase對話方塊
成功連線後,按“ 將分析新增到應用程式” 按鈕,以便助理可以在Android Studio專案中進行所有必要的與Firebase相關的配置更改。
此時,如果您開啟 app
模組的 build.gradle 檔案以及其他更改,您應該看到其中 implementation
存在以下依賴項:
implementation 'com.google.firebase:firebase-core:16.0.4'
為了能夠使用ML Kit的面部輪廓檢測功能,您還需要兩個依賴項:一個用於最新版本的ML Vision庫,另一個用於ML Vision面部模型。以下是新增它們的方法:
implementation 'com.google.firebase:firebase-ml-vision:18.0.1' implementation 'com.google.firebase:firebase-ml-vision-face-model:17.0.2'
在本教程中,您將使用遠端影象。為便於下載和顯示此類影象,請為 Picasso 庫新增依賴項:
implementation 'com.squareup.picasso:picasso:2.71828'
ML Kit的面部輪廓檢測始終在使用者裝置上本地執行。預設情況下,在使用者首次開啟應用程式時會自動下載進行面部輪廓檢測的機器學習模型。但是,為了改善使用者體驗,我建議您在使用者安裝應用後立即開始下載。為此,請將以下 <meta-data> 標記新增到AndroidManifest.xml 檔案中:
<meta-data android:name="com.google.firebase.ml.vision.DEPENDENCIES" android:value="face" />
2.建立佈局
您將在應用程式的佈局中需要三個小部件:EditText 使用者可以在其中鍵入線上照片的URL的ImageView 小部件,用於顯示照片的Button 小部件以及用於啟動面部輪廓檢測過程的 小部件。此外,您還需要一個 RelativeLayout 小部件來定位三個小部件。因此,將以下程式碼新增到主活動的佈局XML檔案中:
<``RelativeLayout` `xmlns:android``=``"[http://schemas.android.com/apk/res/android](http://schemas.android.com/apk/res/android)"` `android:layout_width``=``"match_parent"` `android:layout_height``=``"match_parent"` `android:padding``=``"16dp"``>` `<``EditText` `android:layout_width``=``"match_parent"` `android:layout_height``=``"wrap_content"` `android:hint``=``"Image URL"` `android:imeOptions``=``"actionGo"` `android:inputType``=``"textUri"` `android:id``=``"@+id/user_input"` `/>` `<``Button` `android:layout_width``=``"match_parent"` `android:layout_height``=``"wrap_content"` `android:text``=``"Detect contours"` `android:layout_alignParentBottom``=``"true"` `android:id``=``"@+id/action_button"` `/>` `<``ImageView` `android:layout_width``=``"match_parent"` `android:layout_height``=``"match_parent"` `android:id``=``"@+id/photo"` `android:layout_below``=``"@+id/user_input"` `android:layout_above``=``"@id/action_button"` `android:scaleType``=``"centerCrop"``/>` `</``RelativeLayout``>`
3.下載和顯示影象
使用Picasso庫,下載和顯示遠端影象只需要呼叫兩種方法。首先,呼叫load() 方法以指定要下載的影象的URL,然後呼叫該into() 方法以指定ImageView 要在其中顯示下載影象的視窗小部件。
當然,只有在使用者輸入URL後才能呼叫這兩種方法。因此,請確保在OnEditorActionListener 附加到EditText 上一步中建立的視窗小部件的物件中呼叫它們。以下程式碼顯示瞭如何執行此操作:
user_input.setOnEditorActionListener { _, action, _ -> if(action == EditorInfo.IME_ACTION_GO) { Picasso.get() .load(user_input.text.toString()) .into(photo) true } false }
立即執行應用程式並嘗試鍵入有效的影象URL以確保其正常工作。

應用程式顯示照片
4.建立面部輪廓檢測器
您將在附加到Button 佈局視窗小部件的單擊事件處理程式中執行所有面部輪廓檢測操作。因此,在繼續之前,請將以下程式碼新增到您的活動:
action_button.setOnClickListener { // Rest of the code goes here }
為了能夠處理面部資料,您現在必須建立一個 FirebaseVisionFaceDetector 物件。但是,由於預設情況下它不會檢測面的輪廓,因此您還必須建立一個 FirebaseVisionFaceDetectorOptions 可以對其進行配置的物件。
要建立有效的選項物件,必須遵循構建器模式。因此,建立 FirebaseVisionFaceDetectorOptions.Builder 類的例項,呼叫其 setContourMode() 方法 ,並將 ALL_CONTOURS 常量傳遞給它,以指定您要檢測影象中存在的所有面的輪廓。
然後呼叫build() 構建器的方法來生成選項物件。
val detectorOptions = FirebaseVisionFaceDetectorOptions.Builder() .setContourMode( FirebaseVisionFaceDetectorOptions.ALL_CONTOURS ).build()
您現在可以將選項物件傳遞給getVisionFaceDetector() ML Kit FirebaseVision 類的方法來建立面部輪廓檢測器。
val detector = FirebaseVision .getInstance() .getVisionFaceDetector(detectorOptions)
5.收集座標資料
面部輪廓檢測器無法直接使用ImageView 視窗小部件顯示的照片 。相反,它希望您將FirebaseVisionImage 物件傳遞給它。要生成此類物件,必須將照片轉換為Bitmap 物件。以下程式碼顯示瞭如何執行此操作:
val visionImage = FirebaseVisionImage.fromBitmap( (photo.drawable as BitmapDrawable).bitmap )
您現在可以呼叫detectInImage() 檢測器的方法來檢測照片中存在的所有面部的輪廓。該方法以非同步方式執行,並在FirebaseVisionFace 成功完成後返回物件列表 。
detector.detectInImage(visionImage).addOnSuccessListener { // More code here }
在on-success偵聽器中,您可以使用it 隱式變數來遍歷檢測到的面部列表。每個面都有大量與之相關的輪廓點。要訪問這些點,您必須呼叫該getContour() 方法。該方法可以返回幾個不同面部標誌的輪廓點。例如,如果將常量傳遞 LEFT_EYE 給它,它將返回左眼輪廓所需的點。同樣,如果你傳遞UPPER_LIP_TOP 給它,你將得到與上脣頂邊相關的點。
在本教程中,我們將使用FACE 常量,因為我們想要突出顯示面部本身。以下程式碼顯示如何列印沿每個面邊緣存在的所有點的X和Y座標:
it.forEach { val contour = it.getContour(FirebaseVisionFaceContour.FACE) contour.points.forEach { println("Point at ${it.x}, ${it.y}") } // More code here }
如果您現在嘗試使用該應用程式並指定其中至少有一個面部的影象,您應該在 Logcat 視窗中看到類似的 內容 :

Logcat視窗顯示輪廓點的座標
6.在臉部周圍繪製路徑
要突出顯示檢測到的面部,讓我們使用輪廓點簡單地繪製它們周圍的路徑。為了能夠繪製這樣的路徑,您需要一個 ImageView
小部件點陣圖的可變副本。通過呼叫其 copy()
方法建立一個。
val mutableBitmap = (photo.drawable as BitmapDrawable).bitmap.copy( Bitmap.Config.ARGB_8888, true )
通過直接修改點陣圖的畫素來繪製路徑可能很困難。因此,通過將它傳遞給Canvas 類的建構函式,為它建立一個新的2D畫布 。
此外,建立一個Paint 物件以指定要在畫布上繪製的畫素的顏色。以下程式碼顯示如何建立可在其上繪製半透明紅色畫素的畫布:
val canvas = Canvas(mutableBitmap) val myPaint = Paint(Paint.ANTI_ALIAS_FLAG) myPaint.color = Color.parseColor("#99ff0000")
在畫布上繪製路徑的最簡單方法是使用Path 該類。通過使用類的直觀命名 moveTo() 和lineTo() 方法,您可以輕鬆地在畫布上繪製複雜的形狀。
現在,要繪製一個面的形狀,請呼叫該moveTo() 方法一次,並將第一個輪廓點的座標傳遞給它。通過這樣做,您可以指定路徑的開始位置。然後將所有點的座標傳遞給lineTo() 方法以實際繪製路徑。最後,呼叫close() 方法關閉路徑並填充它。
因此,新增以下程式碼:
val path = Path() path.moveTo(contour.points[0].x, contour.points[0].y) contour.points.forEach { path.lineTo(it.x, it.y) } path.close()
要渲染路徑,請將其drawPath() 與Paint物件一起傳遞給畫布的方法。
canvas.drawPath(path, myPaint)
要更新ImageView 視窗小部件以顯示修改後的點陣圖,請將點陣圖傳遞給其setImageBitmap() 方法。
photo.setImageBitmap(mutableBitmap)
如果你現在執行應用程式,你應該能夠看到它在它檢測到的所有面上繪製半透明的紅色蒙版。

應用程式突出顯示一個臉
結論
藉助ML Kit新的人臉輪廓檢測API和一點創造力,您可以輕鬆建立人工智慧應用程式,可以執行復雜的計算機視覺相關任務,如交換面部,檢測情緒或應用數字化妝。在本教程中,您學習瞭如何使用API生成的2D座標來繪製突出顯示照片中存在的面的形狀。
想學習更多Android知識,或者獲取相關資料請加入Android技術開發交流2群:935654177。本群可免費獲取Gradle,RxJava,小程式,Hybrid,移動架構,NDK,React Native,效能優化等技術教程!