Reputation: 11
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
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:
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:
Upvotes: 6
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
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
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