Студия Android - не удается распознать лица с помощью OpenCV по фотографиям из моей галереи - PullRequest
1 голос
/ 15 мая 2019

Я пытаюсь использовать opencv для обнаружения лиц на статических изображениях из моей галереи, но мне не удается их обнаружить (или нарисовать прямоугольники на картинке). Я перепробовал много вещей, ни одна из которых не работала для меня. Помощь будет оценена.

Я пытался изменить подходы к обнаружению лиц, но ни один из них не помог.

Логически все выглядит хорошо, я думаю: выберите изображение из галереи ---> функция detectFaces ---> установив высоту и ширину для каждого имеющегося у меня Mat, преобразовав изображение imageView из растрового изображения в Mat, чтобы я мог работать над Мат, чтобы обнаружить лица, а затем позже преобразовать Мат обратно в растровое изображение, чтобы увидеть результаты на изображении (imgview.setImageBitmap (bm)).

public class GalleryDetection extends AppCompatActivity {

private Button button;
private ImageView imgview;
private org.opencv.core.Mat rgba, grayscaleImage;
private CascadeClassifier cascadeClassifier;
private int absoluteFaceSize, mDetectorType = 0;
private DetectionBasedTracker mNativeDetector;
private float mRelativeFaceSize = 0.2f;

static {
    System.loadLibrary("opencv_java3");
}

private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) 
{
    @Override
    public void onManagerConnected(int status) {
        switch (status){
            case LoaderCallbackInterface.SUCCESS:
                rgba = new Mat();
                grayscaleImage = new Mat();
                MatOfRect faces = new MatOfRect();
                initializeOpenCVDependencies();
                break;
            default:
                super.onManagerConnected(status);
                break;
        }
    }
};

private void initializeOpenCVDependencies() {
    File cascadeDir = getDir("cascade", Context.MODE_APPEND);
    File mCascadeFile = new File(cascadeDir, "lbpcascade frontalface.xml");
    cascadeClassifier = new CascadeClassifier(mCascadeFile.getAbsolutePath());
    mNativeDetector = new DetectionBasedTracker(mCascadeFile.getAbsolutePath(), 0);
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_gallery_detection);
    Toolbar toolbar = findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    FloatingActionButton fab = findViewById(R.id.fab);
    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                    .setAction("Action", null).show();
        }
    });
    func();
}

void func() {
    this.button = (Button) findViewById(R.id.buttonGallery);
    this.imgview = (ImageView) findViewById(R.id.imageViewGallery);


    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
            startActivityForResult(intent, 101);
        }
    });

}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == 101 && resultCode == RESULT_OK && data != null) {
        Uri imageUri = data.getData();
        String path = getPath(imageUri);
        imgview.setImageURI(imageUri);
        detectFaces();
    }
}

private void detectFaces() {
    Bitmap bm = ((BitmapDrawable) imgview.getDrawable()).getBitmap(); // Convert imageview image to bitmap
    grayscaleImage = new Mat(bm.getHeight(), bm.getWidth(), CvType.CV_8UC4); // grayImage same size as image view
    rgba = new Mat(imgview.getHeight(), imgview.getWidth(), CvType.CV_8UC4); // rgbaImage same size as image view
    Utils.bitmapToMat(bm, rgba); // Convert bitmap to Mat
    absoluteFaceSize = (int) (bm.getHeight() * 0.2); // set the face size
    Utils.matToBitmap(drawRect(rgba), bm); // Convert the Mat with the triangle to bitmap
    imgview.setImageBitmap(bm); // Set the image in the imageview to the bitmap with the triangles
}

private String getPath(Uri uri) {
    if(uri == null) {
        return null;
    }
    else {
        String[] projection = {MediaStore.Images.Media.DATA};
        Cursor cursor = getContentResolver().query(uri, projection, null, null, null);
        if (cursor != null) {
            int col_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
            cursor.moveToFirst();

            return cursor.getString(col_index);
        }
    }
    return uri.getPath();
}

public Mat drawRect(Mat rgba) {
    Imgproc.cvtColor(rgba, grayscaleImage, Imgproc.COLOR_RGBA2RGB); // Convert colors (not really sure how and why it's here)
    if(absoluteFaceSize == 0) {
        int height = grayscaleImage.rows();
        if(Math.round(height * mRelativeFaceSize) > 0) {
            absoluteFaceSize = Math.round(height * mRelativeFaceSize);
        }
        mNativeDetector.setMinFaceSize(absoluteFaceSize);
    }
    MatOfRect faces = new MatOfRect();
    if (mDetectorType == 0) {
        if (cascadeClassifier != null) {
            cascadeClassifier.detectMultiScale(grayscaleImage, faces, 1.1,2,2,
                    new Size(absoluteFaceSize, absoluteFaceSize), new Size());
        }
    }
    else if (mDetectorType == 1) {
        if (mNativeDetector != null) {
            mNativeDetector.detect(grayscaleImage, faces);
        }
    }
    Rect[] facesArray = faces.toArray();
    for (int i = 0; i < facesArray.length; i++) {
        Imgproc.rectangle(rgba, facesArray[i].tl(), facesArray[i].br(), new Scalar(255, 0, 0), 3);
    }
    return rgba;
}

}

Ожидаемый результат: лица изображения обведены прямоугольниками

Фактический результат: изображение показывается без прямоугольников

...