2014-01-20 114 views
0

我遇到了我的Surf描述符問題。OpenCV衝浪描述符Java不工作

此代碼從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的值,但它不工作。

有沒有人爲什麼?

在此先感謝。

回答

0

爲了提高匹配性,在計算單應性之前進行比率和對稱性測試。檢查「OpenCV 2計算機視覺應用程序編程手冊」的第8-9章。它有詳細的解釋和代碼示例。

+0

嗯我看過這本書,代碼是用C++編寫的 – Pric