使用齐次坐标实现矩阵变换

时间:2012-09-23 20:42:50

标签: matlab image-processing matrix transformation

目前,我需要使用matlab编写一个程序,使用像

这样的齐次坐标转换矩阵
% for translation
T = [1 0 dx; 0 1 dy; 0 0 1];

例如:

A =
    92    99     1     8    15    67    74    51    58    40
    98    80     7    14    16    73    55    57    64    41
     4    81    88    20    22    54    56    63    70    47
    85    87    19    21     3    60    62    69    71    28
    86    93    25     2     9    61    68    75    52    34
    17    24    76    83    90    42    49    26    33    65
    23     5    82    89    91    48    30    32    39    66
    79     6    13    95    97    29    31    38    45    72
    10    12    94    96    78    35    37    44    46    53
    11    18   100    77    84    36    43    50    27    59

>> I = translate(A, 4, 4)
I =

   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN
   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN
   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN
   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN
   NaN   NaN   NaN   NaN    92    99     1     8    15    67
   NaN   NaN   NaN   NaN    98    80     7    14    16    73
   NaN   NaN   NaN   NaN     4    81    88    20    22    54
   NaN   NaN   NaN   NaN    85    87    19    21     3    60
   NaN   NaN   NaN   NaN    86    93    25     2     9    61
   NaN   NaN   NaN   NaN    17    24    76    83    90    42

NaN个单元格的意思是“空格”。如您所见,A矩阵在x轴上转换了4个单位,在y轴上转换了4个单位,留下了NaN个值。输出矩阵I必须与A的大小相同。

但是,我当前的程序在使用图像时效果不佳(它没有在空白区域放置'NaN'值,它将'1'放在一起):

所以,这是我的计划:

function t_matrix = translate(input_matrix, dx, dy)

    [rows cols] = size(input_matrix);

    t_matrix = input_matrix;
    t_matrix(:) = NaN;

    T = [1 0 dx; 0 1 dy; 0 0 1];

    for n = 1:numel(input_matrix)


        [x y] = ind2sub([rows cols], n);

        v = [x y 1]';

        v = T*v;

        a = floor(v(1));
        b = floor(v(2));

        if a > 0 && b > 0
            t_matrix(a, b) = input_matrix(x,y);
        end
    end

    t_matrix = t_matrix(1:rows, 1:cols);

如何以更简单的方式使用matlab实现同构转换?

仅限制:继续使用此矩阵:

% for translation
T = [1 0 dx; 0 1 dy; 0 0 1];

并保留空格的NaN值。

2 个答案:

答案 0 :(得分:1)

您的代码问题可能是您对整数进行操作,而NaN是一个双精度值。您无法将input_matrix分配给t_matrix。您应该使用nan函数创建t_matrix:

 t_matrix = nan(size(input_matrix));

以下是您的代码的直接翻译,我刚刚删除了循环

function I = translate(input_matrix, dx, dy)
    % get matrix dimensions
    [rows cols] = size(input_matrix);
    T = [1 0 dx; 0 1 dy; 0 0 1];
    % create a nan's output matrix
    I = nan(size(input_matrix));

    % create row-column index pairs
    [R C] = meshgrid(1:cols, 1:rows);
    % append 1 at the end
    IDX = [R(:) C(:) ones(numel(input_matrix),1)]';
    % transform coordinates
    V = floor(T*IDX);
    % find indices that fall into [rows, cols] range
    keep = find(V(1,:)>0 & V(1,:)<=rows & V(2,:)>0 & V(2,:)<=cols);
    % assign output only to the correct indices
    I(sub2ind([rows cols], V(1,keep), V(2,keep))) = input_matrix(sub2ind([rows cols], R(keep), C(keep)))
end

另一方面,只需运行以下函数即可获得与问题相同的结果(尽管没有T矩阵......)

function I = translate(A, dx, dy)
    I = nan(size(A));
    I(dx+1:end, dy+1:end) = A(1:end-dx, 1:end-dy);
end

答案 1 :(得分:0)

如果你有图像处理工具箱,实现它的最简单方法是使用内置函数maketformimtransform

I = imread('cameraman.tif');
dx = 40;  
dy = 100;
tform = maketform('affine',[1 0 0; 0 1 0; dx dy 1]);  %#Create a translation matrix
J = imtransform(I,tform,'XData',[0 size(I,2)+dx],'YData',[0 size(I,1)+dy]);
imshow(I), figure, imshow(J)
  • 作为maketform输入的矩阵是你的矩阵的转置
  • 设置XDataYData非常重要,否则您将无法获得“翻译效果”,因为imtransform找到了最小的输出范围。
  • 如果要获得与初始图像相同的大小,请使用以下语法:

 J = imtransform(I,tform,'XData',[0 size(I,2)],'YData',[0 size(I,1)]);

之前的图片:

enter image description here

图片之后:

enter image description here

图像之后(保持相同的大小):

enter image description here