如何在java中使用openCV检查两个图像是否相似?
我必须使用OpenCV检查两个图像在java中是否相似,我正在使用OpenCV和ORB 这是我的主课如何在java中使用openCV检查两个图像是否相似?,java,android,opencv,Java,Android,Opencv,我必须使用OpenCV检查两个图像在java中是否相似,我正在使用OpenCV和ORB 这是我的主课 System.out.println("Welcome to OpenCV " + Core.VERSION); System.loadLibrary(Core.NATIVE_LIBRARY_NAME);()); System.out.println(System.getProperty("user.dir")); File f1 = new File(System.getProperty("u
System.out.println("Welcome to OpenCV " + Core.VERSION);
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);());
System.out.println(System.getProperty("user.dir"));
File f1 = new File(System.getProperty("user.dir") + "\\test.jpg");
File f2 = new File(System.getProperty("user.dir") + "\\test2.jpg");
MatchingDemo2 m = new MatchingDemo2();
m.mth(f1.getAbsolutePath(), f2.getAbsolutePath());
这是我的匹配demo2.java文件
public class MatchingDemo2 {
public void mth(String inFile, String templateFile){
FeatureDetector detector = FeatureDetector.create(FeatureDetector.ORB);
//Create descriptors
//first image
// generate descriptors
//second image
// generate descriptors
System.out.println("size " + matches.size());
//HOW DO I KNOW IF IMAGES MATCHED OR NOT ????
//THIS CODE IS FOR CONNECTIONS BUT I AM NOT ABLE TO DO IT
//feature and connection colors
Scalar RED = new Scalar(255,0,0);
Scalar GREEN = new Scalar(0,255,0);
//output image
Mat outputImg = new Mat();
MatOfByte drawnMatches = new MatOfByte();
//this will draw all matches, works fine
Features2d.drawMatches(img1, keypoints1, img2, keypoints2, matches,
outputImg, GREEN, RED, drawnMatches, Features2d.NOT_DRAW_SINGLE_POINTS);
int DIST_LIMIT = 80;
List<DMatch> matchList = matches.toList();
List<DMatch> matches_final = new ArrayList<DMatch>();
for(int i=0; i<matchList.size(); i++){
if(matchList.get(i).distance <= DIST_LIMIT){
matches_final.add(matches.toList().get(i));
}
}
MatOfDMatch matches_final_mat = new MatOfDMatch();
matches_final_mat.fromList(matches_final);
for(int i=0; i< matches_final.size(); i++){
System.out.println("Good Matchs "+ matches_final.get(i));
}
}
}
对于相同的图像以及不同的图像,我得到的匹配数是相同的
我真的很困惑?您能解释一下如何比较两幅图像,并判断它们是否相似吗
我试图实现的是匹配器只搜索关键点图的最近匹配。对于度量差异,您需要使用距离的(平均)和(或其他度量)。因为您使用的是BRUTEFORCE matcher,所以您将始终从列车中的查询(模板)(包含查询的图像)中获得所有关键点描述符的最佳匹配。 i、 e:BRUTEFORCE matcher将始终找到100%的匹配(列车描述符中所有查询关键点描述符的最佳等效关键点) 这意味着您需要将匹配项筛选为正确匹配项(内联项)和不正确匹配项(异常值)匹配项 你可以用两种方法来做 1.距离计算 使用Andrey Smorodov提到的距离。你可以用这个方法 (但这并不总是提供正确的结果) 3.另一种更简单的方法是比较这两幅图像的直方图,您可以使用compHist()openCV的功能,如图所示 并参考openCV文档 比较直方图中的各种方法给出了从0到1或更高值的输出范围,该输出取决于直方图之间的相似性。在某些方法中小心1是100%正匹配,在其他方法中小心0。 “对于卡方检验法,低分表示比高分更好的匹配。完美匹配为0,总不匹配是无限的(取决于直方图的大小)。” 余数:-两个完全不同的图像可以具有完全相同的直方图值 小贴士: 1.现在关于knnMatch,只需使用matcher.knnMatch();以及输出的适当数据类型 2.也在
matcher.match(query, train, matches);
查询=>模板的关键点描述符,例如球和
包含相同球的图像的train=>关键点描述符。
查询描述符的数量小于列描述符的数量请确保这一点正确
现在祝你好运。上面您已经打印了“good Matchs DMatch[queryIdx=29,trainIdx=67,imgIdx=0,distance=49.0]”。获取所有距离,求和,按它们的数量(计算平均值)进行划分,这将成为你的相似性度量。对于同一图像与自身相比,我得到0作为平均值,对于不同的图像,我得到50-70作为平均值。但是它实际上没有正确地比较图像?我应该怎么做才能得到一个很好的匹配(除了使用SURF)?我还应该如何为比较的图像绘制位图?你可能需要PSNR之类的东西吗?然后看看。为什么你们认为你们得到的平均距离并没有相关的差异度量?您可以像这里描述的那样绘制覆盖图:如何在java中实现它?什么是keypointsRef Determine Mask?你能把你的项目上传到github上吗?另外,你提供的直方图链接不是图像,而是存储在数组中的直方图,所以我检查了,但我在转换代码方面有问题1)我在技巧中解释过,keypointRef是从包含名为train keypoints 2)Mask的对象是Calib3d.findHomography()中的可选输出;3) 无需在android中转换代码。您可以在android NDK中使用jni包装器。您可以在github上上载项目吗?我认为使用earthmover距离(而不是使用平均距离)可能是更好的距离度量。
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 <= (3 * min_dist)) // change the limit as you desire
good_matches.addLast(matchesList.get(i));
}
LinkedList<Point> objList = new LinkedList<Point>();
LinkedList<Point> sceneList = new LinkedList<Point>();
List<KeyPoint> keypoints_RefList = keypointsRef.toList();
List<KeyPoint> keypoints_List = keypoints.toList();
for (int i = 0; i < good_matches.size(); i++) {
objList.addLast(keypoints_RefList.get(good_matches.get(i).queryIdx).pt);
sceneList.addLast(keypoints_List.get(good_matches.get(i).trainIdx).pt);
}
MatOfPoint2f obj = new MatOfPoint2f();
MatOfPoint2f scene = new MatOfPoint2f();
obj.fromList(objList);
scene.fromList(sceneList);
Mat mask = new Mat();
Mat hg = Calib3d.findHomography(obj, scene, 8, 10, mask);
08-22 01:08:38.929: I/OCVSample::Activity(25799): Keypoints Size: 1x477 KeypointsRef Size : 1x165
08-22 01:08:39.049: I/OCVSample::Activity(25799): descriptor Size: 32x477 descriptorRef Size : 32x165
08-22 01:08:39.129: I/OCVSample::Activity(25799): Matches Size: 1x165
08-22 01:08:39.129: I/OCVSample::Activity(25799): matchesList Size: 165
08-22 01:08:39.139: I/OCVSample::Activity(25799): Max dist : 460.44110107421875 Min dist : 100.0
08-22 01:08:39.139: I/OCVSample::Activity(25799): good matches size: 19
08-22 01:08:39.139: I/OCVSample::Activity(25799): obj size : 1x165
08-22 01:08:39.139: I/OCVSample::Activity(25799): scene size : 1x165
08-22 01:08:40.239: I/OCVSample::Activity(25799): Homography mask size : 1x165
08-22 01:08:40.239: I/OCVSample::Activity(25799): Homography mask : [1; 1; 1; 1; 1; 1; 1; 0; 1; 0; 1; 1; 1; 1; 0; 1; 1; 1; 0; 1; 1; 1; 1; 0; 1; 0; 1; 1; 1; 1; 1; 1; 0; 0; 1; 1; 1; 1; 0; 1; 0; 1; 1; 1; 1; 1; 0; 1; 1; 1; 1; 1; 1; 1; 0; 1; 1; 0; 1; 0; 1; 0; 0; 1; 0; 1; 1; 1; 1; 1; 1; 1; 0; 1; 1; 1; 1; 1; 0; 1; 1; 1; 1; 0; 0; 1; 1; 0; 1; 1; 1; 1; 0; 1; 0; 1; 1; 1; 1; 1; 1; 1; 1; 1; 1; 1; 0; 1; 1; 1; 1; 0; 0; 0; 1; 0; 1; 1; 1; 1; 0; 0; 1; 1; 1; 1; 1; 0; 1; 0; 1; 1; 0; 1; 0; 1; 1; 1; 1; 1; 1; 0; 1; 1; 0; 1; 1; 1; 1; 0; 1; 1; 1; 1; 1; 1; 1; 0; 1; 1; 0; 0; 1; 1]
matcher.match(query, train, matches);