二维点集匹配

时间:2011-12-08 09:36:21

标签: image-processing opencv computer-vision feature-detection

将扫描(拍摄的照片)点集与模板点集(图像中的蓝色,绿色,红色,粉色圆圈)匹配的最佳方法是什么? 我正在使用opencv / c ++。也许某种ICP算法?我想将扫描图像包装到模板图像中!

模板点集: template image

扫描点集: scan image

4 个答案:

答案 0 :(得分:1)

如果对象相当僵硬并且对齐,那么简单的auto-correlation就可以了。 如果没有,我会使用RANSAC来估计主题和模板之间的转换(似乎你有特征点)。请提供有关问题的一些细节。

修改 可以在您的情况下使用RANSAC(随机样本共识)。将模板中不必要的点视为噪声(特征检测器检测到的错误特征) - 它们是大纲。 RANSAC可以处理大纲,因为它会随机选择一小部分特征点(可以启动模型的最小量),启动模型并计算模型与给定数据的匹配程度(模板中有多少其他点对应于您的其他要点)。如果选择了错误的子集,则此值将很低,您将删除模型。如果您选择正确的子集,它将很高,您可以使用LMS算法改进匹配。

答案 1 :(得分:1)

你必须匹配红色矩形吗?原始图像在角落中包含四个黑色矩形,似乎制作以进行匹配。我可以通过4行Mathematica代码可靠地找到它们:

lotto = [source image]
lottoBW = Image[Map[Max, ImageData[lotto], {2}]]

这为每个像素取最大值(R,G,B),即它过滤掉红色和黄色打印(或多或少)。结果如下:

bw filter result

然后我只使用LoG滤镜找到暗点并在结果图像中查找局部最大值

lottoBWG = ImageAdjust[LaplacianGaussianFilter[lottoBW, 20]]
MaxDetect[lottoBWG, 0.5]

结果: enter image description here

答案 2 :(得分:0)

你看过OpenCV的descriptor_extractor_matcher.cpp样本了吗?该样本使用RANSAC来检测两个输入图像之间的单应性。我假设当你说包裹时你实际上意味着扭曲?如果您想使用您检测到的单应矩阵扭曲图像,请查看warpPerspective函数。最后,here是使用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...

您可能需要调整响应强度,使其在提取阶段不会被阈值化。但是,希望这可以说明你可能会尝试做什么。

答案 3 :(得分:0)

请按照以下步骤操作:

  1. 匹配两个图像中的点或要素,这将决定您的包装;
  2. 确定要为包装寻找的转换。最通用的是单应性(参见cv :: findHomography()),较不通用的是简单的翻译(使用cv :: matchTempalte())。中间案例将是沿x,y和旋转的平移。为此,我写了一个比Homography更好的快速函数,因为它使用较少的自由度,同时仍然优化正确的度量(坐标的平方差): https://stackoverflow.com/a/18091472/457687
  3. 如果您认为您的匹配有很多异常值,请在步骤1之上使用RANSAC。您基本上需要随机选择查找参数,求解,确定内点所需的最小点集,使用所有内点再次求解,以及然后迭代尝试改进当前的解决方案(增加内部数量,减少错误,或两者兼而有之)。请参阅Wikipedia for RANSAC算法:http://en.wikipedia.org/wiki/Ransac