Problems with OpenCV ellipse detection in Java

こ雲淡風輕ζ 提交于 2019-12-11 03:29:01

问题


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 !


回答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;
}


来源:https://stackoverflow.com/questions/21962234/problems-with-opencv-ellipse-detection-in-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!