特性检测Opencv/Javacv不工作



我试图运行javacv的特征检测程序来比较2个图像中的类似功能,但是我得到一个运行时异常。由于我是javacv的新手,我不知道如何解决这个问题。

异常跟踪是
OpenCV Error: Assertion failed (queryDescriptors.type() == trainDescCollection[0].type()) in     unknown function, file ......srcopencvmodulesfeatures2dsrcmatchers.cpp, line 351
Exception in thread "main"   java.lang.RuntimeException: ......srcopencvmodulesfeatures2dsrcmatchers.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;
            }
        };
    }

有谁知道我还需要什么才能使这个工作…感谢您的帮助

由于错误清楚地表明描述符类型不匹配。您必须检查描述符类型是否匹配。

matcher.match之前一个简单的if语句将解决您的问题

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

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

descriptors[i] = new CvMat(null);

相反,我把它写成这样解决了问题。

descriptors[i] = CvMat.create(1, 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 < 2, i++) {

相关内容

  • 没有找到相关文章