将扫描(拍照)点集与模板点集(图像中的蓝色、绿色、红色、粉红色圆圈)匹配的最佳方法是什么?我正在使用 opencv/c++。也许某种ICP算法?我想将扫描图像包装到模板图像!
模板点集:
扫描点集:
将扫描(拍照)点集与模板点集(图像中的蓝色、绿色、红色、粉红色圆圈)匹配的最佳方法是什么?我正在使用 opencv/c++。也许某种ICP算法?我想将扫描图像包装到模板图像!
模板点集:
扫描点集:
你必须匹配红色矩形吗?原始图像在角落中包含四个黑色矩形,似乎是为了匹配而制作的。我可以用 4 行 Mathematica 代码可靠地找到它们:
lotto = [source image]
lottoBW = Image[Map[Max, ImageData[lotto], {2}]]
这需要每个像素的 max(R,G,B),即它过滤掉红色和黄色打印(或多或少)。结果如下所示:
然后我只使用一个 LoG 过滤器来找到暗点并在结果图像中寻找局部最大值
lottoBWG = ImageAdjust[LaplacianGaussianFilter[lottoBW, 20]]
MaxDetect[lottoBWG, 0.5]
结果:
如果对象是相当刚性和对齐的,简单的自相关就可以解决问题。如果没有,我会使用RANSAC来估计主题和模板之间的转换(看起来你有特征点)。请提供有关该问题的一些详细信息。
编辑: RANSAC(随机样本共识)可以用于您的情况。将模板中不必要的点视为噪声(特征检测器检测到的错误特征)——它们是轮廓线。RANSAC 可以处理大纲,因为它随机选择一小部分特征点(可以启动您的模型的最小数量),启动模型并计算您的模型与给定数据的匹配程度(模板中有多少其他点对应于您的其他点)。如果你选择了错误的子集,这个值会很低,你会放弃模型。如果您选择正确的子集,它会很高,您可以使用 LMS 算法改进您的匹配。
按着这些次序:
你看过 OpenCV 的descriptor_extractor_matcher.cpp样本吗?此示例使用 RANSAC 来检测两个输入图像之间的单应性。我想当你说包裹时,你实际上是指经线?如果您想使用检测到的单应矩阵扭曲图像,请查看warpPerspective函数。最后,这里有一些在 OpenCV 中使用不同特征检测器的好教程。
编辑: 您可能没有 SURF 功能,但您肯定有不同类别的特征点。基于特征的匹配通常分为两个阶段:特征检测(您已经完成)和匹配所需的提取。因此,您可以尝试将特征转换为KeyPoint,然后进行特征提取和匹配。下面是一个小代码片段,你可以如何去做:
typedef int RED_TYPE = 1;
typedef int GREEN_TYPE = 2;
typedef int BLUE_TYPE = 3;
typedef int PURPLE_TYPE = 4;
struct BenFeature
{
Point2f pt;
int classId;
};
vector<BenFeature> benFeatures;
// Detect the features as you normally would in addition setting the class ID
vector<KeyPoint> keypoints;
for(int i = 0; i < benFeatures.size(); i++)
{
BenFeature bf = benFeatures[i];
KeyPoint kp(bf.pt,
10.0, // feature neighborhood diameter (you'll probaby need to tune it)
-1.0, // (angle) -1 == not applicable
500.0, // feature response strength (set to the same unless you have a metric describing strength)
1, // octave level, (ditto as above)
bf.classId // RED, GREEN, BLUE, or PURPLE.
);
keypoints.push_back(kp);
}
// now proceed with extraction and matching...
您可能需要调整响应强度,使其不会被提取阶段阈值化。但是,希望这能说明您可能会尝试做的事情。