实际上,我正试图将从图像中提取的关键点列表与从另一个图像中提取的关键点列表相匹配。我尝试了SURF/SIFT来检测关键点,但从每张图像中检测到的关键点的准确性来看,结果并不像预期的那样。我想过不使用关键点检测器,只是使用连接区域的点,然后使用SIFT/SUFT计算这些点的描述符,但大多数时候调用计算方法将清空关键点列表。
下面的代码示例:
int minHessian = 100;
SurfFeatureDetector detector(minHessian);
Mat descriptors_object;
SurfDescriptorExtractor extractor;
detector.detect( img_object, keypoints_object);
extractor.compute( img_object, keypoints_object,descriptors_object );
for (int index = 0; index < listOfObjectsExtracted.size(); index ++)
{
Mat partOfImageScene = listOfObjectsExtracted[index];
vector<Point2f> listOfContourPoints = convertPointsToPoints2f(realContoursOfRects[index]);
vector<KeyPoint> keypoints_scene;
KeyPoint::convert(listOfContourPoints, keypoints_scene, 100, 1000);
//detector.detect( partOfImageScene, keypoints_scene );
if (keypoints_scene.size() > 0)
{
//-- Step 2: Calculate descriptors (feature vectors)
Mat descriptors_scene;
extractor.compute( partOfImageScene, keypoints_scene, descriptors_scene );
//Logic of matching between descriptors_scene and descriptors_object
}
}
因此,在步骤2中调用compute
之后,keypoints_scene大多数时候变为空。我知道他们在OpenCV文档中声明了以下内容:
注意,该方法可以通过删除这样的关键字没有定义描述符(通常)这些是图像边界附近的关键点)。这个方法确保了输出关键点和描述符彼此一致(以便关键点的数量等于描述符行计数)。
但是无论如何要得到更好的结果?我的意思是对我选择的所有点都有描述符?我是否违反了关键点的使用方式?我应该尝试不同的特征提取器比SIFT/SURF得到我想要的?或者在OpenCV中实现的每个特征检测器都有同样的问题?
:
我使用KeyPoint::convert
方法从点转换到关键点,我传递100作为大小,1000作为响应。下面您可以看到该方法的详细信息:
//! converts vector of points to the vector of keypoints, where each keypoint is assigned the same size and the same orientation
static void convert(const vector<Point2f>& points2f,
CV_OUT vector<KeyPoint>& keypoints,
float size=1, float response=1, int octave=0, int class_id=-1);
100的尺寸对我来说很好,不是吗?如果没有,有什么方法可以获得符合我情况的最佳价值?或者这只是经验之谈?
:图片大小:1920*1080,这里是一个示例
大多数情况下,它们靠近图像的边界。有什么问题吗?
我明白了。问题在于我计算描述符的方式,因为正如你在上面的代码中看到的,我试图计算图像的一小部分而不是图像本身的描述符。所以当我把图像本身而不是partOfImageScene
,像extractor.compute( img_scene, keypoints_scene, descriptors_scene );
这样的东西,它工作得很好,我没有从我的列表中丢失任何关键点。