Android Studio 中的 OpenCV - Haar Cascade - 如何检查是否检测到图像

OpenCV in Android Studio - Haar Cascade - How to check if image is detected

我编写了一个程序,用于使用 OpenCV 的 Haar Cascade 方法检测香蕉。

public class MainActivity extends Activity implements CvCameraViewListener2 {

private static final String TAG = "OCVSample::Activity";
private static final Scalar BANANA_RECT_COLOR = new Scalar(0, 255, 0, 255);
public static final int JAVA_DETECTOR = 0;

private Mat mRgba;
private Mat mGray;
private File mCascadeFile;
private CascadeClassifier mJavaDetectorBanana;
boolean check = false;

private int mDetectorType = JAVA_DETECTOR;
private String[] mDetectorName;

private float mRelativeBananaSize = 0.2f;
private int mAbsoluteBananaSize = 0;

private CameraBridgeViewBase mOpenCvCameraView;

public Button mSpeechButton;
public TextView checkResults;

double xCenter = -1;
double yCenter = -1;

private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
    @Override
    public void onManagerConnected(int status) {
        switch (status) {
            case LoaderCallbackInterface.SUCCESS: {
                Log.i(TAG, "OpenCV Loaded Successfully");

                try {
                    InputStream is = getResources().openRawResource(R.raw.banana4th);
                    File cascadeDir = getDir("cascade", Context.MODE_PRIVATE);
                    mCascadeFile = new File(cascadeDir, "banana4th.xml");
                    FileOutputStream os = new FileOutputStream(mCascadeFile);

                    byte[] buffer = new byte[4096];
                    int bytesRead;
                    while ((bytesRead = is.read(buffer)) != -1) {
                        os.write(buffer, 0, bytesRead);
                    }
                    is.close();
                    os.close();

                    mJavaDetectorBanana = new CascadeClassifier(mCascadeFile.getAbsolutePath());
                    if (mJavaDetectorBanana.empty()) {
                        Log.e(TAG, "Failed to load cascade classifier");
                        mJavaDetectorBanana = null;
                    } else
                        Log.i(TAG, "Loaded cascade classifier from " + mCascadeFile.getAbsolutePath());

                    cascadeDir.delete();
                } catch (IOException e) {
                    e.printStackTrace();
                    Log.e(TAG, "Failed to load cascade. Exception thrown: " + e);
                }
                mOpenCvCameraView.enableFpsMeter();
                mOpenCvCameraView.setCameraIndex(0);
                mOpenCvCameraView.enableView();
            }
            break;
            default: {
                super.onManagerConnected(status);
            }
            break;
        }
    }
};

public MainActivity() {
    mDetectorName = new String[2];
    mDetectorName[JAVA_DETECTOR] = "Java";
    Log.i(TAG, "Instantiated new" + this.getClass());
}

@Override
public void onCreate(Bundle savedInstanceState){
    Log.i(TAG,"Called onCreate");
    super.onCreate(savedInstanceState);
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

    setContentView(R.layout.activity_main);

    mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.fd_activity_surface_view);
    mOpenCvCameraView.setCvCameraViewListener(this);
    mSpeechButton = (Button) findViewById(R.id.ttsBtn);
    checkResults = (TextView) findViewById(R.id.checkResultTB);

    Button backButton = (Button) findViewById(R.id.backBtn);

    backButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent UIActivity = new Intent(MainActivity.this, UiActivity.class);
            startActivity(UIActivity);
        }
    });
    }

@Override
public void onPause() {
    super.onPause();
    if(mOpenCvCameraView!=null)
        mOpenCvCameraView.disableView();
}

@Override
public void onResume() {
    super.onResume();
    if (!OpenCVLoader.initDebug()) {
        Log.d(TAG, "Internal OpenCV library not found. Using OpenCV Manager for initialization");
        OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_3_0, this, mLoaderCallback);
    } else {
        Log.d(TAG, "OpenCV library found inside package. Using it!");
        mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);
    }
}

public void onDestroy() {
    super.onDestroy();
    mOpenCvCameraView.disableView();
}

public void onCameraViewStarted(int width, int height) {
    mGray = new Mat();
    mRgba = new Mat();
}

public void onCameraViewStopped() {
    mGray.release();
    mRgba.release();
}

public Mat onCameraFrame(CvCameraViewFrame inputFrame) {

    mRgba = inputFrame.rgba();
    mGray = inputFrame.gray();

    if (mAbsoluteBananaSize == 0) {
        int height = mGray.rows();
        if (Math.round(height * mRelativeBananaSize) > 0) {
            mAbsoluteBananaSize = Math.round(height * mRelativeBananaSize);
        }
    }

    MatOfRect bananas = new MatOfRect();

    if (mDetectorType == JAVA_DETECTOR) {
        if (mJavaDetectorBanana != null) {
            mJavaDetectorBanana.detectMultiScale(mGray, bananas, 1.1, 2, 2, //TODO: objdetect.CV_HAAR_SCALE_IMAGE)
                    new Size(mAbsoluteBananaSize, mAbsoluteBananaSize), new Size());
        }
    } else {
        Log.e(TAG, "Detection method is not selected!");
    }

    Rect[] bananasArray = bananas.toArray();
    for (int i = 0; i < bananasArray.length; i++) {
        Imgproc.rectangle(mRgba, bananasArray[i].tl(), bananasArray[i].br(), BANANA_RECT_COLOR, 3);
        xCenter = (bananasArray[i].x + bananasArray[i].width + bananasArray[i].x) / 2;
        yCenter = (bananasArray[i].y + bananasArray[i].height + bananasArray[i].y) / 2;
    }
    return mRgba;
}

在 运行 代码和香蕉出现在 Android 设备的相机中后,香蕉的轮廓将显示在矩形中,如下所示:

Banana Outlined in blue rectangle using the imgproc.rectangle function

在此之后,我希望添加一个按钮,按下该按钮后,如果屏幕上有香蕉,文本视图的文本将更改为 "Banana Detected",如果屏幕上有香蕉,则为 "Banana Not Detected"屏幕上没有。

这就是我卡住的地方,你如何检查屏幕上是否有香蕉?我知道必须使用 if-else,但我不确定所需的条件。非常感谢任何帮助!

如果没有检测到香蕉,您的 bananasArray 应该是空的。 在这种情况下,通过检查 bananasArray 是否包含数据来更改 TextView

(例如,通过检查是否 bananasArray.length > 0