mariam
mariam

Reputation: 11

How do I shear an image in MATLAB without using built-in functions?

I want a method to shear an image without using the built-in functions (methods) of MATLAB. How can I do this?

Upvotes: 1

Views: 11771

Answers (4)

gnovice
gnovice

Reputation: 125874

I'm assuming that "without using the built-in functions" means "not using the Image Processing Toolbox".

Using just core MATLAB functions, image shearing can be done using a shear matrix and the function interp2. The shear matrix can be used to compute a new set of sheared coordinates for the image pixels, and interp2 can then be used to interpolate the image values at these new coordinates. Here's an example of applying an x-direction shear to a sample image:

img = imread('cameraman.tif');  % Read a sample grayscale image
img = double(img);              % Convert the image to type double
[nRows, nCols] = size(img);     % Get the image size
[x, y] = meshgrid(1:nRows, 1:nCols);  % Create coordinate values for the pixels
coords = [x(:).'; y(:).'];            % Collect the coordinates into one matrix
shearMatrix = [1 0.2; 0 1];           % Create a shear matrix
newCoords = shearMatrix*coords;       % Apply the shear to the coordinates
newImage = interp2(img, ...              % Interpolate the image values
                   newCoords(1, :), ...  %   at the new x coordinates
                   newCoords(2, :), ...  %   and the new y coordinates
                   'linear', ...         %   using linear interpolation
                   0);                   %   and 0 for pixels outside the image
newImage = reshape(newImage, nRows, nCols);  % Reshape the image data
newImage = uint8(newImage);                  % Convert the image to type uint8

And the following figure shows the shear applied to the image by the above code:

enter image description here

You can adjust the direction (x or y) and magnitude of the shear by modifying the off-diagonal terms of the shear matrix. You can also change which edge of the image (top, bottom, left, or right) is held fixed when the shear is done by first flipping the image in a given direction, performing the interpolation, then flipping the image back. You can use the functions flipud and fliplr to change the fixed edge for x-direction and y-direction shears, respectively. Here are some examples of different shears:

enter image description here

Upvotes: 6

feelfree
feelfree

Reputation: 11763

Here I give an example where image rotation can be realized with three independent shearing operations( for more details, please refer to here. By doing so, I want to show how to implement shearing operation.

I = imread('cameraman.tif');
I = imresize(I,[255,255]);
delta = 20;  % rotation angle
rot_I = imrotate(I,-delta);
figure; imshow(rot_I);
% 1. calculate the shearing metrix
delta = delta/180*pi;
x_shear_matrix = [ 1 -tan(delta/2);
                   0    1];
y_shear_matrix = [1  0;
                 sin(delta) 1];

 whole_matrix = [cos(delta)  -sin(delta);
                 sin(delta)      cos(delta)];
             disp(whole_matrix);
  seperated_matrix = x_shear_matrix*y_shear_matrix*x_shear_matrix;
  disp(seperated_matrix);
 % 2. shear in the x-direction
 sheared_img = shear_x(I,delta);
 figure; imshow( sheared_img);  
 % 3. Shear in the y-direction
  new_sheared_img = shear_y(sheared_img,delta);
 figure; imshow(new_sheared_img);
 % 4. shear in the x-direction
  final = shear_x(new_sheared_img,delta);
  figure; imshow(final,'final');

The shearing operations for x-direction and y-direction are as follows:

function new_sheared_img = shear_x(I,delta);

[row,col] = size(I);
 center_x = floor(col/2);
 center_y = floor(row/2);
 top_right_x = col-center_x-tan(delta/2)*(1-center_y);
 bottom_left_x = 1-center_x-tan(delta/2)*(row-center_y);
 new_width =ceil(top_right_x-bottom_left_x+1);
 center_x_new = floor(new_width/2);
 center_y_new = center_y;
 new_sheared_img = zeros(row,new_width);
 for i= 1:row
     pos_y = (i-center_y); 
     pos_y_img = pos_y+center_y; 
     pos_y_img = floor(pos_y_img+0.5);
     for j=1:col
         pos_x = (j-center_x)-tan(delta/2)*pos_y;
         pos_x_img = pos_x-bottom_left_x+1; 
         pos_x_img = floor(pos_x_img+0.5);
         new_sheared_img(pos_y_img,pos_x_img) = I(i,j);
     end 
 end

function  new_sheared_img = shear_y(sheared_img,delta);

 [row,col] = size( sheared_img);
 center_x = floor(row/2);
 center_y = floor(col/2);
 top_left_corner = (1-center_x)*sin(delta)+(1-center_y);
 bottom_right_corner = (col-center_x)*sin(delta)+row-center_y;
 new_height = ceil(bottom_right_corner-top_left_corner+1);
 new_sheared_img = zeros(new_height,col);
 center_x_new = center_x;
 center_y_new = floor(new_height/2);
 for i=1:col
     pos_x = i-center_x;
     pos_x_img = pos_x+center_x_new;
     pos_x_img = floor(pos_x_img+0.5);
     for j=1:row
        pos_y = pos_x*sin(delta)+j-center_y;
        pos_y_img = pos_y-top_left_corner+1;
        pos_y_img = floor(pos_y_img+0.5); 
        new_sheared_img(pos_y_img,pos_x_img) = sheared_img(j,i);
     end
 end

Upvotes: 1

JS Ng
JS Ng

Reputation: 725

Let's generate a sample matrix:

image=reshape(1:25,[5 5])
image =

     1     6    11    16    21
     2     7    12    17    22
     3     8    13    18    23
     4     9    14    19    24
     5    10    15    20    25

To shear it without using MATLAB's in-built functions, just do a remapping of pixels:

for i=1:size(image,1)-1
  image(i+1,:)=image(i+1,[end-i+1:end 1:end-i]);
end

image =

     1     6    11    16    21
    22     2     7    12    17
    18    23     3     8    13
    14    19    24     4     9
    10    15    20    25     5

Shearing it the other way, or shearing vertically, should be a straightforward extension of this.

Upvotes: 1

Fletcher Moore
Fletcher Moore

Reputation: 13814

Form a data table of the X,Y locations of each pixel in the image. Then map these points to new points by multiplying each point by a shear matrix. I'm not familiar with Matlab, so I cannot help you further.

Upvotes: -1

Related Questions