- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我是java android 开发者,我对C/C++ 或Matlab 函数了解不多。在我的代码中做的简单事情就是创建 sift/Surf 图像详细信息并将详细信息保存在 .yml 文件中。
这是我如何创建 sift 的代码
vector < KeyPoint > keypoints;
Mat descriptors;
// Create a SIFT keypoint detector.
SiftFeatureDetector detector;
detector.detect(image, keypoints);
LOGI("Detected %d keypoints\n", (int) keypoints.size());
// Compute feature description.
detector.compute(image, keypoints, descriptors);
将结果描述符保存在 (.yml) 文件中,然后使用 OpenCV 的 FlannBasedMatcher 比较该 yml 文件
这是我的代码
descriptors1 和 descriptors2 是从 .yml 文件创建的两个 mat 对象。
FlannBasedMatcher matcher;
vector<double> ee;
vector < DMatch > good_matches;
double good_matches_sum = 0.0;
vector < vector<DMatch> > matches;
matcher.knnMatch(descriptors1, descriptors2, matches, 2);
for (int i = 0; i < matches.size(); i++) {
if (matches[i][0].distance < 0.8 * matches[i][1].distance) {
good_matches.push_back(matches[i][0]);
good_matches_sum += matches[i][0].distance;
}
}
LOGI("good_matches_sum %d s\n", good_matches_sum);
LOGI("the distance k %f s\n", good_matches_sum);
double score = (double) good_matches_sum / (double) good_matches.size();
LOGI("score %f k %d s\n", score, good_matches.size());
问题出在上面的代码中,我每次都得到不同的结果。e
这里是我的两张图片
//first time run for two images
good_matches_sum 1006632960
the distance k 3054.279755
scores 254.523313 k 12 s
//Second time run for same two images
good_matches_sum -402653184
the distance k 2835.513489
score score scores 257.773954 k 11 s
//Third time run for same two images
good_matches_sum -1946157056
the distance k 2794.588959
score score scores 254.053542 k 11 s
我假设基于阳性结果和阴性结果的图像更纤细或不同。但是每次都有这种不同的结果,我无法判断图像是否相似。
请帮助我,我不知道 Opencv 和 c,所以如果有人有任何想法,请建议更正的代码。谢谢。
最佳答案
基本上,SIFT/SURF 无法判断两个图像是否相似。它只能告诉你一幅图像中的哪个关键点与另一幅图像中的哪个对应点相匹配。
幸运的是,这两个函数还为您提供了更多信息,例如匹配的“距离”以及图像中的匹配总数。
关于判断两张图片有多相似的想法:
1. Use findHomography() to get the homography of two images
2. Check whether the homography is valid (such as 4 of the points form a rectangle).
3. Count the number of "good" matches (match.distance < SOME_DISTANCE)
4. Use some math to generate a score
5. If the previous homography is valid, increase the score
这是我曾经用过的一段代码,还是有一些瑕疵(对于某些特定类型的比赛,得分不合理,但这种情况很少发生)。
注意,MY_****_DISTANCE
取决于您使用的是 SIFT 还是 SURF,以及您提供的 SIFT/SURF 函数的参数。
//===========SCORE ============
vector<double> matchDistance;
double avg = 0;
int avgCount = 0;
int goodCount = 0 ;
for( unsigned i = 0; i < matches.size(); i++ )
{
double dist = matches[i].distance;
//This is a "average match"
if( dist < MY_AVG_DISTANCE && dist > MY_LEAST_DISTANCE )
{
avg += dist; //Count the average of distance of "average matches"
avgCount++;
}
//This is a good match, and number of good match have a great impact on the result
//Good matches are also average matches, that is, {GOOD_MATCH} is a subset of {AVERAGE_MATCH}
if(dist < MY_GOOD_DISTANCE && dist > MY_LEAST_DISTANCE ){
goodCount++; //Count the number of "good matches"
}
}
if(avgCount > 6){
avg /= avgCount; //Gives the average value
if(goodCount < 12){ //If there are too few good matches, make a punishment
avg = avg + (12-goodCount) * 4;
}
}else{
avg = MY_MAX_DISTANCE;
}
avg = avg > MY_AVG_DISTANCE ? MY_AVG_DISTANCE : avg;
avg = avg < MY_MIN_DISTANCE ? MY_MIN_DISTANCE : avg;
double score_avg = (MY_AVG_DISTANCE - avg) / ( MY_AVG_DISTANCE - MY_MIN_DISTANCE ) * 100;
if(homography_valid){ //If the previous homography is valid, make a reward.
score_avg += 40;
score_avg = score_avg > 100 ? 100 : score_avg;
}else{
score_avg -= 5; //Or, make a little punishment
score_avg = score_avg < 0 ? 0 : score_avg;
}
return score_avg
My_****_DISTANCE
是我自己定义的,抱歉之前没有解释。这是我使用的值,但您可能希望更改它以更好地适合您的代码。
#define MY_MIN_DISTANCE 200
#define MY_GOOD_DISTANCE 310
#define MY_AVG_DISTANCE 350
#define MY_MAX_DISTANCE 500
#define MY_MIN_HESSIAN 2000
#define MY_LEAST_DISTANCE 100
当使用参数 SiftFeatureDetector detector(400, 3, 0.04, 10.0, 1.6);
运行 SIFT 时,一些“错误”匹配与一些“正确”匹配的结果是:
Wrong Right
307.993 330.124
470.419 307.374
219.775 371.026
294.389 400.696
355.321 259.239
331.926 189.042
222.317 457.089
320.718 379.061
423.09 201.95
371.098 200.646
362.427 343.229
441.167 359.32
253.253 382.15
367.191 215.678
405.19 358.686
390.251 343.798
341.905 238.002
341.073 226.519
363.775 262.5
340.742 174.877
320.214 415.802
249.405 195.261
347.357 328.76
343.839 116.331
351.058 383.93
286.224 111.472
352.976 138.701
298.409 238.044
385.34 223.716
264.571 331.115
333.339 208.103
329.588 128.168
372.971 267.83
331.804 222.578
301.935 232.459
351.504 342.524
300.762 379.87
346.872 390.031
374.281 308.198
304.746 401.452
307.184 193.298
229.943 98.0714
286.163 133.978
363.634 171.415
361.656 111.077
357.108 134.186
289.712 123.199
371.496 339.944
318.708 192.164
360.547 425.937
331.225 336.535
297.688 309.419
351.898 162.296
408.206 311.055
309.023 457.352
281.375 337.529
362.266 407.757
229.295 388.567
317.005 161.118
386.907 108.936
363.942 215.311
374.832 343.376
311.264 184.318
364.745 188.963
466.795 308.48
381.667 318.828
381.826 119.591
377.338 105.527
377.333 199.206
279.228 369.394
295.078 387.979
267.408 196.942
386.063 307.815
372.14 184.83
294.927
417.138
348.458
97.8621
234.199
144.094
172.377
131.412
250.503
227.139
233.32
116.258
205.331
354.505
95.0368
108.434
116.46
138.246
406.135
308.2
92.817
194.838
312.103
323.163
312.946
377.798
359.393
396.191
320.272
375.025
309.383
280.826
278.456
很明显,“错误”匹配的平均值大于“正确”匹配的平均值。但是如果你遍历很多图片,你会得到一些异常(比如错误匹配,匹配较少但平均距离较低),其中一些我还没有想出如何消除。因此,基于匹配距离的原始数据,你还必须做出一个相当“个人”的分数。
这是您可能需要的一段演示。
std::vector<Point2f> obj_corners(4);
obj_corners[0] = Point(0,0);
obj_corners[1] = Point( img_object.cols, 0 );
obj_corners[2] = Point( img_object.cols, img_object.rows );
obj_corners[3] = Point( 0, img_object.rows );
std::vector<Point2f> scene_corners(4);
Mat H = findHomography( obj, scene, RANSAC );
perspectiveTransform( obj_corners, scene_corners, H);
而且你可以找到in this tutorial的详细信息
这取决于您如何定义“有效”。看官方的例子,左图(“物体”图像)是右图(“场景”图像)的一部分。然后,将单应矩阵应用于“物体”图像的顶点 vector ,我们最终在右侧出现一个绿色四边形,它标记了“物体”图像所在的位置。
至于我,根据教程,我对“有效”的定义是: 1.四个点组成一个四边形 2、四边形的边长不能太小 3、四边形的角不能太小。 4、四边形不能倒置。
并执行一些基本数学运算,这是验证过程的一部分。
bool RectChecker::check_order(const vector<Point2f> &corners, int height, int width){
if(corners[0].y + 5 >= corners[3].y || corners[1].y + 5 >= corners[2].y){ //Point 0 should be above Point 3, so do Point1 and Point2
return false;
}
if(corners[0].x + 5 >= corners[1].x || corners[3].x + 5 >= corners[2].x){ //Point 0 should be on the left of Point 1, so do Point3 and Point2
return false;
}
int cnt = 0;
for(int i = 0 ; i < corners.size() ; i++){
if(corners[i].x < -30 || corners[i].x > width + 30){
cnt++;
continue;
}
if(corners[i].y < -20 || corners[i].y > height + 20){ //This point is outside the image
cnt++;
}
}
if(cnt == 4){ //All points are outside the image
return false;
}
return true;
}
再一次,您可能想要创建自己的验证过程,至于验证,这在很大程度上取决于您的要求。但在我看来,这部分是最简单的部分,而最本质的部分是评分过程。
关于android - 比较 .yml 文件 OpenCV 中的图像 SIFT/SURF 细节?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29830319/
今天我在一个 Java 应用程序中看到了几种不同的加载文件的方法。 文件:/ 文件:// 文件:/// 这三个 URL 开头有什么区别?使用它们的首选方式是什么? 非常感谢 斯特凡 最佳答案 file
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引起辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the he
我有一个 javascript 文件,并且在该方法中有一个“测试”方法,我喜欢调用 C# 函数。 c# 函数与 javascript 文件不在同一文件中。 它位于 .cs 文件中。那么我该如何管理 j
需要检查我使用的文件/目录的权限 //filePath = path of file/directory access denied by user ( in windows ) File fil
我在一个目录中有很多 java 文件,我想在我的 Intellij 项目中使用它。但是我不想每次开始一个新项目时都将 java 文件复制到我的项目中。 我知道我可以在 Visual Studio 和
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 这个问题似乎不是关于 a specific programming problem, a software
我有 3 个组件的 Twig 文件: 文件 1: {# content-here #} 文件 2: {{ title-here }} {# content-here #}
我得到了 mod_ldap.c 和 mod_authnz_ldap.c 文件。我需要使用 Linux 命令的 mod_ldap.so 和 mod_authnz_ldap.so 文件。 最佳答案 从 c
我想使用PIE在我的项目中使用 IE7。 但是我不明白的是,我只能在网络服务器上使用 .htc 文件吗? 我可以在没有网络服务器的情况下通过浏览器加载的本地页面中使用它吗? 我在 PIE 的文档中看到
我在 CI 管道中考虑这一点,我应该首先构建和测试我的应用程序,结果应该是一个 docker 镜像。 我想知道使用构建环境在构建服务器上构建然后运行测试是否更常见。也许为此使用构建脚本。最后只需将 j
using namespace std; struct WebSites { string siteName; int rank; string getSiteName() {
我是 Linux 新手,目前正在尝试使用 ginkgo USB-CAN 接口(interface) 的 API 编程功能。为了使用 C++ 对 API 进行编程,他们提供了库文件,其中包含三个带有 .
我刚学C语言,在实现一个程序时遇到了问题将 test.txt 文件作为程序的输入。 test.txt 文件的内容是: 1 30 30 40 50 60 2 40 30 50 60 60 3 30 20
如何连接两个tcpdump文件,使一个流量在文件中出现一个接一个?具体来说,我想“乘以”一个 tcpdump 文件,这样所有的 session 将一个接一个地按顺序重复几次。 最佳答案 mergeca
我有一个名为 input.MP4 的文件,它已损坏。它来自闭路电视摄像机。我什么都试过了,ffmpeg , VLC 转换,没有运气。但是,我使用了 mediainfo和 exiftool并提取以下信息
我想做什么? 我想提取 ISO 文件并编辑其中的文件,然后将其重新打包回 ISO 文件。 (正如你已经读过的) 我为什么要这样做? 我想开始修改 PSP ISO,为此我必须使用游戏资源、 Assets
给定一个 gzip 文件 Z,如果我将其解压缩为 Z',有什么办法可以重新压缩它以恢复完全相同的 gzip 文件 Z?在粗略阅读了 DEFLATE 格式后,我猜不会,因为任何给定的文件都可能在 DEF
我必须从数据库向我的邮件 ID 发送一封带有附件的邮件。 EXEC msdb.dbo.sp_send_dbmail @profile_name = 'Adventure Works Admin
我有一个大的 M4B 文件和一个 CUE 文件。我想将其拆分为多个 M4B 文件,或将其拆分为多个 MP3 文件(以前首选)。 我想在命令行中执行此操作(OS X,但如果需要可以使用 Linux),而
快速提问。我有一个没有实现文件的类的项目。 然后在 AppDelegate 我有: #import "AppDelegate.h" #import "SomeClass.h" @interface A
我是一名优秀的程序员,十分优秀!