在MATLAB中匹配具有不同方向和比例的图像

Matching images with different orientations and scales in MATLAB

我有两张相似但方向和大小不同的图片。示例如下:

enter image description hereenter image description here

有没有办法匹配这两张图片?

我使用了Procrustes形状分析,但还有其他方法吗?


这是一些让你开始的东西。您所要求的是一个称为图像注册的经典问题。图像配准寻求找到正确的同形性,采取一个图像和另一个对齐。这涉及到寻找两个图像之间的共同兴趣或关键点,并确定两个图像之间匹配的关键点。一旦你有了这些点对,你就可以确定一个同形矩阵,并扭曲其中一个图像,使它们与另一个图像与这个矩阵对齐。好的。

我假设你有计算机视觉和图像处理工具箱,它们是Matlab的一部分。如果你不这样做,那么莫里斯给出的答案是一个很好的选择,VLFEAT工具箱也是我使用过的。好的。

首先,让我们直接从stackoverflow中读取图像:好的。

1
2
3
4
5
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中的任何特征检测算法。我将使用冲浪,因为它本质上和筛一样,但有一些细微但关键的区别。您可以使用cvst工具箱中的detectSURFFeatures函数,它接受灰度图像。输出是一种结构,其中包含一系列关于图像检测到的每个特征点的信息。让我们将其应用于两个图像(灰度)。好的。

1
2
points = detectSURFFeatures(im_gray);
points2 = detectSURFFeatures(im2_gray);

一旦我们检测到这些特性,现在是时候提取描述这些关键点的描述符了。这可以用extractFeatures来完成。它接收灰度图像和从detectSURFFeatures输出的相应结构。输出是经过一些后处理后的一组特征和有效的关键点。好的。

1
2
[features1, validPoints1] = extractFeatures(im_gray, points);
[features2, validPoints2] = extractFeatures(im2_gray, points2);

现在是时候在这两张图片之间匹配特征了。这可以用matchFeatures来完成,并且它在两个图像之间具有以下特征:好的。

1
indexPairs = matchFeatures(features1, features2);

indexPairs是一个二维数组,其中第一列告诉您第一个图像中的哪个特征点与第二个图像中存储在第二列中的那些特征点相匹配。我们将使用这个索引到我们的有效点中,以充实实际匹配的内容。好的。

1
2
matchedPoints1 = validPoints1(indexPairs(:, 1), :);
matchedPoints2 = validPoints2(indexPairs(:, 2), :);

然后,我们可以用这样的showMatchedFeatures来显示匹配的点。我们可以将两个图像并排放置,并在匹配的关键点之间绘制线,以查看哪一个匹配。好的。

1
2
figure;
showMatchedFeatures(im, im2, matchedPoints1, matchedPoints2, 'montage');

这就是我得到的:好的。

enter image description here好的。

它不是完美的,但它肯定能在两幅图像之间找到一致的匹配。好的。

现在我们接下来要做的是找到同形矩阵并扭曲图像。我将使用estimateGeometricTransform,这样我们就可以找到一个将一组点扭曲到另一组点的转换。正如迪玛在下面对我的评论中所指出的,这有力地决定了通过RANSAC得到的最佳同形矩阵。我们可以这样称呼estimateGeometricTransform:好的。型

1
2
tform = estimateGeometricTransform(matchedPoints1.Location,...
     matchedPoints2.Location, 'projective');

第一个输入接受一组输入点,这些点是要转换的点。第二个输入接受一组基点,这些基点是参考点。这些点是我们想要匹配的。好的。型

在我们的例子中,我们要扭曲第一个图像的点-站起来的人,使它与第二个图像匹配-人靠在他身边,所以第一个输入是第一个图像的点,第二个输入是第二个图像的点。好的。型

对于匹配的点,我们要引用Location字段,因为这些字段包含两个图像之间匹配的实际点的坐标。我们还使用projective来计算比例、剪切和旋转。输出是一个包含点转换的结构。好的。型

接下来我们要做的是使用imwarp来扭曲第一个图像,使其与第二个图像对齐。好的。型

1
out = imwarp(im, tform);

out将包含我们的扭曲图像。如果我们并排显示第二个图像和这个输出图像:好的。型

1
2
3
4
5
figure;
subplot(1,2,1);
imshow(im2);
subplot(1,2,2);
imshow(out);

这就是我们得到的:好的。型

enter image description here。好的。型

我会说那很好,你不觉得吗?好的。型

为了您复制和粘贴的乐趣,以下是完整代码的外观:好的。型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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);

。旁白

记住,我使用了所有的默认参数…因此,detectSURFFeaturesmatchFeatures等,您可能需要使用参数来在尝试的不同图像对上获得一致的结果。我把这个留给你做练习。看看上面我链接的所有关于每个函数的链接,这样你就可以随意使用参数来满足你的口味。好的。型

玩得开心,祝你好运!好的。型好啊。


查看计算机视觉系统工具箱中的自动特征匹配示例,查找图像旋转和缩放。

enter image description here

它演示了如何检测兴趣点、提取和匹配特征描述符以及计算两幅图像之间的转换。


您可以通过以下操作获得合理的结果:

  • 检测两个图像中的筛选点。例如VLFEAT库。
  • 使用lowe规则匹配sift描述符,由vlfeat与vl_ubcmatch实现。
  • 使用ransac查找符合某些同形H的匹配点子集。使用harris特征点的示例可以在Peter Kovesi网站上看到,靠近ransac本身和其他有用功能。

初始结果:

enter image description here


这是一种与其他方法不同的方法。基于特性的注册方法更为健壮,但我的方法可能只对您的应用程序有用,所以我将在这里写下来。

  • 加载参考图像(我称之为模型)和要与模型比较的图像
  • 计算两幅图像的直方图
  • 比较两个柱状图。有很多方法可以做到这一点。这里我将使用交叉和相关
  • 柱状图交集:计算柱状图交集,并将其除以模型柱状图中的像素数进行归一化。这将给您一个介于0和1之间的值。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    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。