android安卓 基于CameraX和MLKIT实现中文识别Demo

实现功能,一个最简demo说明:

依赖

因为是实验性质,这里都是beta版本

	// CameraX core library
    def camerax_version = '1.1.0-beta01'
    implementation "androidx.camera:camera-core:$camerax_version"

    // CameraX Camera2 extensions
    implementation "androidx.camera:camera-camera2:$camerax_version"

    // CameraX Lifecycle library
    implementation "androidx.camera:camera-lifecycle:$camerax_version"

    // CameraX View class
    implementation "androidx.camera:camera-view:$camerax_version"

    //ML Kit 中文识别
    implementation 'com.google.mlkit:text-recognition-chinese:16.0.0-beta3'

CameraX调起相机预览

官方文档
官方文档有些晦涩难懂

示例代码:

layout

	<FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/container">
        <androidx.camera.view.PreviewView
            android:layout_height="match_parent"
            android:layout_width="match_parent"
            android:id="@+id/previewView" />
    </FrameLayout>

Activity

/**
 * https://developer.android.google.cn/training/camerax/preview?hl=zh_cn#implementation
 * 没有写申请权限代码
 * @author markrenChina
 */
class MainActivity : AppCompatActivity() {

    private lateinit var cameraProviderFuture : ListenableFuture<ProcessCameraProvider>
    //用于分析的线程
    private lateinit var cameraExecutor: ExecutorService

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        /**
         * 创建的实例ProcessCameraProvider。这用于将摄像机的生命周期绑定到生命周期所有者。
         * 由于CameraX具有生命周期感知功能,因此省去了打开和关闭相机的任务
         */
        cameraProviderFuture = ProcessCameraProvider.getInstance(this)
        /**
         * 将侦听器添加到中cameraProviderFuture。添加一个Runnable作为一个参数。
         * 添加作为第二个参数。这会返回在主线程上运行的。ContextCompat.getMainExecutor()Executor
         */
        cameraProviderFuture.addListener(Runnable {
            //用于将相机的生命周期绑定到LifecycleOwner应用程序的过程中。
            val cameraProvider = cameraProviderFuture.get()
            bindPreview(cameraProvider)
        }, ContextCompat.getMainExecutor(this))
        cameraExecutor = Executors.newSingleThreadExecutor()
    }

    private fun bindPreview(cameraProvider : ProcessCameraProvider) {
        //初始化Preview对象,调用其上的对象,从取景器中获取表面提供程序,然后在预览中进行设置。
        val preview : Preview = Preview.Builder()
            .build()

        val cameraSelector : CameraSelector = CameraSelector.Builder()
            .requireLensFacing(CameraSelector.LENS_FACING_BACK)
            .build()

        val previewView = findViewById<PreviewView>(R.id.previewView)
        preview.setSurfaceProvider(previewView.surfaceProvider)

        //分析器
        val imageAnalyzer = ImageAnalysis.Builder()
            .build()
            .also {
                it.setAnalyzer(cameraExecutor, ChineseTextAnalyzer { text ->
                    Log.d("MainActivity", "res: $text")
                })
            }

        cameraProvider.bindToLifecycle(this as LifecycleOwner, cameraSelector, preview,imageAnalyzer)
    }
}

自定义中文识别分析器

官方外网
最简实现:

typealias RecognitionListener = ( text : String) -> Unit

/**
 * 自定义中文分析器
 * @author markrenChina
 */
class ChineseTextAnalyzer(
    listener :RecognitionListener?= null
) : ImageAnalysis.Analyzer{

    private val listeners = ArrayList<RecognitionListener>().apply { listener?.let { add(it) } }
    
    fun onFrameAnalyzed(listener: RecognitionListener) = listeners.add(listener)

    private val recognizer = TextRecognition.getClient(ChineseTextRecognizerOptions.Builder().build())


    @SuppressLint("UnsafeOptInUsageError")
    override fun analyze(image: ImageProxy) {
        // If there are no listeners attached, we don't need to perform analysis
        if (listeners.isEmpty()) {
            image.close()
            return
        }
        val currentTime : Any
        // Keep track of frames analyzed
        currentTime = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            Instant.now()
        }else {
            System.currentTimeMillis()
        }
        //获取image,用mediaImage.close()是不安全的
        val mediaImage = image.image
        mediaImage?.let {
            val photo = InputImage.fromMediaImage(mediaImage,image.imageInfo.rotationDegrees)
            recognizer.process(photo).addOnSuccessListener { text: Text ->
                listeners.forEach { it(text.text) }
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
                    Log.d("ChineseTextAnalyzer", "analyze: duration ${Duration.between(currentTime as Instant,Instant.now()).nano} nanos")
                }else {
                    Log.d("ChineseTextAnalyzer", "analyze: duration ${System.currentTimeMillis() - (currentTime as Long)} Millis")
                }
            }
        }

        image.close()
    }
}

