Я пытаюсь использовать 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;
}
}
Ожидаемый результат: лица изображения обведены прямоугольниками
Фактический результат: изображение показывается без прямоугольников