0
votes

I'm using opencv and java to find circles on an image, I have the image below so far. I'm using Hough to find the circles with the code like this :

    public static Vector<Mat> circles(Mat img){

    System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
    long start_time = System.nanoTime();
    Imgproc.resize(img, img, new Size(450,250));

    Mat gray = new Mat();
    Imgproc.cvtColor(img, gray, Imgproc.COLOR_BGR2GRAY);
    Imgproc.blur(gray, gray, new Size(3, 3));

    Mat edges = new Mat();
    int lowThreshold = 40;
    int ratio = 3;
    Imgproc.Canny(gray, edges, lowThreshold, lowThreshold * ratio);

    Mat circles = new Mat();
    Vector<Mat> circlesList = new Vector<Mat>();

    Imgproc.HoughCircles(edges, circles, Imgproc.CV_HOUGH_GRADIENT, 1, 60, 200, 20, 30, 0 );


    System.out.println("#rows " + circles.rows() + " #cols " + circles.cols());
    double x = 0.0;
    double y = 0.0;
    int r = 0;

    for( int i = 0; i < circles.rows(); i++ )
    {
      double[] data = circles.get(i, 0);
      for(int j = 0 ; j < data.length ; j++){
           x = data[0];
           y = data[1];
           r = (int) data[2];
      }
      Point center = new Point(x,y);
      // circle center
      Core.circle( img, center, 3, new Scalar(0,255,0), -1);
      // circle outline
      Core.circle( img, center, r, new Scalar(0,0,255), 1);

     Imshow im1 = new Imshow("Hough");
     im1.showImage(img); 

     Rect bbox = new Rect((int)Math.abs(x-r), (int)Math.abs(y-r), (int)2*r, (int)2*r);
     Mat croped_image = new Mat(img, bbox);
     Imgproc.resize(croped_image, croped_image, new Size(160,160));
     circlesList.add(croped_image);
     Imshow m2 = new Imshow("cropedImage");
     m2.showImage(croped_image); 
    }

    long end_time = System.nanoTime();
    long duration = (end_time - start_time)/1000000;  //divide by 1000000 to get milliseconds.
    System.out.println("duration :  " + duration * 0.001 + " s"); 
    return circlesList;
}

BUT it always detects only one circle.

enter image description here

My Question is how I can detect all the circles in an image using java/OpenCV ?

Note:-

1- I'm using Mat called circles in HoughCircles function parameters , because the function requires a Mat in Java.

2- I'm using openCV 2.4.11 version.

1
1. you dont have any circles there, you have ellipses! 2. Canny will be applied automatically in HoughCircles function, using canny edges as input for houghCircles function will often lead to bad results. try Imgproc.HoughCircles(gray, circles, Imgproc.CV_HOUGH_GRADIENT, 1, 60, 200, 20, 30, 0 ); directly! 3. Im not sure about your chosen parameters, maybe the "distance-between-circles" parameter is too big. - Micka
The problem that the function take Mat as parameters which contains the result BUT in c++ it takes vector instead of Mat !? - Anonymous
sorry, no idea about the equivalent of c++ vector in java... - Micka

1 Answers

0
votes

The circles are saved in columns of the mat circles try replacing for loop as:

for( int i = 0; i < circles.cols(); i++)
{
  double[] data = circles.get(0,i);
...