为什么 Flutter 原生 C++ 中的 OpenCV 4 冻结了 Flutter 的相机预览?

问题描述

我需要非常快地获取检测到的人脸的坐标,我使用 opencv C++ 本机,但是当我开始启动带有预览和 opencv 的抖动相机图像流时,相机预览冻结但 CascadeClassifier 工作(我在 android studio 日志中看到)。

我做错了什么?

这是我的代码

原生 C++ 部分:

#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/objdetect.hpp>

using namespace std;
using namespace cv;

cv::CascadeClassifier cascade;
std::vector<Rect> detectedobjects;
cv::Mat yuv;
cv::Mat bgr;

extern "C" {

    __attribute__((visibility("default"))) __attribute__((used))
    uint32_t* face_detection(uint8_t *plane0,uint8_t *plane1,uint8_t *plane2,int width,int height)
    {
        detectedobjects.clear();

        if (cascade.empty()) {
        cascade.load("/data/user/0/com.example.app/app_Flutter/haarcascade_frontalface_default.xml")    
        }

        cv::Size actual_size(width,height);
        cv::Size half_size(width/2,height/2);

        cv::Mat y(actual_size,CV_8UC1,plane0);
        cv::Mat u(half_size,plane1);
        cv::Mat v(half_size,plane2);

        cv::Mat u_resized,v_resized;
        cv::resize(u,u_resized,actual_size,cv::INTER_NEAREST); //repeat u values 4 times
        cv::resize(v,v_resized,cv::INTER_NEAREST); //repeat v values 4 times

        cv::merge(std::vector<cv::Mat>{ y,v_resized },yuv);

        cv::cvtColor(yuv,bgr,cv::COLOR_YUV2BGR);

        if(!cascade.empty()) {
            cascade.detectMultiScale( bgr,detectedobjects,1.1,2,0|CASCADE_SCALE_IMAGE,Size(30,30) );
        }
        
        return 0;
    }

}

Flutter 部分代码


typedef _face_detection = Pointer<Uint32> Function(
    Pointer<Uint8>,Pointer<Uint8>,Int32,Int32
    );
typedef FaceDetection = Pointer<Uint32> Function(
    Pointer<Uint8>,int,int
    );

final DynamicLibrary nativeAddLib =
Platform.isAndroid ? DynamicLibrary.open("libnative_with_opencv.so") : DynamicLibrary.process();

final FaceDetection faceDetection = nativeAddLib
    .lookup<NativeFunction<_face_detection>>('face_detection').asFunction<FaceDetection>();


void perform(Cameraimage img) {
    Pointer<Uint8> p = allocate(count: img.planes[0].bytes.length);
    Pointer<Uint8> p1 = allocate(count: img.planes[1].bytes.length);
    Pointer<Uint8> p2 = allocate(count: img.planes[2].bytes.length);

    // Assign the planes data to the pointers of the image
    Uint8List pointerList = p.asTypedList(img.planes[0].bytes.length);
    Uint8List pointerList1 = p1.asTypedList(img.planes[1].bytes.length);
    Uint8List pointerList2 = p2.asTypedList(img.planes[2].bytes.length);
    pointerList.setRange(0,img.planes[0].bytes.length,img.planes[0].bytes);
    pointerList1.setRange(0,img.planes[1].bytes.length,img.planes[1].bytes);
    pointerList2.setRange(0,img.planes[2].bytes.length,img.planes[2].bytes);

    Pointer<Uint32> imgP = faceDetection(
        p,p1,p2,img.width,img.height
    );
}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)