2016-01-13 21 views
15

Tôi đang cố gắng so sánh hai hình ảnh (xác định xem chúng có giống nhau hay không) bằng cách sử dụng thư viện OpenCV. Tôi đã cấu hình trình bao bọc java và tìm thấy một số hướng dẫn (chủ yếu là trong C/C++) mà tôi đang cố gắng viết lại vào Java. Tôi đang sử dụng phương pháp phát hiện tính năng.So sánh hai hình ảnh với OpenCV trong Java

Vấn đề là thuật toán hiện tại không tạo ra bất kỳ kết quả hợp lý nào (nó cho rằng hai hình ảnh tương tự không có điểm chung và tìm thấy các kết quả trùng khớp giữa hai ảnh khác hoàn toàn khác nhau). Ai đó có thể đề nghị tôi nên sử dụng trình kết hợp openCV để tạo ra một số kết quả hợp lý không?

Đây là mã của tôi cho sự so sánh hình ảnh

private static void compareImages(String path1, String path2) { 
    System.out.println(path1 + "-" + path2); 

    FeatureDetector detector = FeatureDetector.create(FeatureDetector.ORB); 
    DescriptorExtractor descriptor = DescriptorExtractor.create(DescriptorExtractor.ORB); 

    DescriptorMatcher matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE_HAMMING); 

    // first image 
    Mat img1 = Imgcodecs.imread(path1, Imgcodecs.CV_LOAD_IMAGE_GRAYSCALE); 
    Mat descriptors1 = new Mat(); 
    MatOfKeyPoint keypoints1 = new MatOfKeyPoint(); 

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

    // second image 
    Mat img2 = Imgcodecs.imread(path2, Imgcodecs.CV_LOAD_IMAGE_GRAYSCALE); 
    Mat descriptors2 = new Mat(); 
    MatOfKeyPoint keypoints2 = new MatOfKeyPoint(); 

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

    // match these two keypoints sets 
    MatOfDMatch matches = new MatOfDMatch(); 
    matcher.match(descriptors1, descriptors2, matches); 

    for (DMatch m : matches.toArray()) { 
     // how to use these values to detect the similarity? They seem to be way off 
     // all of these values are in range 50-80 which seems wrong to me 
     System.out.println(m.distance); 
    } 
    } 

Thật không may, các thuật toán như SURF và SIFT không có sẵn trong các wrapper java vì vậy tôi đang sử dụng ORB. Tôi có ít hoặc không có kinh nghiệm với tầm nhìn máy tính, tôi chỉ cố gắng để có được thuật toán so sánh đơn giản này làm việc để tạo ra một số kết quả hợp lý. Tôi sẽ rất vui khi được giúp đỡ!

EDIT: Trường hợp sử dụng của tôi đang chạy thuật toán này so với hình ảnh được chụp từ các góc khác nhau. Tôi đã cập nhật mã của mình để được định dạng tốt hơn.

hình ảnh mẫu để so sánh:

enter image description here enter image description here

+0

[có thể có ích] (http://stackoverflow.com/questions/15544158/error-matching-with-orb-in- android) – GPPK

+0

Thuật toán trong liên kết có vẻ giống hệt như những gì tôi có ở đây ... vẫn tạo ra kết quả rất kém. Tôi chỉ muốn tải hai hình ảnh và sản xuất một số loại giá trị cho thấy sự giống nhau của chúng – Smajl

+0

chỉ là một lưu ý: tôi đã cố gắng ghép hai hình ảnh với 'cv :: Stitcher' mà sử dụng nội bộ' xfeatures2d :: SURF' và stitcing đã thất bại. tôi nghĩ rằng điều này có nghĩa là rất khó để xác định sự hài hước của hình ảnh của SURF – sturkmen

Trả lời

5

Chỉ cần tôi hai xu:

  1. Có quyền truy cập vào SURF và SIFT trong java: openCV DescriptorExtractor Reference. Tôi đã thử triển khai FREAK ba năm trước và phát hiện ra rằng có một số thay đổi xảy ra với bộ mô tả nhị phân khi openCV chuyển chúng sang Java. Có thể là ORB phải chịu cùng một vấn đề. Bạn đã so sánh dữ liệu của các bộ mô tả từ c hoặc C++ với các phần tử ở phía bên java?

  2. Trình so khớp lực lượng vũ phu tìm thấy đối tượng địa lý phù hợp nhất từ ​​hình ảnh tàu cho tính năng EVERY trong hình ảnh truy vấn. Ngay cả khi nó trông hoàn toàn khác nhau. Bạn phải sàng lọc thông qua các trận đấu và thả những người xấu. Có tồn tại một số chiến lược, một cách dễ dàng sẽ là chỉ cần lấy 20% số trận đấu tốt nhất (nhưng điều này sẽ không làm giảm TẤT CẢ outlier). Progressive Sample Consensus hoạt động rất tốt trong quá trình thiết lập của tôi.

  3. Sử dụng Tính năng để so sánh sự giống nhau về hình ảnh có những cạm bẫy. Tính năng và chất lượng khác nhau với kích thước và nội dung hình ảnh, điều này làm cho việc so sánh hình ảnh trên toàn cầu trở nên khó khăn (trong trường hợp bạn muốn biết hình ảnh nào trong số hai hình ảnh giống với tham chiếu hơn hình khác). Bạn có thể ước tính biến đổi từ hình ảnh này sang hình ảnh khác với Calib3d.findHomography(obj, scene, CV_RANSAC); và sử dụng điểm khác biệt chuẩn hóa của các khu vực chồng chéo.
+0

Cảm ơn bạn đã trả lời. Đối với SURF và SIFT - chúng được liệt kê trong enum của các thuật toán có sẵn nhưng nếu bạn cố gắng sử dụng chúng, bạn sẽ nhận được "không được hỗ trợ" ngoại lệ. Tôi sẽ phải sử dụng một số phiên bản OpenCV cũ hơn để truy cập chúng. Tôi sẽ rất vui nếu bạn có thể cung cấp một số mã Java mẫu nào đó hoạt động tốt hơn tôi vì mọi chiến lược để xếp hạng các điểm tương đồng về hình ảnh mà tôi đã thử tạo ra kết quả rất kém. Tại thời điểm này, tôi thực sự bị mắc kẹt: / – Smajl

0

Như đã nêu trong this SO Question, cách dễ nhất và đơn giản nhất là so sánh biểu đồ. Nếu thuật toán của bạn chỉ cần làm việc cho một tập dữ liệu cụ thể, hãy thử sử dụng các kênh màu khác nhau để xem hình ảnh trong bộ của bạn có phần giống nhau nhất ở đâu.

Cách tiếp cận biểu đồ có vẻ không thực tế, nhưng với sự tương đồng về màu sắc của hình ảnh của bạn, tôi tin rằng điều này có thể là một số sử dụng.

Sau khi so sánh biểu đồ hai hình ảnh của bạn trong Photoshop:

histogram comparison

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