processing images Asynchronously from onCameraFrame callback

asked 2014-05-08 00:40:11 -0600

kevik gravatar image

updated 2014-05-08 05:53:07 -0600

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 = true;

        // 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;

}

}
edit retag flag offensive close merge delete

Comments

1

you never set detectionRunnning to true.

    // prevent any more Asynchronous task threads from being launched
    // until this one is finished running
    detectionRunnning = false;  // hmm ? should be set to true instead?
berak gravatar imageberak ( 2014-05-08 02:39:21 -0600 )edit