这种实现下,解析速度非常的慢,所以,以上代码只是一个demo,不是实际使用的代码。

demo

一个封装过的aar
使用aar效果图,比demo多了一些相机相关的代码,需要注册CameraActivity:
aar效果图

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
ML Kit是Google推出的一个移动端机器学习框架,可以方便地实现人脸识别和姿势检测。下面是实现人脸识别和姿势检测的详细步骤: 1. 在Android Studio中创建一个新的项目,将minSdkVersion设置为21或更高版本。 2. 在项目的build.gradle文件中添加以下依赖项: ``` dependencies { implementation 'com.google.firebase:firebase-ml-vision:24.0.3' } ``` 3. 配置Firebase ML Kit。在Firebase控制台中创建一个新的项目,并启用ML Kit API。然后将google-services.json文件下载到您的项目中。 4. 为了实现人脸识别,您需要在布局文件中添加一个SurfaceView用于显示照相机预览,并在Activity中实现相机预览和人脸检测。以下是一个简单的示例: ``` public class MainActivity extends AppCompatActivity { private CameraSource cameraSource; private CameraSourcePreview preview; private GraphicOverlay graphicOverlay; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); preview = findViewById(R.id.camera_preview); graphicOverlay = findViewById(R.id.face_overlay); // 创建一个人脸检测器 FaceDetector faceDetector = new FaceDetector.Builder(this) .setTrackingEnabled(false) .build(); // 创建一个相机源 cameraSource = new CameraSource.Builder(this, faceDetector) .setRequestedPreviewSize(640, 480) .setFacing(CameraSource.CAMERA_FACING_FRONT) .setAutoFocusEnabled(true) .setRequestedFps(30.0f) .build(); // 启动相机预览 preview.start(cameraSource); // 添加一个人脸检测器工具 FaceGraphic faceGraphic = new FaceGraphic(graphicOverlay); graphicOverlay.add(faceGraphic); // 设置人脸检测回调 faceDetector.setProcessor(new Detector.Processor<Face>() { @Override public void release() { graphicOverlay.clear(); } @Override public void receiveDetections(Detector.Detections<Face> detections) { // 获取人脸检测结果 SparseArray<Face> faces = detections.getDetectedItems(); if (faces.size() > 0) { Face face = faces.valueAt(0); // 更新人脸检测器工具 faceGraphic.update(face); } else { faceGraphic.setFace(null); } } }); } } ``` 5. 为了实现姿势检测,您需要在布局文件中添加一个ImageView用于显示姿势检测结果,并在Activity中实现姿势检测。以下是一个简单的示例: ``` public class MainActivity extends AppCompatActivity { private FirebaseVisionPoseDetector poseDetector; private ImageView poseImageView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); poseImageView = findViewById(R.id.pose_image); // 创建一个姿势检测器 poseDetector = FirebaseVision.getInstance().getPoseDetector(); // 加载要检测的图像 Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.pose_image); // 创建一个FirebaseVisionImage对象 FirebaseVisionImage image = FirebaseVisionImage.fromBitmap(bitmap); // 进行姿势检测 poseDetector.detectInImage(image) .addOnSuccessListener(new OnSuccessListener<List<FirebaseVisionPose>>() { @Override public void onSuccess(List<FirebaseVisionPose> poses) { // 获取第一个姿势检测结果 FirebaseVisionPose pose = poses.get(0); // 获取姿势检测结果的角度 float leftShoulderAngle = pose.getPoseLandmark(FirebaseVisionPoseLandmark.LEFT_SHOULDER).getInFrameLikelihood(); float rightShoulderAngle = pose.getPoseLandmark(FirebaseVisionPoseLandmark.RIGHT_SHOULDER).getInFrameLikelihood(); // 根据角度更新姿势检测结果 if (leftShoulderAngle > 0.5 && rightShoulderAngle > 0.5) { poseImageView.setImageResource(R.drawable.correct_pose_image); } else { poseImageView.setImageResource(R.drawable.incorrect_pose_image); } } }) .addOnFailureListener(new OnFailureListener() { @Override public void onFailure(@NonNull Exception e) { // 处理姿势检测失败的情况 } }); } } ``` 这些是实现人脸识别和姿势检测的基本步骤。您可以根据您的需求进行更改和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值