Android相機預覽,指定區域顯示預覽框,在區域內出現人臉進行人臉識別,並抓拍人臉照片存在本地

效果圖:html

第一種是使用camerax進行預覽,android camerax預覽官方文檔,主要經過imageAnalysis,抓幀進行圖片處理,而後經過android自帶的圖片人臉識別FaceDetector判斷是否有人臉,有人臉保存當前抓拍的照片:java

val file = File(filesDir, "head_tmp.png")
            val create = Observable.create<File> { emitter ->
                val intArray = IntArray(2)
                iv_scan.getLocationInWindow(intArray)
                val createBitmap = Bitmap.createBitmap(
                    bitmap, intArray[0], intArray[1], iv_scan.width, iv_scan.height
                )
                //必須是565才能識別
                val bitmap1: Bitmap = createBitmap.copy(Bitmap.Config.RGB_565, true)
                val faceDetector = FaceDetector(bitmap1.width, bitmap1.height, 1)
                val array = arrayOfNulls<FaceDetector.Face>(1)
                val faces = faceDetector.findFaces(bitmap1, array)
                if (faces > 0) {
                    Log.e(TAG, "檢測到臉")
                    val fos = FileOutputStream(file.path)
                    createBitmap.compress(Bitmap.CompressFormat.PNG, 100, fos)
                    fos.flush()
                    fos.close()
                    emitter.onNext(file)
                } else {
                    Log.e(TAG, "未檢測到臉")
                    emitter.onError(Throwable("未檢測到臉"))
                }

            }
            var disposable: Disposable? = null
            val observer = object : Observer<File> {
                override fun onNext(t: File) {
                    disposable?.dispose()
                    isOne = false
                    setResult(Activity.RESULT_OK)
                    finish()
                }

                override fun onError(e: Throwable) {
                    isOne = true
                }

                override fun onComplete() {

                }

                override fun onSubscribe(d: Disposable) {
                    disposable = d
                }
            }
            create.subscribeOn(Schedulers.computation())//指定被觀察者線程
                .observeOn(AndroidSchedulers.mainThread())//指定觀察者線程
                .subscribe(observer)

第二種使用了免費的虹軟識別人臉識別,主要判斷指定識別框的rect和虹軟人臉識別框的rect,比較兩個rect,是否在它的範圍內,若是在抓拍人臉:android

if (drawInfoList.size > 0) {
                    for (i in drawInfoList.indices) {
                        val rect: Rect = drawInfoList[i].rect
                        val rect1 = Rect()
                        iv_scan.getGlobalVisibleRect(rect1)
                        if (rect1.contains(rect)) {
                            //爲了美觀,擴大rect截取註冊圖
                            val cropRect: Rect =
                                CommUtils.getBestRect(
                                    previewSize!!.width, previewSize!!.height, faceInfoList[i].rect
                                )
                            cropRect.left = cropRect.left and 3.inv()
                            cropRect.top = cropRect.top and 3.inv()
                            cropRect.right = cropRect.right and 3.inv()
                            cropRect.bottom = cropRect.bottom and 3.inv()

                            headBmp = CommUtils.getHeadImage(
                                nv21,
                                previewSize!!.width,
                                previewSize!!.height,
                                faceInfoList[i].orient,
                                cropRect,
                                ArcSoftImageFormat.NV21
                            )
                            headBmp?.apply {
                                cropBitmap(this)
                            }
                            break
                        }
                    }
                }

demo:https://github.com/withyi9223/facesbgit

相關文章
相關標籤/搜索