Java中OpenCV椭圆检测的问题 [英] Problems with OpenCV ellipse detection in Java

查看:380
本文介绍了Java中OpenCV椭圆检测的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们尝试从转换硬币检测中转换c ++代码(和适合椭圆)在图像上到Java。当我们使用参数

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

它崩溃与此错误:

 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)

这里是转换的Java代码:

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);
        }
    }

}

帮助使用?提前感谢!

推荐答案

可能 cvGetSize(src)崩溃。当 src null 时,会发生这种情况。

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

换句话说,图片未加载/找到(可能路径错误?)

以后,您可以通过测试映像是否已成功加载来避免此类问题:

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

这篇关于Java中OpenCV椭圆检测的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