OpenCV Surf Descriptor Java无效

时间:2014-01-20 10:17:08

标签: java c++ opencv surf matcher

我的冲浪描述符出现了问题。

此代码已从C ++翻译为Java,我不知道为什么它对我不起作用。

public class SURF2 {

public void run(String pathObject, String pathScene, String pathResult) {

    System.out.println("\nRunning FindObject");

    Mat img_object = Highgui.imread("src/OpenCV/".concat(pathObject), 0); //0 = CV_LOAD_IMAGE_GRAYSCALE
    Mat img_scene = Highgui.imread("src/OpenCV/".concat(pathScene), 0);

    FeatureDetector detector = FeatureDetector.create(FeatureDetector.SURF); //4 = SURF

    MatOfKeyPoint keypoints_object = new MatOfKeyPoint();
    MatOfKeyPoint keypoints_scene  = new MatOfKeyPoint();

    detector.detect(img_object, keypoints_object);
    detector.detect(img_scene, keypoints_scene);

    DescriptorExtractor extractor = DescriptorExtractor.create(2); //2 = SURF;

    Mat descriptor_object = new Mat();
    Mat descriptor_scene = new Mat() ;

    extractor.compute(img_object, keypoints_object, descriptor_object);
    extractor.compute(img_scene, keypoints_scene, descriptor_scene);

    DescriptorMatcher matcher = DescriptorMatcher.create(DescriptorMatcher.FLANNBASED); // 1 = FLANNBASED
    MatOfDMatch matches = new MatOfDMatch();

    matcher.match(descriptor_object, descriptor_scene, matches);
    List<DMatch> matchesList = matches.toList();

    Double max_dist = 0.0;
    Double min_dist = 100.0;

    for(int i = 0; i < descriptor_object.rows(); i++){
        Double dist = (double) matchesList.get(i).distance;
        if(dist < min_dist) min_dist = dist;
        if(dist > max_dist) max_dist = dist;
    }

    System.out.println("-- Max dist : " + max_dist);
    System.out.println("-- Min dist : " + min_dist);    

    LinkedList<DMatch> good_matches = new LinkedList<DMatch>();
    MatOfDMatch gm = new MatOfDMatch();

    for(int i = 0; i < descriptor_object.rows(); i++){
        if(matchesList.get(i).distance < 3*min_dist){
            good_matches.addLast(matchesList.get(i));
        }
    }

    gm.fromList(good_matches);

    Mat img_matches = new Mat();
    Features2d.drawMatches(
            img_object,
            keypoints_object, 
            img_scene,
            keypoints_scene, 
            gm, 
            img_matches, 
            new Scalar(255,0,0), 
            new Scalar(0,0,255), 
            new MatOfByte(), 
            2);

    LinkedList<Point> objList = new LinkedList<Point>();
    LinkedList<Point> sceneList = new LinkedList<Point>();

    List<KeyPoint> keypoints_objectList = keypoints_object.toList();
    List<KeyPoint> keypoints_sceneList = keypoints_scene.toList();

    for(int i = 0; i<good_matches.size(); i++){
        objList.addLast(keypoints_objectList.get(good_matches.get(i).queryIdx).pt);
        sceneList.addLast(keypoints_sceneList.get(good_matches.get(i).trainIdx).pt);
    }

    MatOfPoint2f obj = new MatOfPoint2f();
    obj.fromList(objList);

    MatOfPoint2f scene = new MatOfPoint2f();
    scene.fromList(sceneList);

    //Aquí

    Mat hg = Calib3d.findHomography(obj, scene);

    Mat obj_corners = new Mat(4,1,CvType.CV_32FC2);
    Mat scene_corners = new Mat(4,1,CvType.CV_32FC2);

    obj_corners.put(0, 0, new double[] {0,0});
    obj_corners.put(1, 0, new double[] {img_object.cols(),0});
    obj_corners.put(2, 0, new double[] {img_object.cols(),img_object.rows()});
    obj_corners.put(3, 0, new double[] {0,img_object.rows()});

    Core.perspectiveTransform(obj_corners,scene_corners, hg);

    Core.line(img_matches, new Point(scene_corners.get(0,0)), new Point(scene_corners.get(1,0)), new Scalar(0, 255, 0),4);
    Core.line(img_matches, new Point(scene_corners.get(1,0)), new Point(scene_corners.get(2,0)), new Scalar(0, 255, 0),4);
    Core.line(img_matches, new Point(scene_corners.get(2,0)), new Point(scene_corners.get(3,0)), new Scalar(0, 255, 0),4);
    Core.line(img_matches, new Point(scene_corners.get(3,0)), new Point(scene_corners.get(0,0)), new Scalar(0, 255, 0),4);

    /*

    Mat H = Calib3d.findHomography(obj, scene);

    LinkedList<Point> cornerList = new LinkedList<Point>();
    cornerList.add(new Point(0,0));
    cornerList.add(new Point(img_object.cols(),0));
    cornerList.add(new Point(img_object.cols(),img_object.rows()));
    cornerList.add(new Point(0,img_object.rows()));

    MatOfPoint obj_corners = new MatOfPoint();
    obj_corners.fromList(cornerList);

    MatOfPoint scene_corners = new MatOfPoint();

    //ERROR HERE :
    //OpenCV Error: Assertion failed (scn + 1 == m.cols && (depth == CV_32F || depth == CV_64F)) in unknown function, file ..\..\..\src\opencv\modules\core\src\matmul.cpp, line 1926
    Core.perspectiveTransform(obj_corners, scene_corners, H);

    //Draw the lines... later, when the homography will work
    /*
    Core.line(img_matches, new Point(), new Point(), new Scalar(0,255,0), 4);
    Core.line(img_matches, new Point(), new Point(), new Scalar(0,255,0), 4);
    Core.line(img_matches, new Point(), new Point(), new Scalar(0,255,0), 4);
    Core.line(img_matches, new Point(), new Point(), new Scalar(0,255,0), 4);
    */

    //Sauvegarde du résultat
    System.out.println(String.format("Writing %s", pathResult));
    Highgui.imwrite("src/OpenCV/" + pathResult, img_matches);
}

public static void main(String[] args) {

    System.loadLibrary(Core.NATIVE_LIBRARY_NAME);

    new SURF2().run("taxiTemplate.png", "escenario.jpg", "resultadoFlann.jpg");

}

}

例如:

http://i.stack.imgur.com/2Mh0G.jpg

我尝试使用SIFT,更改DescriptorMatcher的值,但它不起作用。

有人为什么?

提前致谢。

1 个答案:

答案 0 :(得分:0)

在计算单应性之前改进匹配,执行比率和对称性测试。检查“OpenCV 2计算机视觉应用程序编程手册”的第8-9章。它有详细的解释和代码示例。