2014-02-22 61 views
2

我们尝试将C++代码从Detection of coins (and fit ellipses) on an image转换为Java。当我们启动程序与参数Java中的OpenCV椭圆检测问题

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代码:

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

} 

谁能帮助用?提前致谢 !

+0

根据错误信息,崩溃发生在你的代码行65。那是哪条线? – karlphillip

+0

这是一行: 'IplImage dst = cvCreateImage(cvGetSize(src),8,3);' – Baschdl

回答

1

可能cvGetSize(src)正在发生这样的事故。当srcnull时会发生这种情况。

换句话说,图像没有加载/找到(也许路径是错误的?)。

今后,您可以通过测试避免这样的问题,如果图像加载成功:

IplImage src = cvLoadImage(args[1], 0); 
if (src == null) 
{ 
    System.out.println("!!! Unable to load image: " + args[1]); 
    return; 
} 
+0

感谢您的帮助,现在程序加载了图像,但之后发生了编辑我们问题时提到的错误。 – Baschdl

+0

啊...不要这样做:(现在你完全改变了这个问题,你的代码有问题,这个答案解决了它!如果你改变了这个问题,答案对于未来的访问者来说就变得没有用处,那么答案就没有意义了,相反,当发生这种情况时,你应该问一个**新问题**,而不是劫持你的旧问题来解决新问题,这就是你需要做的:提出一个新问题,我会回滚这一个到以前的编辑,所以这个答案仍然有效。我会尽力帮助你在新的线程! – karlphillip

+0

对不起,我是新来的stackoverflow。这是新的线程:[致命错误已被Java运行时检测到环境:Java中的OpenCV椭圆检测](http://stackoverflow.com/questions/21968038/fatal-error-has-been-detected-by-the-java-runtime-environment-opencv-ellipse-de) – Baschdl