3

我正在尝试使用 Android 上的 firebase MLkit 运行这个人脸检测示例我使用库CameraView而不是内置的CameraView 。运行日志中显示的代码:Faces: [],因此没有从相机中找到人脸。

您可以在 github 上查看该项目

编码:

import android.os.Bundle
import android.util.Log
import com.google.android.material.bottomnavigation.BottomNavigationView
import androidx.appcompat.app.AppCompatActivity
import android.widget.TextView
import androidx.annotation.WorkerThread
import com.otaliastudios.cameraview.CameraView
import com.otaliastudios.cameraview.Frame
import com.otaliastudios.cameraview.FrameProcessor
import com.otaliastudios.cameraview.Size
import androidx.core.view.ViewCompat.getRotation
import com.google.android.gms.tasks.OnFailureListener
import com.google.firebase.FirebaseApp
import com.google.firebase.ml.vision.FirebaseVision
import com.google.firebase.ml.vision.common.FirebaseVisionImage
import com.google.firebase.ml.vision.common.FirebaseVisionImageMetadata
import com.google.firebase.ml.vision.face.FirebaseVisionFace
import com.google.firebase.ml.vision.face.FirebaseVisionFaceContour
import com.google.firebase.ml.vision.face.FirebaseVisionFaceDetectorOptions
import com.google.firebase.ml.vision.face.FirebaseVisionFaceLandmark


class MainActivity : AppCompatActivity() {

    private lateinit var textMessage: TextView
    private lateinit var camera:CameraView
    private val onNavigationItemSelectedListener = BottomNavigationView.OnNavigationItemSelectedListener { item ->
        when (item.itemId) {
            R.id.navigation_home -> {
                textMessage.setText(R.string.title_home)
                return@OnNavigationItemSelectedListener true
            }
            R.id.navigation_dashboard -> {
                textMessage.setText(R.string.title_dashboard)
                return@OnNavigationItemSelectedListener true
            }
            R.id.navigation_notifications -> {
                textMessage.setText(R.string.title_notifications)
                return@OnNavigationItemSelectedListener true
            }
        }
        false
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val navView: BottomNavigationView = findViewById(R.id.nav_view)

        textMessage = findViewById(R.id.message)
        navView.setOnNavigationItemSelectedListener(onNavigationItemSelectedListener)

        camera = findViewById<CameraView>(R.id.camera)
        camera.setLifecycleOwner(this)

        val realTimeOpts1 = FirebaseVisionFaceDetectorOptions.Builder()
            .setContourMode(FirebaseVisionFaceDetectorOptions.ALL_LANDMARKS)
            .build()
        val realTimeOpts = FirebaseVisionFaceDetectorOptions.Builder()
            .setPerformanceMode(FirebaseVisionFaceDetectorOptions.ACCURATE)
            .setLandmarkMode(FirebaseVisionFaceDetectorOptions.ALL_LANDMARKS)
            .build()

        FirebaseApp.initializeApp(this);


        camera.addFrameProcessor { frame ->
            val data = frame.data
            val rotation = frame.rotation
            val time = frame.time
            val size = frame.size
            val format = frame.format
            val metadata = FirebaseVisionImageMetadata.Builder()
                .setWidth(480) // 480x360 is typically sufficient for
                .setHeight(360) // image recognition
                .setFormat(FirebaseVisionImageMetadata.IMAGE_FORMAT_NV21)
                .setRotation(3)
                .build()
            val image = FirebaseVisionImage.fromByteArray(data, metadata)
            val detector = FirebaseVision.getInstance()
                .getVisionFaceDetector(realTimeOpts)

            val result = detector.detectInImage(image)
                .addOnSuccessListener { faces ->
                    // Task completed successfully
                    // ...
                    Log.e("FACE", faces.toString())

                    for (face in faces) {
                        val bounds = face.boundingBox
                        val rotY = face.headEulerAngleY // Head is rotated to the right rotY degrees
                        val rotZ = face.headEulerAngleZ // Head is tilted sideways rotZ degrees

                        // If landmark detection was enabled (mouth, ears, eyes, cheeks, and
                        // nose available):
                        val leftEar = face.getLandmark(FirebaseVisionFaceLandmark.LEFT_EAR)
                        leftEar?.let {
                            val leftEarPos = leftEar.position
                        }

                        // If contour detection was enabled:
                        val leftEyeContour = face.getContour(FirebaseVisionFaceContour.LEFT_EYE).points
                        val upperLipBottomContour = face.getContour(FirebaseVisionFaceContour.UPPER_LIP_BOTTOM).points

                        // If classification was enabled:
                        if (face.smilingProbability != FirebaseVisionFace.UNCOMPUTED_PROBABILITY) {
                            val smileProb = face.smilingProbability
                        }
                        if (face.rightEyeOpenProbability != FirebaseVisionFace.UNCOMPUTED_PROBABILITY) {
                            val rightEyeOpenProb = face.rightEyeOpenProbability
                        }

                        // If face tracking was enabled:
                        if (face.trackingId != FirebaseVisionFace.INVALID_ID) {
                            val id = face.trackingId
                        }
                    }
        }.addOnFailureListener(
                    object : OnFailureListener {
                        override fun onFailure(e: Exception) {
                            // Task failed with an exception
                            // ...
                            Log.e("M", e.toString())
                        }
                    })
    }}

}

在activity_main.xml 中:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/message"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="@dimen/activity_horizontal_margin"
        android:layout_marginLeft="@dimen/activity_horizontal_margin"
        android:layout_marginTop="@dimen/activity_vertical_margin"
        android:text="@string/title_home"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
    <androidx.cardview.widget.CardView
            xmlns:card_view="http://schemas.android.com/apk/res-auto"
            android:layout_gravity="center"
            android:layout_width="280dp"
            card_view:cardCornerRadius="280dp"
            android:layout_height="280dp">
        <com.otaliastudios.cameraview.CameraView
                android:id="@+id/camera"
                app:cameraFacing="front"
                android:keepScreenOn="true"
                android:layout_width="match_parent"
                android:layout_height="match_parent" />
    </androidx.cardview.widget.CardView>

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/nav_view"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="0dp"
        android:layout_marginEnd="0dp"
        android:background="?android:attr/windowBackground"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:menu="@menu/bottom_nav_menu" />
</androidx.constraintlayout.widget.ConstraintLayout>

对Fotoapparat也进行了同样的尝试,结果相同:未找到面孔。我在这里想念什么?

4

2 回答 2

0

我认为问题在于 frame.rotation 值。也许您可以将 FirebaseVisionImageMetadata.ROTATION_90 用于 FirebaseVisionImageMetadata

于 2020-06-03T07:06:56.473 回答
0

尝试以编程方式获取高度和宽度,frame而不是对它们进行硬编码。

于 2019-06-03T11:32:45.820 回答