티스토리 뷰

OpenCV의 설치자바 프로그래밍 테스트를 살펴봤으니, 

이제 이미지 유사도 비교를 해보도록 하자. 

OpenCV를 활용한 이미지의 유사도 비교는 

히스토그램 비교, 템플릿 매칭, 피처 매칭의 세 가지 방법이 있다. 

오늘은 이 중에서 피처 매칭(Feature Matching)을 알아보도록 하자. 


Feature Matching

먼저 전체 소스를 살펴보면 다음과 같다. 

일반적으로 C로 구현되어 있는 Feature Matching 소스를 자바로 변환한 것이다. 

  1. package kr.co.acronym;  
  2.   
  3. import org.opencv.core.Core;  
  4. import org.opencv.core.CvType;  
  5. import org.opencv.core.DMatch;  
  6. import org.opencv.core.Mat;  
  7. import org.opencv.core.MatOfDMatch;  
  8. import org.opencv.core.MatOfKeyPoint;  
  9. import org.opencv.features2d.DescriptorExtractor;  
  10. import org.opencv.features2d.DescriptorMatcher;  
  11. import org.opencv.features2d.FeatureDetector;  
  12. import org.opencv.imgcodecs.Imgcodecs;  
  13.   
  14. public class Mini {  
  15.   
  16.     public static void main(String[] args) {  
  17.         // Set image path  
  18.         String filename1 = "C:\\images\\iphone1.jpeg";  
  19.         String filename2 = "C:\\images\\iphone2.jpeg";  
  20.   
  21.         int ret;  
  22.         ret = compareFeature(filename1, filename2);  
  23.           
  24.         if (ret > 0) {  
  25.             System.out.println("Two images are same.");  
  26.         } else {  
  27.             System.out.println("Two images are different.");  
  28.         }  
  29.     }  
  30.   
  31.     /** 
  32.      * Compare that two images is similar using feature mapping   
  33.      * @author minikim 
  34.      * @param filename1 - the first image 
  35.      * @param filename2 - the second image 
  36.      * @return integer - count that has the similarity within images  
  37.      */  
  38.     public static int compareFeature(String filename1, String filename2) {  
  39.         int retVal = 0;  
  40.         long startTime = System.currentTimeMillis();  
  41.           
  42.         System.loadLibrary(Core.NATIVE_LIBRARY_NAME);  
  43.           
  44.         // Load images to compare  
  45.         Mat img1 = Imgcodecs.imread(filename1, Imgcodecs.CV_LOAD_IMAGE_COLOR);  
  46.         Mat img2 = Imgcodecs.imread(filename2, Imgcodecs.CV_LOAD_IMAGE_COLOR);  
  47.   
  48.         // Declare key point of images  
  49.         MatOfKeyPoint keypoints1 = new MatOfKeyPoint();  
  50.         MatOfKeyPoint keypoints2 = new MatOfKeyPoint();  
  51.         Mat descriptors1 = new Mat();  
  52.         Mat descriptors2 = new Mat();  
  53.   
  54.         // Definition of ORB key point detector and descriptor extractors  
  55.         FeatureDetector detector = FeatureDetector.create(FeatureDetector.ORB);   
  56.         DescriptorExtractor extractor = DescriptorExtractor.create(DescriptorExtractor.ORB);  
  57.   
  58.         // Detect key points  
  59.         detector.detect(img1, keypoints1);  
  60.         detector.detect(img2, keypoints2);  
  61.           
  62.         // Extract descriptors  
  63.         extractor.compute(img1, keypoints1, descriptors1);  
  64.         extractor.compute(img2, keypoints2, descriptors2);  
  65.   
  66.         // Definition of descriptor matcher  
  67.         DescriptorMatcher matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE_HAMMING);  
  68.   
  69.         // Match points of two images  
  70.         MatOfDMatch matches = new MatOfDMatch();  
  71. //      System.out.println("Type of Image1= " + descriptors1.type() + ", Type of Image2= " + descriptors2.type());  
  72. //      System.out.println("Cols of Image1= " + descriptors1.cols() + ", Cols of Image2= " + descriptors2.cols());  
  73.           
  74.         // Avoid to assertion failed  
  75.         // Assertion failed (type == src2.type() && src1.cols == src2.cols && (type == CV_32F || type == CV_8U)  
  76.         if (descriptors2.cols() == descriptors1.cols()) {  
  77.             matcher.match(descriptors1, descriptors2 ,matches);  
  78.       
  79.             // Check matches of key points  
  80.             DMatch[] match = matches.toArray();  
  81.             double max_dist = 0double min_dist = 100;  
  82.               
  83.             for (int i = 0; i < descriptors1.rows(); i++) {   
  84.                 double dist = match[i].distance;  
  85.                 if( dist < min_dist ) min_dist = dist;  
  86.                 if( dist > max_dist ) max_dist = dist;  
  87.             }  
  88.             System.out.println("max_dist=" + max_dist + ", min_dist=" + min_dist);  
  89.               
  90.             // Extract good images (distances are under 10)  
  91.             for (int i = 0; i < descriptors1.rows(); i++) {  
  92.                 if (match[i].distance <= 10) {  
  93.                     retVal++;  
  94.                 }  
  95.             }  
  96.             System.out.println("matching count=" + retVal);  
  97.         }  
  98.           
  99.         long estimatedTime = System.currentTimeMillis() - startTime;  
  100.         System.out.println("estimatedTime=" + estimatedTime + "ms");  
  101.           
  102.         return retVal;  
  103.     }  
  104. }  


