我修改了OpenCV演示应用程序“matching_to_many_images.cpp”,以查询图像(左)到网络摄像头的帧(右)。第一张图片的右上角出了什么问题?
我们认为这与我们遇到的另一个问题有关。我们从一个空的数据库开始,我们只添加唯一的(与我们数据库中的功能不匹配的功能),但在添加了三个功能后,我们得到了所有新功能的匹配....
我们正在使用: SurfFeatureDetector surfFeatureDetector(400,3,4); SurfDescriptorExtractor surfDescriptorExtractor; FlannBasedMatcher flannDescriptorMatcher;
完整代码可在以下网址找到:http://www.copypastecode.com/71973/
答案 0 :(得分:10)
我认为这与边界关键点有关。检测器检测关键点,但是为了使SURF描述符返回一致的值,它需要在其周围的像素块中的像素数据,这在边界像素中不可用。在检测到关键点之后但在计算描述符之前,您可以使用以下代码段删除边界点。我建议使用20或更多的borderSize。
removeBorderKeypoints( vector<cv::KeyPoint>& keypoints, const cv::Size imageSize, const boost::int32_t borderSize )
{
if( borderSize > 0)
{
keypoints.erase( remove_if(keypoints.begin(), keypoints.end(),
RoiPredicatePic((float)borderSize, (float)borderSize,
(float)(imageSize.width - borderSize),
(float)(imageSize.height - borderSize))),
keypoints.end() );
}
}
将RoiPredicatePic实施为:
struct RoiPredicatePic
{
RoiPredicatePic(float _minX, float _minY, float _maxX, float _maxY)
: minX(_minX), minY(_minY), maxX(_maxX), maxY(_maxY)
{}
bool operator()( const cv::KeyPoint& keyPt) const
{
cv::Point2f pt = keyPt.pt;
return (pt.x < minX) || (pt.x >= maxX) || (pt.y < minY) || (pt.y >= maxY);
}
float minX, minY, maxX, maxY;
};
此外,近似最近邻居索引不是匹配图像对之间的特征的最佳方式。我建议你尝试其他更简单的匹配器。
答案 1 :(得分:4)
你的方法完美无缺,但由于错误地调用了drawMatches函数,它显示错误的结果。
你的错误电话是这样的:
drawMatches(image2, image2Keypoints, image1, image1Keypoints, matches, result);
正确的电话应该是:
drawMatches(image1, image1Keypoints, image2, image2Keypoints, matches, result);
答案 2 :(得分:3)
我遇到了同样的问题。令人惊讶的是,该解决方案与边界点或KNN匹配器无关。只需要一个不同的匹配策略来过滤掉好的匹配&#34;来自过多的比赛。
使用2 NN搜索,以及以下条件 -
如果距离(第一场比赛)&lt; 0.6 *距离(第二场比赛)第一场比赛是&#34;好比赛&#34;。
过滤掉所有不满足上述条件的匹配项,并仅为#34;好匹配&#34;调用drawMatches。瞧!