It's comparing image similarity using feature matching.
I've used OpenCV and converted c language to java.
The source is as follows:
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;
}
}
I created a new function, compareFeature that is compared two images.
It calculates the distance of the feature in those images.
If you check the last of the source, I decide the similarity by the minimum distance of two images.
The distance value that I choose is 10.
But if you try more and more, the value is more precise.
If it is one more, I think that the two images are similar.
I tested next 3 images.
When I checked image1.jpeg and image1.jpeg, the result is identical.
If I checked image1.jpeg and image2.jpeg, the result is similar.
If I checked image1.jpeg and image3.jpeg, the result is not similar.





