我有以下来自emgu opencv包装器的示例
HomographyMatrix homography = null;
SURFDetector surfCPU = new SURFDetector(500,true);
VectorOfKeyPoint modelKeyPoints;
VectorOfKeyPoint observedKeyPoints;
Matrix<int> indices;
Matrix<byte> mask;
int k = 2;
double uniquenessThreshold = 0.9; //0.8
//extract features from the object image
modelKeyPoints = surfCPU.DetectKeyPointsRaw(modelImage, null);
Matrix<float> modelDescriptors = surfCPU.ComputeDescriptorsRaw(modelImage, null, modelKeyPoints);
modelImage.Dispose();
// extract features from the observed image
observedKeyPoints = surfCPU.DetectKeyPointsRaw(observedImage, null);
Matrix<float> observedDescriptors = surfCPU.ComputeDescriptorsRaw(observedImage, null, observedKeyPoints);
observedImage.Dispose();
BruteForceMatcher<float> matcher = new BruteForceMatcher<float>(DistanceType.L2);
matcher.Add(modelDescriptors);
indices = new Matrix<int>(observedDescriptors.Rows, k);
using (Matrix<float> dist = new Matrix<float>(observedDescriptors.Rows, k))
{
matcher.KnnMatch(observedDescriptors, indices, dist, k, null);
mask = new Matrix<byte>(dist.Rows, 1);
mask.SetValue(255);
Features2DToolbox.VoteForUniqueness(dist, uniquenessThreshold, mask);
}
//...
应用 KnnMatch 后,如何获取匹配的关键点数,非零像素计数与获得 2 张图像之间的相似性有什么关系?
即使邻居很远,k-NN 也总是会找到一个"最近"的邻居。因此,如果您的图像有 1000 个兴趣点,则它们都将与另一个图像中的一个兴趣点匹配,即使另一个图像具有或多或少的兴趣点。
匹配的数量与 2 张图像之间的相似性没有直接关系,因为匹配集包含"良好"匹配(内在),但也包含许多错误匹配(异常值)。
匹配后,您应该过滤匹配(通过使用 VoteForUniqueness 和 VoteForSizeAndOrientation),然后尝试查找单应性矩阵。然后,您可以计算有多少匹配项验证了同形异义词。这些匹配是内在,相似性与内数的相关性更高一些。
您可以在本文中获得更详细的信息:
[Augereau, O., Journet, N., & Domenger, J. P. (2013年2月)。半结构化文档图像匹配和识别。在 DRR。
-
请参阅 OpenCV 文档 http://www.opencv.org.cn/opencvdoc/2.3.2/html/modules/features2d/doc/common_interfaces_of_descriptor_matchers.html
void DescriptorMatcher::knnMatch(const Mat&queryDescriptors, vector>& matches, int k, const vector& masks=vector(), bool compactResult=false )
匹配项(在您的代码中是 dist)– 匹配项。对于同一查询描述符,每个匹配项 [i] 都是 k 个或更少的匹配项。k – 每个查询描述符找到的最佳匹配项计数,如果查询描述符的可能匹配项总数少于 k 个,则更少。
-
关于相似性(我不清楚这个问题),代码使用的是 L2 距离。
BruteForceMatcher matcher = new BruteForceMatcher(DistanceType.L2);