이미지 파일 2개를 받아서 서로 비교하는 compareFeature라는 메소드를 만들었다. 

핵심은 이미지에서 KeyPoint를 지정해서 서로 비교해서 거리를 계산한다. 

각 피처의 거리가 어느정도 일때, 두 이미지가 유사하다고 볼 건지를 결정하는 것이 가장 중요하다. 


90~94번째 소스를 보면, 10 이하일 때를 유사하다고 판단하는 것으로 우선 설정했다. 

다양한 이미지로 테스트하면서 이 값을 정하는 것이 필요할 것으로 보인다. 


위 로직에 따라 유사한 것으로 판단된 피처의 개수를 리턴했고, 

메인함수에서는 유사한 피처가 한개 이상이면 동일한 이미지라고 판단하도록 구성했다. 


추가로 76번째의 if 문은 완전히 서로 다른 이미지를 함수에 넣었을 때 발생하는 Assert 오류를 피하기 위해 적용했다. 


Feature Matching Test

다음의 세 개의 아이폰 이미지를 가지고 테스트를 해 봤다. 


먼저 동일한 이미지인 iphone1.jpeg를 비교하면 다음과 같이 동일하다고 나온다. 

 

이번에는 거의 비슷해 보이는 iphone1.jpeg와 iphone2.jpeg를 비교해보자. 

두 이미지의 피처간 거리가 있기는 하지만, 10 이하의 값이 2개가 나와서 유사한 이미지로 판단했다. 


마지막으로 완전히 다른 iphone1.jpeg와 iphone3.jpeg를 비교해 보면 다음과 같다. 

최소 거리값이 24가 나오면서 전혀 다른 이미지라고 나타났다. 


위 예제를 잘 활용하면, 피처 매칭으로 이미지 유사도를 비교해 볼 수 있을 것 같다. 

다음에는 히스토그램을 이용한 비교를 살펴보려고 한다. 


OpenCV 더보기..

OpenCV를 활용한 이미지 유사도 비교 방법~

OpenCV 설치 및 자바 이클립스 환경 설정~

OpenCV 자바 이클립스에서의 프로그래밍 시작하기~

OpenCV 이미지 유사도 비교 #1 - 피처 매칭

OpenCV 이미지 유사도 비교 #2 - 히스토그램 비교


댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2025/08   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
글 보관함