2014-02-22 137 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