Geometric Transformation - Rotation

For one of my projects I needed to do a geometric normalization. So I needed to estimate the general orientation of an image block and to rotate it to some angle. Well, I searched for a ready-to-use Matlab function. I found one, however it was not what I needed. As a result the rotated image seems as follows:


So, it was not sufficient for me and my purposes and I was forced to write my own function which could rotate a part of the image in a different way. Here you can read some more for the Rotation Matrix and especially the section "In two dimensions". Based on this article I tried to implement it and to create a function which could rotate an image block around a central pixel.

To be convenient to apply some transformation, it is needed to use homogenous coordinate system and to represent the transformation matrix as a 3x3 matrix.


So, to apply a rotation to some image patch we need to create the rotation matrix which will be used for estimating the new coordinates of every one of the pixels of the original image patch.


When we rotate some image patch we should keep in mind the coordinate frame of the image and the sign of the axis:


When we rotate a point in the image frame we can note stranger results than we expect because of the positive angle value.

In the presented code I use the standard Cartesian frame. Then I transform it to the image frame. Well, here is the code: 

function [newimage]=geometric_transform_rotation(img,pix_source_x,pix_source_y,window_size,angle)

%Transformation rotation
%       myfunc_rotation(img,pix_source_x,pix_source_y,window_size)
%img – the source image
%pix_source_x – the “x” coordinate of the central pixel, which will be used for circular rotation around it.
%pix_source_y - the “y” coordinate of the central pixel
%window_size – the size of the window posed over the image. It will be used for retrieving a small patch from the image.
%angle – the rotation angle (degrees)
% by Hristo Aleksiev


%generating of values for the positive semi-axis
%0---|---|---|---|->
%    1   2   3   4
for i=1:1:window_size
    one_half_dim_window(i)=i;
end

% generating of values for the entire axis
for i=1:1:2*window_size
    one_dim_window(i)=i-window_size;
end

%generating of 2D arrays for every of the axis (“x” and “y”) which will %contain the “x” and “y” coordinates of every pixel
source_x_layer=meshgrid(one_dim_window);
source_y_layer=(-1*(source_x_layer))';

%defining of the size of these 2D arrays
[layer_y_size,layer_x_size]=size(source_x_layer);

%generating of the transformation matrix
transl=[cosd(angle) -sind(angle) 0;sind(angle) cosd(angle) 0;0 0 1];
xp=0;yp=0;
vecout=[xp yp 1]';

%generating of 2D arrays to contain the values of the new estimated %coordinates of the rotated image
sink_x_layer=zeros(layer_y_size,layer_x_size);
sink_y_layer=zeros(layer_y_size,layer_x_size);

%walking through the arrays of the standard coordinates, transforming, %estimating the new coordinates for every point and saving the values to the %appropriate array
for i=1:1:2*window_size
    for j=1:1:2*window_size
        x=source_x_layer(i,j);
        y=source_y_layer(i,j);
        vecout=transl*[x;y;1];
        sink_x_layer(i,j)=round(vecout(1));
        sink_y_layer(i,j)=round(vecout(2));
    end
end

%initializing the array which will contain the new transformed image newimage=zeros(layer_y_size,layer_x_size);

%walking through the arrays of the new coordinates, reading their values, %estimating the new coordinates of the pixel which should be read from the %source image and writing this value to the new image
for i=1:1:2*window_size
    for j=1:1:2*window_size
       new_pix_source_y=sink_y_layer(i,j);
       new_pix_source_x=sink_x_layer(i,j);
       newimage(i,j)=img((pix_source_y-new_pix_source_y),(pix_source_x+new_pix_source_x));
    end
end
newimage=uint8(newimage);
end

To test it I use this image:


IM=imread('KungFuPanda.jpg');
grayIM=rgb2gray(IM);
rotatedImagePatch=geometric_transform_rotation(grayIM,190,130,50,16);
imshow(rotatedImagePatch);

It should be grayscale to apply this code and as a result we receive these images:
16 degrees of rotation

38 degrees of rotation

74 degrees of rotation

As you can see, there are differences to the corners of the images. However the circular area with a center equals to the center of the patch is always the same.



Няма коментари:

Публикуване на коментар