티스토리 뷰
OpenCV의 설치와 자바 프로그래밍 테스트를 살펴봤으니,
이제 이미지 유사도 비교를 해보도록 하자.
히스토그램 비교, 템플릿 매칭, 피처 매칭의 세 가지 방법이 있다.
오늘은 이 중에서 피처 매칭(Feature Matching)을 알아보도록 하자.
Feature Matching
먼저 전체 소스를 살펴보면 다음과 같다.
일반적으로 C로 구현되어 있는 Feature Matching 소스를 자바로 변환한 것이다.
- package kr.co.acronym;
- import org.opencv.core.Core;
- import org.opencv.core.CvType;
- import org.opencv.core.DMatch;
- import org.opencv.core.Mat;
- import org.opencv.core.MatOfDMatch;
- import org.opencv.core.MatOfKeyPoint;
- import org.opencv.features2d.DescriptorExtractor;
- import org.opencv.features2d.DescriptorMatcher;
- import org.opencv.features2d.FeatureDetector;
- import org.opencv.imgcodecs.Imgcodecs;
- public class Mini {
- public static void main(String[] args) {
- // Set image path
- String filename1 = "C:\\images\\iphone1.jpeg";
- String filename2 = "C:\\images\\iphone2.jpeg";
- int ret;
- ret = compareFeature(filename1, filename2);
- if (ret > 0) {
- System.out.println("Two images are same.");
- } else {
- System.out.println("Two images are different.");
- }
- }
- /**
- * Compare that two images is similar using feature mapping
- * @author minikim
- * @param filename1 - the first image
- * @param filename2 - the second image
- * @return integer - count that has the similarity within images
- */
- public static int compareFeature(String filename1, String filename2) {
- int retVal = 0;
- long startTime = System.currentTimeMillis();
- System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
- // Load images to compare
- Mat img1 = Imgcodecs.imread(filename1, Imgcodecs.CV_LOAD_IMAGE_COLOR);
- Mat img2 = Imgcodecs.imread(filename2, Imgcodecs.CV_LOAD_IMAGE_COLOR);
- // Declare key point of images
- MatOfKeyPoint keypoints1 = new MatOfKeyPoint();
- MatOfKeyPoint keypoints2 = new MatOfKeyPoint();
- Mat descriptors1 = new Mat();
- Mat descriptors2 = new Mat();
- // Definition of ORB key point detector and descriptor extractors
- FeatureDetector detector = FeatureDetector.create(FeatureDetector.ORB);
- DescriptorExtractor extractor = DescriptorExtractor.create(DescriptorExtractor.ORB);
- // Detect key points
- detector.detect(img1, keypoints1);
- detector.detect(img2, keypoints2);
- // Extract descriptors
- extractor.compute(img1, keypoints1, descriptors1);
- extractor.compute(img2, keypoints2, descriptors2);
- // Definition of descriptor matcher
- DescriptorMatcher matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE_HAMMING);
- // Match points of two images
- MatOfDMatch matches = new MatOfDMatch();
- // System.out.println("Type of Image1= " + descriptors1.type() + ", Type of Image2= " + descriptors2.type());
- // System.out.println("Cols of Image1= " + descriptors1.cols() + ", Cols of Image2= " + descriptors2.cols());
- // Avoid to assertion failed
- // Assertion failed (type == src2.type() && src1.cols == src2.cols && (type == CV_32F || type == CV_8U)
- if (descriptors2.cols() == descriptors1.cols()) {
- matcher.match(descriptors1, descriptors2 ,matches);
- // Check matches of key points
- DMatch[] match = matches.toArray();
- double max_dist = 0; double min_dist = 100;
- for (int i = 0; i < descriptors1.rows(); i++) {
- double dist = match[i].distance;
- if( dist < min_dist ) min_dist = dist;
- if( dist > max_dist ) max_dist = dist;
- }
- System.out.println("max_dist=" + max_dist + ", min_dist=" + min_dist);
- // Extract good images (distances are under 10)
- for (int i = 0; i < descriptors1.rows(); i++) {
- if (match[i].distance <= 10) {
- retVal++;
- }
- }
- System.out.println("matching count=" + retVal);
- }
- long estimatedTime = System.currentTimeMillis() - startTime;
- System.out.println("estimatedTime=" + estimatedTime + "ms");
- return retVal;
- }
- }
이미지 파일 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 이미지 유사도 비교 #2 - 히스토그램 비교
'Cloud&BigData > Machine Learing' 카테고리의 다른 글
OpenCV 이미지 유사도 비교 #2 - 히스토그램 비교 (7) | 2015.09.24 |
---|---|
OpenCV 자바 이클립스에서의 프로그래밍 시작하기~ (0) | 2015.09.11 |
OpenCV 설치 및 자바 이클립스 환경 설정~ (0) | 2015.09.08 |
OpenCV를 활용한 이미지 유사도 비교 방법~ (2) | 2015.08.04 |
F Measure - Precision과 Recall을 통합한 정확도 측정 (1) | 2015.08.03 |
- Total
- Today
- Yesterday
- r
- 구글
- java
- 애플
- SCORM
- XML
- mysql
- 모바일
- 자바스크립트
- 클라우드
- 맥
- 아이폰
- 세미나
- 마케팅
- 책
- 웹
- 프로젝트
- 도서
- 하둡
- fingra.ph
- 자바
- Hadoop
- 통계
- 빅데이터
- 분석
- 안드로이드
- 디자인
- HTML
- ms
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |