在 MATLAB 中匹配具有不同方向和比例的图像
Posted
技术标签:
【中文标题】在 MATLAB 中匹配具有不同方向和比例的图像【英文标题】:Matching images with different orientations and scales in MATLAB 【发布时间】:2015-05-21 12:57:11 【问题描述】:我有两张相似但方向和大小不同的图像。下面是一个例子:
有没有办法匹配这两个图像?
我用过 Procrustes 形状分析,还有其他方法吗?
【问题讨论】:
您需要使用对数极坐标比较...不知道它是否已经在matlab或matlab工具箱中实现... 我会使用图像配准。找到一组在两个图像之间匹配的关键点,然后找到一个将两者对齐在一起的单应性/变换矩阵。顺便说一句,在我写答案之前,你有计算机视觉工具箱吗? 这可能会给你一些想法:Algorithm improvement for Coca-Cola can shape recognition @kkuilla - 很棒的链接。我喜欢那个已经有一段时间了。 【参考方案1】:这里有一些东西可以帮助您入门。您要的是一个经典问题,称为image registration。图像配准旨在找到正确的单应性,将一张图像与另一张图像对齐。这涉及找到两个图像之间共有的兴趣点或关键点,并确定哪些关键点在两个图像之间匹配。一旦你有了这些点对,你就可以确定一个单应矩阵并扭曲其中一个图像,以便它们与另一个与这个矩阵对齐。
我将假设您拥有属于 MATLAB 的计算机视觉和图像处理工具箱。如果您不这样做,那么 Maurits 给出的答案是一个不错的选择,VLFeat Toolbox 也是我用过的。
首先,让我们直接从 *** 中读取图像:
im = imread('http://i.stack.imgur.com/vXqe8.png');
im2 = imread('http://i.stack.imgur.com/Pd7pt.png');
im_gray = rgb2gray(im);
im2_gray = rgb2gray(im2);
我们还需要转换为灰度,因为关键点检测算法需要灰度图像。接下来,我们可以使用任何属于 MATLAB CVST 的特征检测算法……我将使用SURF,因为它与 SIFT 基本相同,但有一些细微但关键的区别。您可以使用 detectSURFFeatures
函数,它是 CVST 工具箱的一部分,它接受灰度图像。输出是一个结构,其中包含有关算法为图像检测到的每个特征点的信息。让我们将其应用于两张图像(灰度)。
points = detectSURFFeatures(im_gray);
points2 = detectSURFFeatures(im2_gray);
一旦我们检测到特征,现在是时候提取描述这些关键点的描述符了。这可以通过extractFeatures
完成。这需要一个灰度图像和从detectSURFFeatures
输出的相应结构。输出是经过一些后处理后的一组特征和有效关键点。
[features1, validPoints1] = extractFeatures(im_gray, points);
[features2, validPoints2] = extractFeatures(im2_gray, points2);
现在是时候匹配两张图片之间的特征了。这可以通过matchFeatures
完成,它会吸收两个图像之间的特征:
indexPairs = matchFeatures(features1, features2);
indexPairs
是一个二维数组,其中第一列告诉您第一张图像中的哪个特征点与第二张图像中的特征点匹配,存储在第二列中。我们将使用它来索引我们的有效点以充实实际匹配的内容。
matchedPoints1 = validPoints1(indexPairs(:, 1), :);
matchedPoints2 = validPoints2(indexPairs(:, 2), :);
然后我们可以像这样使用showMatchedFeatures
来显示哪些点匹配。我们可以将两个图像并排放置,并在匹配的关键点之间画线,看看哪个匹配。
figure;
showMatchedFeatures(im, im2, matchedPoints1, matchedPoints2, 'montage');
这是我得到的:
它并不完美,但它肯定会在两张图片之间找到一致的匹配。
现在我们接下来需要做的是找到单应矩阵并扭曲图像。我将使用estimateGeometricTransform
,以便我们可以找到一个将一组点扭曲到另一组的转换。正如 Dima 在下面给我的 cmets 中指出的那样,这个稳健地通过 RANSAC 确定了最佳单应矩阵。我们可以这样调用estimateGeometricTransform
:
tform = estimateGeometricTransform(matchedPoints1.Location,...
matchedPoints2.Location, 'projective');
第一个输入接受一组 输入 点,这些点是您要转换的点。第二个输入接受一组 base points,它们是 reference 点。这些点是我们想要匹配的。
在我们的例子中,我们想要扭曲第一张图像中的点 - 站立的人并使其匹配第二张图像 - 倾斜的人,因此第一个输入是来自第一张图像的点,第二个输入是来自第二个图像的点。
对于匹配的点,我们希望引用Location
字段,因为它们包含两个图像之间实际匹配点的坐标。我们还使用projective
来说明缩放、剪切和旋转。输出是一个结构,其中包含我们的点变换。
我们接下来要做的是使用imwarp
来扭曲第一个图像,使其与第二个图像对齐。
out = imwarp(im, tform);
out
将包含我们扭曲的图像。如果我们并排显示第二张图像和这个输出图像:
figure;
subplot(1,2,1);
imshow(im2);
subplot(1,2,2);
imshow(out);
这是我们得到的:
我会说这很不错,你不觉得吗?
为了您的复制和粘贴乐趣,完整的代码如下所示:
im = imread('http://i.stack.imgur.com/vXqe8.png');
im2 = imread('http://i.stack.imgur.com/Pd7pt.png');
im_gray = rgb2gray(im);
im2_gray = rgb2gray(im2);
points = detectSURFFeatures(im_gray);
points2 = detectSURFFeatures(im2_gray);
[features1, validPoints1] = extractFeatures(im_gray, points);
[features2, validPoints2] = extractFeatures(im2_gray, points2);
indexPairs = matchFeatures(features1, features2);
matchedPoints1 = validPoints1(indexPairs(:, 1), :);
matchedPoints2 = validPoints2(indexPairs(:, 2), :);
figure;
showMatchedFeatures(im, im2, matchedPoints1, matchedPoints2, 'montage');
tform = estimateGeometricTransform(matchedPoints1.Location,...
matchedPoints2.Location, 'projective');
out = imwarp(im, tform);
figure;
subplot(1,2,1);
imshow(im2);
subplot(1,2,2);
imshow(out);
一边
请记住,我对所有内容都使用了 默认 参数...所以detectSURFFeatures
、matchFeatures
等。您可能需要使用这些参数才能在不同的环境中获得一致的结果您尝试的图像对。我会把它留给你作为练习。查看我在上面链接的关于每个函数的所有链接,以便您可以根据自己的喜好调整参数。
玩得开心,祝你好运!
【讨论】:
cp2tform
已被弃用。使用fitgeotform
进行线性最小二乘拟合,或使用estimateGeometricTrasnform
使用RANSAC 进行稳健拟合。此外,imtransform
已被弃用,取而代之的是 imwarp
。
@Dima - fitgeotform
我没有,这就是我使用cp2tform
的原因。我正在使用 MATLAB R2013a。如果我有更新版本的 MATLAB,我肯定会使用 fitgeotform
。我确实有imwarp
。 FWIW,非常感谢您的提示。
@Dima - 不错。看起来我有estimateGeometricTransform
。我要修改我的答案。
对于特征匹配 estimateGeometricTransform
更好,因为它对异常值具有鲁棒性。如果您有旧版本,则可以使用 vision.GeometricTransformEstimator
对象。
@rayryeng +1 这是在 MATLAB 中使用 OpenCV 的类似方法(使用 mexopencv 作为包装器):***.com/a/20481266/97160【参考方案2】:
查看计算机视觉系统工具箱中的 Find Image Rotation and Scale Using Automated Feature Matching 示例。
它展示了如何检测兴趣点、提取和匹配特征描述符,以及计算两幅图像之间的转换。
【讨论】:
@rayryeng,有很多。你应该检查一下:) mathworks.com/help/vision/examples.html【参考方案3】:您可以通过以下方式获得合理的结果:
检测两个图像中的 SIFT 点。例如 vlfeat 库。 使用 Lowe 规则匹配 SIFT 描述符,由 vlfeat 实现,vl_ubcmatch
使用 RANSAC 查找符合某些单应性 H 的匹配点子集。使用 Harris 特征点的示例可以在Peter Kovesi 的站点上看到,在 RANSAC 本身和其他有用功能旁边。
初步结果:
【讨论】:
【参考方案4】:这是一种与其他方法截然不同的方法。基于特征的注册方法更健壮,但我的方法可能对你的应用程序有用,所以我在这里写下来。
加载参考图像(我称之为模型)和您要与模型比较的图像 计算两张图片的直方图 比较两个直方图。有很多方法可以做到这一点。这里我将使用交集和相关性Histogram Intersection :计算直方图的交点,并通过将其除以模型直方图中的像素数对其进行归一化。这将为您提供一个介于 0 和 1 之间的值。
image = imread('Pd7pt.png');
model = imread('vXqe8.png');
grImage = rgb2gray(image);
grModel = rgb2gray(model);
hImage = imhist(grImage);
hModel = imhist(grModel);
normhistInterMeasure = sum(min(hImage, hModel))/sum(hModel)
corrMeasure = corr2(hImage, hModel)
对于交集和相关,我分别得到 0.2492 和 0.9999。
【讨论】:
以上是关于在 MATLAB 中匹配具有不同方向和比例的图像的主要内容,如果未能解决你的问题,请参考以下文章
使用模板图像来匹配使用opencv的具有比例、旋转变化和部分遮挡的目标[重复]