I am getting the Mat image that is provided from onCameraFrame() callback method. this I get from CvCameraViewFrame inputFrame that is passed in the parameters.
This use of OpenCV in this example is the Java API version to be used in Android
the problem is that the Imgproc.HoughCircles() method for proccessing the image takes time. I want to use a background thread or Android AsyncTask for this. I tries this several time and it is not working. Is there some example that shows how to do this correctly or how can this be done.
running HoughCirles method inside onCamraFrame() really does slow down the camera frame rate. It looks like doing this on a separate thread is the best way to go. here is my attempt below. it does not work. it is using AsyncTaksk to run HoughCircles on a background thread.
i have tried using a boolean value as shown below to prevent any new frames from being started until the current thread running HoughCircles is finished. the other way i tried is to use a counter variable and only pull one frame out of 10 frames. but this did not work either.
he is what I tried as an example:
public Mat onCameraFrame(final CvCameraViewFrame inputFrame) {
mRgba = inputFrame.rgba(); // colo
mGray = inputFrame.gray(); // grayscale required for detection
// if detected circles is more than zero
// or Animation settings page fragment is not visible on screen
if((detected > 0)&&(!detectionRunning)) {
// prevent any more Asynchronous task threads from being launched
// until this one is finished running
detectionRunnning = false;
// launnch new Asynchronous task that takes mGray Mat image
// and checks to see of any circles exist by using
// the OpenCV Imgproc.HoughCircles() method, passing
// in the mGray as parameter to the doInBackground() method
// of this class
new CircleTask().execute(mGray);
}
// mRgba must be returned with this callback method to show
// up on screen of viewfinder
return mRgba;
} // onCameraFrame
// background thread task takes Mat image from onCameraFrame and
// runs the HoughCircles method on a background thread so UI thread is not blocked
public class CircleTask extends AsyncTask<Mat, Void, Integer> {
// run detection method in background thread
// takes in parameter in the .execute(Mat mGray) call on the class that is created
@Override
protected Integer doInBackground(Mat... params) {
grayMatImage = params[0];
MatOfRect circles = new MatOfRect();
// doing a gaussian blur prevents getting a lot of false positives
Imgproc.GaussianBlur(mGray, mGray, new Size(5, 5), 2, 2);
// for detection of circles
Imgproc.HoughCircles(mGray, circles, Imgproc.CV_HOUGH_GRADIENT,
1, mGray.rows()/8, 150, 60, 30, 0);
// int detected is the number of circles detected
int detected = circles.cols();
// this integer is passes to the onPostExecute method below
return detected;
}
// result Integer is passed here after
// this method is run on maing UI thread
@Override
protected void onPostExecute(Integer result) {
Log.i("RESULT OF DETECTION", "number of circles detected " + result);
// add methods here to be executed after circle is detected
// stop blocking and allow the next frame to be started
detectionRunning = false;
}
}