8 matlab image image-processing computer-vision matlab-cvst
我有两个相似但方向和大小不同的图像.下面是一个例子:

有没有办法匹配这两个图像?
我使用了Procrustes形状分析,但还有其他方法吗?
ray*_*ica 17
这是让你入门的东西.您要求的是一个称为图像注册的经典问题.图像配准旨在找到一个正确的单应性,它可以拍摄一张图像并将其与另一张图像对齐.这涉及找到两个图像之间共同的兴趣或关键点,并确定哪两个关键点在两个图像之间匹配.一旦你有了这些点对,就可以确定单应矩阵并扭曲其中一个图像,使它们与另一个图像对齐.
我假设你有计算机视觉和图像处理工具箱,它们是MATLAB的一部分.如果你不这样做,那么Maurits给出的答案是一个很好的选择,VLFeat工具箱也是我用过的.
首先,让我们直接从StackOverflow读取图像:
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);
Run Code Online (Sandbox Code Playgroud)
我们还需要转换为灰度,因为关键点检测算法需要灰度图像.接下来,我们可以使用任何特征检测算法,它是MATLAB的CVST的一部分....我将使用SURF,因为它与SIFT基本相同,但有一些细微但关键的区别.您可以使用detectSURFFeaturesCVST工具箱的一部分功能,它接受灰度图像.输出是一种结构,其中包含有关算法为图像检测到的每个特征点的一组信息.让我们将它应用于两个图像(灰度).
points = detectSURFFeatures(im_gray);
points2 = detectSURFFeatures(im2_gray);
Run Code Online (Sandbox Code Playgroud)
一旦我们检测到这些特征,现在是时候提取描述这些关键点的描述符了.这可以做到extractFeatures.这将采用灰度图像和从中输出的相应结构detectSURFFeatures.在一些后处理之后,输出是一组特征和有效关键点.
[features1, validPoints1] = extractFeatures(im_gray, points);
[features2, validPoints2] = extractFeatures(im2_gray, points2);
Run Code Online (Sandbox Code Playgroud)
现在是时候匹配两个图像之间的功能.这可以通过matchFeatures以下两种图像之间的功能来完成:
indexPairs = matchFeatures(features1, features2);
Run Code Online (Sandbox Code Playgroud)
indexPairs是一个2D数组,其中第一列告诉您第一个图像中哪个特征点与第二个图像中的特征点匹配,存储在第二列中.我们将使用它来索引我们的有效点以充实实际匹配的内容.
matchedPoints1 = validPoints1(indexPairs(:, 1), :);
matchedPoints2 = validPoints2(indexPairs(:, 2), :);
Run Code Online (Sandbox Code Playgroud)
然后我们可以通过使用showMatchedFeatures这样来显示匹配的点.我们可以将两个图像彼此并排放置,并在匹配的关键点之间绘制线条以查看哪个匹配.
figure;
showMatchedFeatures(im, im2, matchedPoints1, matchedPoints2, 'montage');
Run Code Online (Sandbox Code Playgroud)
这就是我得到的:

它并不完美,但它肯定会在两个图像之间找到一致的匹配.
现在我们需要做的是找到单应矩阵并扭曲图像.我将使用,estimateGeometricTransform以便我们可以找到一个转换,将一组点转换为另一组.正如Dima在下面给我的评论中指出的那样,这可以通过RANSAC 强有力地确定最佳单应矩阵.我们可以这样打电话estimateGeometricTransform:
tform = estimateGeometricTransform(matchedPoints1.Location,...
matchedPoints2.Location, 'projective');
Run Code Online (Sandbox Code Playgroud)
第一个输入接受一组输入点,这是您要转换的点.第二个输入采用一组基点作为参考点.这些点是我们想要匹配的.
在我们的例子中,我们想要扭曲第一张图像中的点 - 站起来并使其与第二张图像匹配的人 - 靠在他身边的人,因此第一个输入是来自第一张图像的点,第二张图像是第二张图像.输入是第二个图像的点.
对于匹配点,我们想要引用该Location字段,因为它们包含两个图像之间匹配的实际点的坐标.我们还projective用来计算比例,剪切和旋转.输出是包含我们的点转换的结构.
我们接下来要做的是imwarp用来扭曲第一个图像,使其与第二个图像对齐.
out = imwarp(im, tform);
Run Code Online (Sandbox Code Playgroud)
out将包含我们扭曲的图像.如果我们并排显示第二张图像和此输出图像:
figure;
subplot(1,2,1);
imshow(im2);
subplot(1,2,2);
imshow(out);
Run Code Online (Sandbox Code Playgroud)
这就是我们得到的:

我会说那很好,你不觉得吗?
为了您的复制和粘贴乐趣,这里是完整代码的样子:
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);
Run Code Online (Sandbox Code Playgroud)
请记住,我使用了所有内容的默认参数......所以detectSURFFeatures,matchFeatures等等.您可能需要使用参数来获得您尝试的不同图像对的一致结果.我会把它留给你作为练习.看看我上面链接的所有链接与每个功能,以便您可以使用参数来满足您的口味.
玩得开心,祝你好运!