我正在为我的大学做一个项目,我们想要一个四轴飞行器用他的相机稳定自己。不幸的是,基本矩阵对特征点内的微小变化 react 非常敏感,稍后我会给你举个例子。
多亏了 ocv,我认为我的匹配已经很好用了。 我正在使用 SURF 功能并将它们与 knn-Method 相匹配:
SurfFeatureDetector surf_detect;
surf_detect = SurfFeatureDetector(400);
//detect keypoints
surf_detect.detect(fr_one.img, fr_one.kp);
surf_detect.detect(fr_two.img, fr_two.kp);
//extract keypoints
SurfDescriptorExtractor surf_extract;
surf_extract.compute(fr_one.img, fr_one.kp, fr_one.descriptors);
surf_extract.compute(fr_two.img, fr_two.kp, fr_two.descriptors);
//match keypoints
vector<vector<DMatch> > matches1,matches2;
vector<DMatch> symMatches,goodMatches;
FlannBasedMatcher flann_match;
flann_match.knnMatch(fr_one.descriptors, fr_two.descriptors, matches1,2);
flann_match.knnMatch(fr_two.descriptors, fr_one.descriptors, matches2,2);
//test matches in both ways
symmetryTest(matches1,matches2,symMatches);
std::vector<cv::Point2f> points1, points2;
for (std::vector<cv::DMatch>::const_iterator it= symMatches.begin();
it!= symMatches.end(); ++it)
{
//left keypoints
float x= fr_one.kp[it->queryIdx].pt.x;
float y= fr_one.kp[it->queryIdx].pt.y;
points1.push_back(cv::Point2f(x,y));
//right keypoints
x = fr_two.kp[it->trainIdx].pt.x;
y = fr_two.kp[it->trainIdx].pt.y;
points2.push_back(cv::Point2f(x,y));
}
//kill outliers with ransac
vector<uchar> inliers(points1.size(),0);
findFundamentalMat(Mat(points1),Mat(points2),
inliers,CV_FM_RANSAC,3.f,0.99f);
std::vector<uchar>::const_iterator
itIn= inliers.begin();
std::vector<cv::DMatch>::const_iterator
itM= symMatches.begin();
for ( ;itIn!= inliers.end(); ++itIn, ++itM)
{
if (*itIn)
{
goodMatches.push_back(*itM);
}
}
现在我想用这些匹配计算基本矩阵。我在这个例子中使用了 8POINT 方法 - 我已经用 LMEDS 和 RANSAC 尝试过 - 它只会变得更糟,因为有更多匹配发生变化。
vector<int> pointIndexes1;
vector<int> pointIndexes2;
for (vector<DMatch>::const_iterator it= goodMatches.begin();
it!= goodMatches.end(); ++it) {
pointIndexes1.push_back(it->queryIdx);
pointIndexes2.push_back(it->trainIdx);
}
vector<Point2f> selPoints1, selPoints2;
KeyPoint::convert(fr_one.kp,selPoints1,pointIndexes1);
KeyPoint::convert(fr_two.kp,selPoints2,pointIndexes2);
Mat F = findFundamentalMat(Mat(selPoints1),Mat(selPoints2),CV_FM_8POINT);
当我在同一对图像的循环中调用这些计算时,F 的结果变化很大 - 无法从此类计算中提取运动。
我生成了一个示例,其中我过滤掉了一些匹配项,以便您可以自己看到我提到的效果。
http://abload.de/img/div_c_01ascel.png
http://abload.de/img/div_c_02zpflj.png
是我的代码有问题还是我必须考虑图像质量等其他原因?
在此先感谢您的帮助! 怪胎
最佳答案
总结其他人已经陈述的内容并更详细地阐述,
正如目前在 OpenCV 中实现的那样,8 点算法没有异常值拒绝。它是一种最小二乘算法,不能与 RANSAC 或 LMEDS 一起使用,因为这些标志 override the 8-point flag .建议对输入点进行归一化,以提高线性方程中矩阵的条件数,如"In Defence of the 8-point Algorithm"所述。 .但是,OpenCV 实现 automatically normalizes the input points ,因此无需手动对它们进行归一化。
使用 RANSAC 或 LMEDS,5 点和 7 点算法都具有离群值拒绝。如果您正在使用 RANSAC,您可能需要调整阈值以获得良好的结果。 OpenCV documentation显示 RANSAC 的默认阈值是 1.0,在我看来这有点大。我可能会推荐使用大约 0.1 像素的东西。另一方面,如果您使用的是 LMEDS,则无需担心阈值,因为 LMEDS 会最小化中值误差而不是计算内点。如果使用正确的阈值,LMEDS 和 RANSAC 都具有相似的精度,并且两者的计算时间相当。
5-point algorithm比 7 点算法更稳健,因为它只有 5 个自由度(3 个旋转和 2 个用于单位 vector 平移)而不是 7 个(额外的 2 个参数用于相机主点)。这种最小的参数化允许旋转和平移为 easily extracted from the matrix using SVD并避免 planar structure degeneracy problem .
但是,为了使用 5 点算法获得准确的结果,必须知道焦距。该论文建议焦距应在 10% 以内已知,否则 5 点算法并不比其他未校准算法好。如果您之前没有执行过相机校准,请查看 OpenCV camera calibration tutorial .此外,如果您使用的是 ROS,则有一个不错的 camera calibration package .
使用 OpenCV findEssentialMat function 时我建议首先将像素点传递给 undistortPoints .这不仅逆转了镜头畸变的影响,而且将坐标转换为归一化图像坐标。归一化图像坐标(不要与 8 点算法中的归一化混淆)是不依赖于任何相机固有参数的相机不可知坐标。它们表示方位 vector 与现实世界中的点的角度。例如,标准化图像坐标 (1, 0) 对应于相机光轴在 x 方向上的方位角为 45 度,在 y 方向上为 0 度。
在使用 RANSAC 获得良好假设后,可以使用迭代稳健非线性最小二乘法改进最佳估计。这是 mentioned in the paper并在 "Bundle Adjustment - A Modern Synthesis" 中进行了更详细的描述.不幸的是,OpenCV implementation 似乎5 点算法不使用任何迭代细化方法。
关于c++ - OpenCV findFundamentalMat 非常不稳定和敏感,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25251676/
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我使用的是Firefox版本36.0.1和Selenium-Webdrivergem版本2.45.0。我能够创建Firefox实例,但无法使用脚本继续进行进一步的操作无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055)错误。有人能帮帮我吗? 最佳答案 我遇到了同样的问题。降级到firefoxv33后一切正常。您可以找到旧版本here 关于ruby-无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055),我们在StackOverflow上找到一个类
如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:
Rails相对较新。我正在尝试调用一个API,它应该向我返回一个唯一的URL。我的应用程序中捆绑了HTTParty。我已经创建了一个UniqueNumberController,并且我已经阅读了几个HTTParty指南,直到我想要什么,但也许我只是有点迷路,真的不知道该怎么做。基本上,我需要做的就是调用API,获取它返回的URL,然后将该URL插入到用户的数据库中。谁能给我指出正确的方向或与我分享一些代码? 最佳答案 假设API为JSON格式并返回如下数据:{"url":"http://example.com/unique-url"
我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我
我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“
有没有办法让Ruby能够做这样的事情?classPlane@moved=0@x=0defx+=(v)#thisiserror@x+=v@moved+=1enddefto_s"moved#{@moved}times,currentxis#{@x}"endendplane=Plane.newplane.x+=5plane.x+=10putsplane.to_s#moved2times,currentxis15 最佳答案 您不能在Ruby中覆盖复合赋值运算符。任务在内部处理。您应该覆盖+,而不是+=。plane.a+=b与plane.a=
我想在ruby中生成一个64位整数。我知道在Java中你有很多渴望,但我不确定你会如何在Ruby中做到这一点。另外,64位数字中有多少个字符?这是我正在谈论的示例......123456789999。@num=Random.rand(9000)+Random.rand(9000)+Random.rand(9000)但我认为这是非常低效的,必须有一种更简单、更简洁的方法来做到这一点。谢谢! 最佳答案 rand可以将范围作为参数:pa=rand(2**32..2**64-1)#=>11093913376345012184putsa.
出于某种原因,heroku尝试要求dm-sqlite-adapter,即使它应该在这里使用Postgres。请注意,这发生在我打开任何URL时-而不是在gitpush本身期间。我构建了一个默认的Facebook应用程序。gem文件:source:gemcuttergem"foreman"gem"sinatra"gem"mogli"gem"json"gem"httparty"gem"thin"gem"data_mapper"gem"heroku"group:productiondogem"pg"gem"dm-postgres-adapter"endgroup:development,:t
我刚刚在我的Ubuntu9.10服务器上安装了TeamBox。我使用提供的服务器脚本在端口3000上启动并运行它。它的运行速度非常慢,从另一台计算机连接时每个HTTP请求最多需要30秒。我使用链接从shell加载TeamBox,一点也不花时间。然后我设置了一个SSH隧道,它再次运行得非常快。我通过此服务器上的apache以及SAMBA等运行了大约30个虚拟主机,没有任何问题。我该如何解决这个问题? 最佳答案 我的redmine(ruby,webrick)太慢了。现在我解决了这个问题:apt-getinstallmongrelruby