【问题标题】:Feature Detection Opencv/Javacv not working特征检测 Opencv/Javacv 不工作
【发布时间】:2014-07-01 18:43:09
【问题描述】:

我正在尝试运行 javacv 的特征检测程序来比较 2 张图像中的相似特征,但是我得到了运行时异常。由于我对 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;
            }
        };

    }

有谁知道我可能需要更多的东西来完成这项工作.. 任何帮助表示赞赏

【问题讨论】:

    标签: image opencv javacv feature-detection


    【解决方案1】:

    不知道是否还需要,但我找到了答案。在代码中,这个循环有问题:

    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 &lt; 2, i++) {

    【讨论】:

      【解决方案2】:

      CvMat 未正确初始化,导致错误。

      descriptors[i] = new CvMat(null);
      

      相反,我这样说它解决了问题。

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

      【讨论】:

        【解决方案3】:

        正如错误清楚地表明描述符类型不匹配。如果描述符类型匹配,您必须检查条件。

        matcher.match 之前的简单 if 语句可以解决您的问题

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

        【讨论】:

          猜你喜欢
          • 2011-11-06
          • 1970-01-01
          • 2011-07-11
          • 2013-09-14
          • 1970-01-01
          • 2011-10-19
          • 2013-07-02
          • 2023-03-21
          • 2014-04-04
          相关资源
          最近更新 更多