這一個臉部識別的流程是
初始化我們的 Canvas 以及 Paint
注意:官方文件有標註 bitmap must be in 565 format.
class FaceView(context: Context, attrs: AttributeSet): View(context, attrs) {
private var paint: Paint
private var bitmap: Bitmap
private var canvas: Canvas
private val maxFaceNumbers = 25
private var numberOfFaceDetected = 0
private var faces = arrayOfNulls<FaceDetector.Face>(25)
init {
// bitmap
val width = Resources.getSystem().displayMetrics.widthPixels
bitmap = Bitmap.createBitmap(width, 800, Bitmap.Config.RGB_565)
// Canvas
canvas = Canvas(bitmap)
canvas.drawColor(Color.GRAY)
// Paint
paint = Paint()
paint.color = Color.YELLOW
paint.style = Paint.Style.STROKE
paint.strokeWidth = 4f
paint.textSize = 50f
}
}
提供一個來放入圖片的 Uri 的方法,將圖片的大小轉成和 FaceView 相同。
fun setupWithImage(uri: Uri) {
Log.e("FaceView","Setup With Uri $uri")
try {
val resolver = context.contentResolver
// must be RGB_565
val options = BitmapFactory.Options()
options.inPreferredConfig = Bitmap.Config.RGB_565
val image = BitmapFactory.decodeStream(resolver.openInputStream(uri), null, options)
// scale the bitmap
bitmap = ThumbnailUtils.extractThumbnail(image, width, height)
} catch (e: Exception) {
Log.e("setup with image","failed")
}
}
通過 FaceDetector 來進行人臉偵測,偵測結束後通過 invalidate() 來呼叫 onDraw 方法
當觸發 onDraw 方法的時候,會去看有幾張臉被識別出來,
根據雙眼的距離來計算整張臉的位置,然後在臉上畫黃色的方塊。
通過 Intent 讓使用者選取圖片
private fun takeImageFromAlbum() {
val intent = Intent()
intent.type = "image/*"
intent.action = Intent.ACTION_GET_CONTENT
startActivityForResult(intent, OPEN_PHOTO_FOLDER_REQUEST_CODE)
}
通過 intent 來接收圖片的 Uri 然後丟給 FaceView 呈現在畫面上。
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
println("onActivityResult requestCode is $requestCode")
when(requestCode){
OPEN_PHOTO_FOLDER_REQUEST_CODE -> {
val imageUri = data?.data
println("imageUri is $imageUri")
if(imageUri != null){
faceView.setupWithImage(imageUri)
} else {
Toast.makeText(this,"get image Uri failed", Toast.LENGTH_SHORT).show()
}
}
else -> {
println("no handler on ActivityResult, resultcode is $resultCode")
}
}
}
在通過剛才 FaceView 提供的 detectFace 方法進行臉部識別和畫方塊的功能。
faceView.detectFace()