【问题标题】:How to measure the rotation of a image in MATLAB?如何在MATLAB中测量图像的旋转?
【发布时间】:2012-11-10 17:18:02
【问题描述】:

我有两张图片。一个是原始的,另一个是旋转的。

现在,我需要找出图像旋转的角度。直到现在,我一直在考虑发现每种颜色的质心(因为我将使用的每张图像都有带有颜色的正方形)并用它来发现图像旋转了多少,但我失败了。

我正在使用它来发现图像中较高正方形的质心和颜色:

i = rgb2gray(img);
bw = im2bw(i,0.01);
s = regionprops(bw,'Centroid');
centroids = cat(1, s.Centroid);
colors = impixel(img,centroids(1),centroids(2));
top = max(centroids);
topcolor = impixel(img,top(1),top(2));

【问题讨论】:

  • 您是否考虑过使用 Procrustes 分析? MATLAB 提供了procrustes 函数,维基百科对这个方法有很好的描述。

标签: matlab image-processing


【解决方案1】:

您可以检测图像和旋转版本中的一个彩色矩形的角,并使用这些作为控制点,使用CP2TFORM 函数推断两个图像之间的转换(如图像配准)。然后我们可以从仿射变换矩阵计算旋转角度:

这是一个示例代码:

%# read first image (indexed color image)
[I1 map1] = imread('http://i.stack.imgur.com/LwuW3.png');

%# constructed rotated image
deg = -15;
I2 = imrotate(I1, deg, 'bilinear', 'crop');

%# find blue rectangle
BW1 = (I1==2);
BW2 = imrotate(BW1, deg, 'bilinear', 'crop');

%# detect corners in both
p1 = corner(BW1, 'QualityLevel',0.5);
p2 = corner(BW2, 'QualityLevel',0.5);

%# sort corners coordinates in a consistent way (counter-clockwise)
p1 = sortrows(p1,[2 1]);
p2 = sortrows(p2,[2 1]);
idx = convhull(p1(:,1), p1(:,2)); p1 = p1(idx(1:end-1),:);
idx = convhull(p2(:,1), p2(:,2)); p2 = p2(idx(1:end-1),:);

%# make sure we have the same number of corner points
sz = min(size(p1,1),size(p2,1));
p1 = p1(1:sz,:); p2 = p2(1:sz,:);

%# infer transformation from corner points
t = cp2tform(p2,p1,'nonreflective similarity');    %# 'affine'

%# rotate image to match the other
II2 = imtransform(I2, t, 'XData',[1 size(I1,2)], 'YData',[1 size(I1,1)]);

%# recover affine transformation params (translation, rotation, scale)
ss = t.tdata.Tinv(2,1);
sc = t.tdata.Tinv(1,1);
tx = t.tdata.Tinv(3,1);
ty = t.tdata.Tinv(3,2);
translation = [tx ty];
scale = sqrt(ss*ss + sc*sc);
rotation = atan2(ss,sc)*180/pi;

%# plot the results
subplot(311), imshow(I1,map1), title('I1')
hold on, plot(p1(:,1),p1(:,2),'go')
subplot(312), imshow(I2,map1), title('I2')
hold on, plot(p2(:,1),p2(:,2),'go')
subplot(313), imshow(II2,map1)
title(sprintf('recovered angle = %g',rotation))

【讨论】:

    【解决方案2】:

    如果你能识别出只对应一个组件的颜色,那就更容易了:

    1. 计算每张图片的质心
    2. 计算每个图像的质心(在 x 和 y 中)的平均值。这是每张图片的“中心”
    3. 获取每个图像的红色分量颜色质心(在您的示例中)
    4. 从每张图像的红色分量颜色质心中减去每张图像质心的平均值
    5. 计算 4) 中计算的每个向量的 ArcTan2,然后减去角度。那是你的结果。

    如果每种颜色有多个图形,则需要计算所有可能的旋转组合,然后选择与其他可能的旋转兼容的组合。

    如果您认为有用,我可以将代码发布到Mathematica

    【讨论】:

      【解决方案3】:

      我会采用上述方法的变体:

      % Crude binarization method to knock out background and retain foreground
      % features. Note one looses the cube in the middle
      im = im > 1
      

      然后我会得到二维自相关:

      acf = normxcorr2(im, im);
      

      从这个结果中,可以很容易地检测到峰值,并且随着旋转进入自相关函数 (ACF) 域,可以通过匹配原始 ACF 和旋转图像中的 ACF 之间的峰值来确定旋转,例如使用所谓的Hungarian algorithm

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-11
        • 2017-03-07
        • 2013-02-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-29
        相关资源
        最近更新 更多