2

We tried to convert the c++ Code from Detection of coins (and fit ellipses) on an image into Java. When we start the program with the parameters

2 PathToThePicture

it crashes with this error:

 OpenCV Error: Bad argument (Array should be CvMat or IplImage) in cvGetSize, file       
 ..\..\..\..\opencv\modules\core\src\array.cpp, line 1238
 Exception in thread "main" java.lang.RuntimeException: ..\..\..\..\opencv\modules       
 \core\src\array.cpp:1238: error: (-5) Array should be CvMat or IplImage in function   
 cvGetSize

 at com.googlecode.javacv.cpp.opencv_core.cvGetSize(Native Method)
 at DetectEllipse.main(DetectEllipse.java:65)

Here is the converted Java-Code:

import static com.googlecode.javacv.cpp.opencv_core.CV_FILLED;
import static com.googlecode.javacv.cpp.opencv_core.CV_RGB;
import static com.googlecode.javacv.cpp.opencv_core.CV_WHOLE_SEQ;
import static com.googlecode.javacv.cpp.opencv_core.cvCreateImage;
import static com.googlecode.javacv.cpp.opencv_core.cvCreateMemStorage;
import static com.googlecode.javacv.cpp.opencv_core.cvDrawContours;
import static com.googlecode.javacv.cpp.opencv_core.cvGetSize;
import static com.googlecode.javacv.cpp.opencv_core.cvPoint;
import static com.googlecode.javacv.cpp.opencv_core.cvScalar;
import static com.googlecode.javacv.cpp.opencv_core.cvXorS;
import static com.googlecode.javacv.cpp.opencv_core.cvZero;
import static com.googlecode.javacv.cpp.opencv_highgui.cvLoadImage;
import static com.googlecode.javacv.cpp.opencv_highgui.cvSaveImage;
import static com.googlecode.javacv.cpp.opencv_imgproc.CV_CHAIN_APPROX_SIMPLE;
import static com.googlecode.javacv.cpp.opencv_imgproc.CV_RETR_CCOMP;
import static com.googlecode.javacv.cpp.opencv_imgproc.CV_THRESH_BINARY;
import static com.googlecode.javacv.cpp.opencv_imgproc.cvContourArea;
import static com.googlecode.javacv.cpp.opencv_imgproc.cvDilate;
import static com.googlecode.javacv.cpp.opencv_imgproc.cvFindContours;
import static com.googlecode.javacv.cpp.opencv_imgproc.cvThreshold;

import com.googlecode.javacpp.Loader;
import com.googlecode.javacv.cpp.opencv_core.CvContour;
import com.googlecode.javacv.cpp.opencv_core.CvMemStorage;
import com.googlecode.javacv.cpp.opencv_core.CvRect;
import com.googlecode.javacv.cpp.opencv_core.CvScalar;
import com.googlecode.javacv.cpp.opencv_core.CvSeq;
import com.googlecode.javacv.cpp.opencv_core.IplImage;

public class DetectEllipse{

    public static final double M_PI = 3.14159265358979323846;
    public static final double MIN_AREA = 100.00;
    public static final double MAX_TOL = 100.00;

    private static int[] array = { 0 };
    //
    // We need this to be high enough to get rid of things that are too small
    // too
    // have a definite shape. Otherwise, they will end up as ellipse false
    // positives.
    //
    //
    // One way to tell if an object is an ellipse is to look at the relationship
    // of its area to its dimensions. If its actual occupied area can be
    // estimated
    // using the well-known area formula Area = PI*A*B, then it has a good
    // chance of
    // being an ellipse.
    //
    // This value is the maximum permissible error between actual and estimated
    // area.
    //

    public static void main(String[] args) {
        IplImage src = cvLoadImage(args[1], 0);
        // the first command line parameter must be file name of binary
        // (black-n-white) image
        if (Integer.parseInt(args[0]) == 2) {
            IplImage dst = cvCreateImage(cvGetSize(src), 8, 3);
            CvMemStorage storage = cvCreateMemStorage(0);
            CvSeq contour = new CvContour();
            // maybe: = new CvSeq(0)
            cvThreshold(src, src, 1, 255, CV_THRESH_BINARY);
            //
            // Invert the image such that white is foreground, black is
            // background.
            // Dilate to get rid of noise.
            //
            cvXorS(src, cvScalar(255, 0, 0, 0), src, null);
            cvDilate(src, src, null, 2);

            cvFindContours(src, storage, contour,
                    Loader.sizeof(CvContour.class), CV_RETR_CCOMP,
                    CV_CHAIN_APPROX_SIMPLE, cvPoint(0, 0));
            cvZero(dst);

            for (; contour.flags() != 0; contour = contour.h_next()) {
                // if not working: use contour.isNull()
                double actual_area = Math.abs(cvContourArea(contour,
                        CV_WHOLE_SEQ, 0));
                if (actual_area < MIN_AREA)
                    continue;

                //
                // FIXME:
                // Assuming the axes of the ellipse are vertical/perpendicular.
                //
                CvRect rect = ((CvContour) contour).rect();
                int A = rect.width() / 2;
                int B = rect.height() / 2;
                double estimated_area = Math.PI * A * B;
                double error = Math.abs(actual_area - estimated_area);
                if (error > MAX_TOL)
                    continue;
                System.out.printf("center x: %d y: %d A: %d B: %d\n", rect.x()
                        + A, rect.y() + B, A, B);

                CvScalar color = CV_RGB(
                        tangible.RandomNumbers.nextNumber() % 255,
                        tangible.RandomNumbers.nextNumber() % 255,
                        tangible.RandomNumbers.nextNumber() % 255);
                cvDrawContours(dst, contour, color, color, -1, CV_FILLED, 8,
                        cvPoint(0, 0));
            }

            cvSaveImage("coins.png", dst, array);
        }
    }

}

Can anyone help use? Thanks in advance !

Community
  • 1
  • 1
Baschdl
  • 375
  • 3
  • 15

1 Answers1

1

Probably cvGetSize(src) is doing the crash. That happens when src is null.

In other words, the image was not loaded/found (maybe the path is wrong?).

In the future, you can avoid such problems by testing if the image was loaded successfully:

IplImage src = cvLoadImage(args[1], 0);
if (src == null) 
{
    System.out.println("!!! Unable to load image: " + args[1]);
    return;
}
karlphillip
  • 92,053
  • 36
  • 243
  • 426
  • Thanks for your help, now the programm loads the image, but after that the error mentioned in the edit of our question occurs. – Baschdl Feb 23 '14 at 00:26
  • Ah... don' t do that :( Now you completely changed the question. You code had a problem, and this answer fixed it! IF you change the question the answers become useless for future visitors and they will get down votes because the answers don't make sense anymore. Instead, when this happens, you should ask a **new question** instead of hijacking your old question to fix new problems. Here's what you need to do: ask a new question and I will rollback this one to the previous edit so this answer remains valid. I will try to help you on the new thread! – karlphillip Feb 23 '14 at 01:24
  • Sorry, I'm new to stackoverflow. This is the new thread: [fatal error has been detected by the Java Runtime Environment: OpenCV ellipse detection in Java](http://stackoverflow.com/questions/21968038/fatal-error-has-been-detected-by-the-java-runtime-environment-opencv-ellipse-de) – Baschdl Feb 23 '14 at 12:14