cloudelin / javacv

Automatically exported from code.google.com/p/javacv
0 stars 0 forks source link

CantFind Circles using cvFindContours and cvFitEllipse2 #27

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?

Hi Samuel,
i am trying to find circles using your javacv library. But i'm having trouble 
getting it to work. So i thought maybe you could help with some tips :)

I have an image that i convert to grayscale, then smooth it, then find edges 
using canny. After that i run cvFindContours and would like to go through the 
found contours using cvFitEllipse2 to find its bounding box and calculate by 
its height and width if it could be a circle.

The code looks like this. I left parts out because i build a gui around it to 
add visual parameter tweaking later:

// Prepare image to detect objects.
IplImage imageToDetectObjects = inputImage.getCopy().getOpenCVImage();

// convert to grayscale
IplImage src = imageToDetectObjects.clone();
int width = src.width;
int height = src.height;
IplImage dst = cvCreateImage(new CvSize(width, height).byValue(), IPL_DEPTH_8U, 
1);
cvCvtColor(src, dst, CV_RGB2GRAY);
imageToDetectObjects = dst.clone();

// smooth it, otherwise a lot of false circles may be detected
cvSmooth(imageToDetectObjects, imageToDetectObjects, CV_GAUSSIAN, 9, 9, 2, 2);

// create binary image
IplImage binImage = imageToDetectObjects.clone();
cv.cvCanny(imageToDetectObjects, binImage, 0.3, 0.5, 3);
imageToDetectObjects = binImage.clone();

.
.
.

// find contours
memoryStorage = CvMemStorage.create();
CvSeq.PointerByReference contourPointer = new CvSeq.PointerByReference();
int contourPointerSize = 
com.sun.jna.Native.getNativeSize(CvContour.ByValue.class);
CvSeq contourList = new CvSeq();

cvFindContours(imageToDetectObjects, memoryStorage, contourPointer, 
contourPointerSize, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);
contourList = contourPointer.getStructure();

double circleError = 0.50;

// check if contour is circle
while (contourList != null) {
    if (contourList.elem_size >= 6) {

        CvBox2D box = cvFitEllipse2(contourList);

        CvSize size = new CvSize((int) (box.size.width * 0.5), (int) (box.size.width * 0.5));
        double smallAxis, longAxis;

        if (size.width < size.height) {
            smallAxis = size.width;
            longAxis = size.height;

        } else {
            smallAxis = size.height;
            longAxis = size.width;
        }

        float circleMeasure = (float) ((longAxis - smallAxis) / longAxis);

        if (circleMeasure < circleError) {
            circleList.add((double) box.center.x);
            circleList.add((double) box.center.y);
            circleList.add((double) ((size.width + size.height) / 2));
        }

    }
    contourList = contourList.h_next;
}

What is the expected output? What do you see instead?

Now when i debug it, as soon as i hit the line 
CvBox2D box = cvFitEllipse2(contourList);
i get the error message: 
"OpenCV Error: Incorrect size of input array (Number of points should be >= 6) 
in unknown function, file ..\..\..\..\ocv\opencv\src\cv\cvshapedescr.cpp, line 
972"
So i am wondering if im doing something fundamentaly wrong here? Maybe you have 
an idea?

What version of the product are you using? On what operating system?

I'm using the 2010-07-30 release of javacv and OpenCV 2.1.0 with Eclipse Helios 
on Windows XP.

Best Regards,
Chris

Original issue reported on code.google.com by christia...@gmx.net on 10 Oct 2010 at 1:35

GoogleCodeExporter commented 9 years ago
First, the issue tracker here is for the benefits of the _developers_ of JavaCV 
(i.e.: me), to track problems with JavaCV. Your issue is not a problem with 
JavaCV. If you have problems _using_ JavaCV, as a _user_, you should post a 
message to the discussion group (mailing list). 

In any case, I think the error message is clear.. cvFitEllipse2() needs 6 or 
more points, while cvFindContours() may return less than 6 points, so you need 
to check for that.

Original comment by samuel.a...@gmail.com on 13 Oct 2010 at 9:30

GoogleCodeExporter commented 9 years ago
Yes thats why i put "if (contourList.elem_size >= 6)" in front of the 
cvFitEllipse2 call. But i'm still getting the error message about the 6 points.
I'm sorry if this is the wrong place for this question. I will repost it in the 
discussion group.

Original comment by christia...@gmx.net on 13 Oct 2010 at 12:21