2014-07-04 17 views
8

Tôi đang sử dụng máy dò tính năng ORB để tìm các trận đấu giữa hai hình ảnh sử dụng mã này:OpenCV lọc ORB phù hợp

FeatureDetector detector = FeatureDetector.create(FeatureDetector.ORB); 
    DescriptorExtractor descriptor = DescriptorExtractor.create(DescriptorExtractor.ORB);; 
    DescriptorMatcher matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE_HAMMING); 

    // First photo 
    Imgproc.cvtColor(img1, img1, Imgproc.COLOR_RGB2GRAY); 
    Mat descriptors1 = new Mat(); 
    MatOfKeyPoint keypoints1 = new MatOfKeyPoint(); 

    detector.detect(img1, keypoints1); 
    descriptor.compute(img1, keypoints1, descriptors1); 

    // Second photo 
    Imgproc.cvtColor(img2, img2, Imgproc.COLOR_RGB2GRAY); 
    Mat descriptors2 = new Mat(); 
    MatOfKeyPoint keypoints2 = new MatOfKeyPoint(); 

    detector.detect(img2, keypoints2); 
    descriptor.compute(img2, keypoints2, descriptors2); 

    // Matching 

    MatOfDMatch matches = new MatOfDMatch(); 
    MatOfDMatch filteredMatches = new MatOfDMatch(); 
    matcher.match(descriptors1, descriptors2, matches); 

    // Linking 
    Scalar RED = new Scalar(255,0,0); 
    Scalar GREEN = new Scalar(0,255,0); 

    List<DMatch> matchesList = matches.toList(); 
    Double max_dist = 0.0; 
    Double min_dist = 100.0; 

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



    LinkedList<DMatch> good_matches = new LinkedList<DMatch>(); 
    for(int i = 0;i < matchesList.size(); i++){ 
     if (matchesList.get(i).distance <= (1.5 * min_dist)) 
      good_matches.addLast(matchesList.get(i)); 
    } 



    // Printing 
    MatOfDMatch goodMatches = new MatOfDMatch(); 
    goodMatches.fromList(good_matches); 

    System.out.println(matches.size() + " " + goodMatches.size()); 

    Mat outputImg = new Mat(); 
    MatOfByte drawnMatches = new MatOfByte(); 
    Features2d.drawMatches(img1, keypoints1, img2, keypoints2, goodMatches, outputImg, GREEN, RED, drawnMatches, Features2d.NOT_DRAW_SINGLE_POINTS); 

    Highgui.imwrite("matches.png", outputImg); 

Vấn đề của tôi là tôi không thể tìm thấy một cách để lọc các trận đấu để họ chỉ phù hợp khi họ có vị trí tương tự trong ảnh. Tôi luôn nhận được nhiều trận đấu cho một điểm chính ngay cả khi họ ở rất xa về vị trí.

Có cách nào để lọc chúng tốt hơn không?

Trả lời

6

Để có kết quả đối sánh tốt hơn, bạn nên bao gồm các phương pháp lọc này theo thứ tự đã cho.

  1. Thực hiện khớp theo hai hướng cho mỗi điểm trong hình ảnh đầu tiên tìm kết quả phù hợp nhất trong hình ảnh thứ hai và ngược lại.

  2. Thực hiện kiểm tra tỷ lệ (kiểm tra tỷ lệ khoảng cách euclide) giữa các đối sánh để loại bỏ các kết quả không rõ ràng.

  3. Thực hiện kiểm tra RANSAC: đây là thuật toán phù hợp với mô hình, tìm dữ liệu phù hợp nhất với mô hình và loại bỏ các ngoại lệ.
  4. Thực hiện homography: nó là một thuật toán chiếu hình ảnh.

Bạn có thể nhận tất cả chi tiết về các phương pháp trên trong chương 9 của sách dạy nấu lập trình ứng dụng thị giác máy tính. Nó cũng có mã mẫu để triển khai các kỹ thuật lọc này. Nó rất dễ hiểu. (Lưu ý: Mã trong cuốn sách này là trong C++ nhưng một khi bạn hiểu, nó có thể dễ dàng được thực hiện trong JAVA)

1

Sau khi đọc cuốn sách Rober Langaniere. Tôi đã biết có một cách. Nó là để loại bỏ các trận đấu với khoảng cách xa hơn. Trong java, nó giống như sau

Collections.sort(bestMatches,new Comparator<DMatch>() { 
     @Override 
     public int compare(DMatch o1, DMatch o2) { 
      if(o1.distance<o2.distance) 
       return -1; 
      if(o1.distance>o2.distance) 
       return 1; 
      return 0; 
     } 
    }); 
    if(bestMatches.size()>3){ 
     bestMatches = bestMatches.subList(0,3); 
    } 
+0

Xin chào, cảm ơn câu trả lời, tôi cũng sử dụng cách này, sau khi nhận được kết quả thô từ phương thức .match (.., .., ..), tôi sắp xếp chúng tăng dần và chỉ cần chọn top 10, 30 hoặc bất cứ điều gì phù hợp với tôi. câu hỏi của tôi là, sắp xếp các kết quả phù hợp được trả về từ phương thức .match (.., .., ...) theo thứ tự tăng dần có thể là một sự thay thế cho việc dập tắt? bởi vì như tôi đã thấy trong nhiều ví dụ, khi sử dụng thresholding, có vẻ như nó là một cách khác để có được các kết quả phù hợp nhất, và sử dụng thuật toán sắp xếp mà bạn đã đăng có thể thay thế .. xin vui lòng tư vấn. – rmaik

+0

Tôi nghĩ rằng nó là phù hợp hơn để thêm như là một add-on cho threshholding, đó là lọc ra các trận đấu tốt nhất từ ​​các trận đấu tốt. – zawhtut

+0

nhưng kể từ khi tôi có khoảng cách được sắp xếp tăng dần, điều này có nghĩa là 10 hoặc 15 đầu tiên sẽ có khoảng cách thấp hơn trong số những người khác, có nghĩa là tôi đang chọn những cái tốt .. vui lòng tư vấn – rmaik

Các vấn đề liên quan