2014-05-13 19 views
-1

我試圖運行javacv的功能檢測程序來比較2圖像中的類似功能,但是我得到一個runtimeexception。由於我對javacv完全陌生,所以我不知道如何解決這個問題。功能檢測Opencv/Javacv不工作

的異常跟蹤是

OpenCV Error: Assertion failed (queryDescriptors.type() == trainDescCollection[0].type()) in  unknown function, file ..\..\..\src\opencv\modules\features2d\src\matchers.cpp, line 351 
Exception in thread "main" java.lang.RuntimeException: ..\..\..\src\opencv\modules\features2d\src\matchers.cpp:351: error: (-215) queryDescriptors.type() == trainDescCollection[0].type() 


at com.googlecode.javacv.cpp.opencv_features2d$DescriptorMatcher.match(Native Method) 
at Ex7DescribingSURF.main(Ex7DescribingSURF.java:63) 

這裏是源代碼

import static com.googlecode.javacv.cpp.opencv_core.NORM_L2; 
    import static com.googlecode.javacv.cpp.opencv_core.cvCreateImage; 
    import static com.googlecode.javacv.cpp.opencv_features2d.drawMatches; 
    import static com.googlecode.javacv.cpp.opencv_highgui.cvLoadImage; 
    import java.util.Arrays; 
    import java.util.Comparator;   
    import javax.swing.JFrame; 

    import com.googlecode.javacv.CanvasFrame; 
    import com.googlecode.javacv.cpp.opencv_core.CvMat; 
    import com.googlecode.javacv.cpp.opencv_core.CvScalar; 
    import com.googlecode.javacv.cpp.opencv_core.CvSize; 
    import com.googlecode.javacv.cpp.opencv_core.IplImage; 
    import com.googlecode.javacv.cpp.opencv_features2d.BFMatcher; 
    import com.googlecode.javacv.cpp.opencv_features2d.DMatch; 
    import com.googlecode.javacv.cpp.opencv_features2d.DescriptorExtractor; 
    import com.googlecode.javacv.cpp.opencv_features2d.DrawMatchesFlags; 
    import com.googlecode.javacv.cpp.opencv_features2d.KeyPoint; 
    import com.googlecode.javacv.cpp.opencv_nonfree.SURF; 

    public class Ex7DescribingSURF { 

     /** 
     * Example for section "Describing SURF features" in chapter 8, page 212. 
     * 
     * Computes SURF features, extracts their descriptors, and finds best 
     * matching descriptors between two images of the same object. There are a 
     * couple of tricky steps, in particular sorting the descriptors. 
     */ 
     public static void main(String[] args) { 
      IplImage img = cvLoadImage("A.jpg"); 
      IplImage template = cvLoadImage("B.jpg"); 
      IplImage images[] = { img, template }; 

      // Setup SURF feature detector and descriptor. 
      double hessianThreshold = 2500d; 
      int nOctaves = 4; 
      int nOctaveLayers = 2; 
      boolean extended = true; 
      boolean upright = false; 
      SURF surf = new SURF(hessianThreshold, nOctaves, nOctaveLayers, 
        extended, upright); 
      DescriptorExtractor surfDesc = DescriptorExtractor.create("SURF"); 
      KeyPoint keyPoints[] = { new KeyPoint(), new KeyPoint() }; 
      CvMat descriptors[] = new CvMat[2]; 

      // Detect SURF features and compute descriptors for both images 
      for (int i = 0; i < 1; i++) { 
       surf.detect(images[i], null, keyPoints[i]); 
       // Create CvMat initialized with empty pointer, using simply `new 
       // CvMat()` leads to an exception. 
       descriptors[i] = new CvMat(null); 
       surfDesc.compute(images[i], keyPoints[i], descriptors[i]); 
      } 

      // Create feature matcher 
      BFMatcher matcher = new BFMatcher(NORM_L2, true); 

      DMatch matches = new DMatch(); 
      // "match" is a keyword in Scala, to avoid conflict between a keyword 
      // and a method match of the BFMatcher, 
      // we need to enclose method name in ticks: `match`. 
      matcher.match(descriptors[0], descriptors[1], matches, null); 
      System.out.println("Matched: " + matches.capacity()); 

      // Select only 25 best matches 
      DMatch bestMatches = selectBest(matches, 25); 

      // Draw best matches 
      IplImage imageMatches = cvCreateImage(new CvSize(images[0].width() 
        + images[1].width(), images[0].height()), images[0].depth(), 3); 
      drawMatches(images[0], keyPoints[0], images[1], keyPoints[1], 
        bestMatches, imageMatches, CvScalar.BLUE, CvScalar.RED, null, 
        DrawMatchesFlags.DEFAULT); 

      CanvasFrame canvas = new CanvasFrame(""); 

      canvas.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

      canvas.showImage(imageMatches); 

     } 

     // ---------------------------------------------------------------------------------------------------------------- 

     /** Select only the best matches from the list. Return new list. */ 
     private static DMatch selectBest(DMatch matches, int numberToSelect) { 
      // Convert to Scala collection for the sake of sorting 
      int oldPosition = matches.position(); 
      DMatch a[] = new DMatch[matches.capacity()]; 
      for (int i = 0; i < a.length; i++) { 
       DMatch src = matches.position(i); 
       DMatch dest = new DMatch(); 
       copy(src, dest); 
       a[i] = dest; 
      } 
      // Reset position explicitly to avoid issues from other uses of this 
      // position-based container. 
      matches.position(oldPosition); 

      // Sort 

      DMatch aSorted[] = a; 
      Arrays.sort(aSorted, new DistanceComparator()); 

      // DMatch aSorted[]=sort(a); 

      // Create new JavaCV list 
      DMatch best = new DMatch(numberToSelect); 
      for (int i = 0; i < numberToSelect; i++) { 
       // Since there is no may to `put` objects into a list DMatch, 
       // We have to reassign all values individually, and hope that API 
       // will not any new ones. 
       copy(aSorted[i], best.position(i)); 
      } 

      // Set position to 0 explicitly to avoid issues from other uses of this 
      // position-based container. 
      best.position(0); 

      return best; 
     } 

     private static void copy(DMatch src, DMatch dest) { 
      // TODO: use Pointer.copy() after JavaCV/JavaCPP 0.3 is released 
      // (http://code.google.com/p/javacpp/source/detail?r=51f4daa13d618c6bd6a5556ff2096d0e834638cc) 
      // dest.put(src) 
      dest.distance(src.distance()); 
      dest.imgIdx(src.imgIdx()); 
      dest.queryIdx(src.queryIdx()); 
      dest.trainIdx(src.trainIdx()); 
     } 

     static class DistanceComparator implements Comparator<DMatch> { 
      public int compare(DMatch o1, DMatch o2) { 
       if (o1.compare(o2)) 
        return -1; 
       else 
        return 1; 
      } 
     }; 

    } 

有誰知道我可能需要更多的,使這項工作..任何幫助表示讚賞

回答

0

CvMat中的不正確初始化,這是給錯誤。

descriptors[i] = new CvMat(null); 

而是我把它這樣解決了問題。

descriptors[i] = CvMat.create(1, 1); 
0

由於錯誤清楚地表明描述符類型不匹配。如果描述符類型匹配,您必須檢查條件。

一個簡單的,如果matcher.match前語句將解決您的問題

 if (descriptors[0].type() == descriptors[1].type()) 
{ 
     matcher.match(descriptors[0], descriptors[1], matches, null); 
     System.out.println("Matched: " + matches.capacity()); 
} 
0

不知道是否仍然需要,但我找到了答案。在代碼中有問題,這個循環:

for (int i = 0; i < 1; i++) { 
    surf.detect(images[i], null, keyPoints[i]); 
    // Create CvMat initialized with empty pointer, using simply `new 
    // CvMat()` leads to an exception. 
    descriptors[i] = new CvMat(null); 
    surfDesc.compute(images[i], keyPoints[i], descriptors[i]); 
} 

i只是0,比退出循環,並嘗試使用對象descriptors[1]這是不存在的。
更改爲for(int i = 0, i < 2, i++) {