www.gusucode.com > images 案例代码 matlab源码程序 > images/PadShearImageExample.m
%% Padding and Shearing an Image Simultaneously % This example shows how to construct a |tform| struct that represents a % simple shear transformation and then applies it to an image. We explore how % the transformation affects straight lines and circles, and then use it as % a vehicle to explore the various options for image padding that can be % used with |imtransform| and |tformarray|. % % Copyright 1993-2013 The MathWorks, Inc. %% Step 1: Transform an Image Using Simple Shear % In two dimensions, a simple shear transformation that maps a pair of % input coordinates |[u v]| to a pair of output coordinates |[x y]| has the form % % $$x = u + a * v$$ % % % $$y = v$$ % % % where |a| is a constant. % % Any simple shear is a special case of an affine transformation. You can % easily verify that % % $$[\begin{array}{c c}x\ y\ 1\end{array}] = [\begin{array}{c c}u\ v\ 1\end{array}] * \left[\begin{array}{c c c}1\;0\;0\\a\;1\;0\\0\;0\;1\end{array}\right]$$ % % yields the values for |x| and |y| that you received from the first two equations. %% % Setting |a| = 0.45, we construct an affine |tform| struct using % |maketform|. a = 0.45; T = maketform('affine', [1 0 0; a 1 0; 0 0 1] ); %% % We select, read, and view and image to transform. A = imread('football.jpg'); h1 = figure; imshow(A); title('Original Image'); %% % We choose a shade of orange as our fill value. orange = [255 127 0]'; %% % We are ready to use |T| to transform |A|. We could call |imtransform| as follows: % % |B = imtransform(A,T,'cubic','FillValues',orange);| % % but this is wasteful since we would apply cubic interpolation along both % columns and rows. (With our pure shear transform, we really only need to % interpolate along each row.) Instead, we create and use a resampler that % applies cubic interpolation along the rows but simply uses nearest % neighbor interpolation along the columns, then call |imtransform| and display the result. R = makeresampler({'cubic','nearest'},'fill'); B = imtransform(A,T,R,'FillValues',orange); h2 = figure; imshow(B); title('Sheared Image'); %% Step 2: Explore the Transformation % Transforming a grid of straight lines or an array of circles with % |tformfwd| is a good way to understand a transformation (as long as it has % both forward and inverse functions). % % Define a grid of lines covering the original image, and % display it over the image Then use |tformfwd| to apply the pure shear to % each line in the grid, and display the result over the sheared image. [U,V] = meshgrid(0:64:320,0:64:256); [X,Y] = tformfwd(T,U,V); gray = 0.65 * [1 1 1]; figure(h1); hold on; line(U, V, 'Color',gray); line(U',V','Color',gray); figure(h2); hold on; line(X, Y, 'Color',gray); line(X',Y','Color',gray); %% % You can do the same thing with an array of circles. gray = 0.65 * [1 1 1]; for u = 0:64:320 for v = 0:64:256 theta = (0 : 32)' * (2 * pi / 32); uc = u + 20*cos(theta); vc = v + 20*sin(theta); [xc,yc] = tformfwd(T,uc,vc); figure(h1); line(uc,vc,'Color',gray); figure(h2); line(xc,yc,'Color',gray); end end %% Step 3: Compare the 'fill', 'replicate', and 'bound' Pad Methods % When we applied the shear transformation, |imtransform| filled in the % orange triangles to the left and right, where there was no data. That's % because we specified a pad method of |'fill'| when calling |makeresampler|. % There are a total of five different pad method choices (|'fill'|, % |'replicate'|, |'bound'|, |'circular'|, and |'symmetric'|). Here we compare the first three. % % First, to get a better look at how the |'fill'| option worked, use the % |'XData'| and |'YData'| options in |imtransform| to force some additional space % around the output image. R = makeresampler({'cubic','nearest'},'fill'); Bf = imtransform(A,T,R,'XData',[-49 500],'YData',[-49 400],... 'FillValues',orange); figure, imshow(Bf); title('Pad Method = ''fill'''); %% % Now, try the |'replicate'| method (no need to specify fill values in this % case). R = makeresampler({'cubic','nearest'},'replicate'); Br = imtransform(A,T,R,'XData',[-49 500],'YData', [-49 400]); figure, imshow(Br); title('Pad Method = ''replicate'''); %% % And try the |'bound'| method. R = makeresampler({'cubic','nearest'}, 'bound'); Bb = imtransform(A,T,R,'XData',[-49 500],'YData',[-49 400],... 'FillValues',orange); figure, imshow(Bb); title('Pad Method = ''bound'''); %% % Results with |'fill'| and |'bound'| look very similar, but look closely and % you'll see that the edges are smoother with |'fill'|. That's because the % input image is padded with the fill values, then the cubic interpolation % is applied across the edge, mixing fill and image values. In contrast, % |'bound'| recognizes a strict boundary between the inside and outside of % the input image. Points falling outside are filled. Points falling inside % are interpolated, using replication when they're near the edge. A close % up look helps show this more clearly. We choose |XData| and |YData| to % bracket a point near the lower right corner of the image, in the output % image space, the resize with |'nearest'| to preserve the appearance of % the individual pixels. R = makeresampler({'cubic','nearest'},'fill'); Cf = imtransform(A,T,R,'XData',[423 439],'YData',[245 260],... 'FillValues',orange); R = makeresampler({'cubic','nearest'},'bound'); Cb = imtransform(A,T,R,'XData',[423 439],'YData',[245 260],... 'FillValues',orange); Cf = imresize(Cf,12,'nearest'); Cb = imresize(Cb,12,'nearest'); figure; subplot(1,2,1); imshow(Cf); title('Pad Method = ''fill'''); subplot(1,2,2); imshow(Cb); title('Pad Method = ''bound'''); %% Step 4: Exercise the 'circular' and 'symmetric' Pad Methods % The remaining two pad methods are |'circular'| (circular repetition in each % dimension) and |'symmetric'| (circular repetition of the image with an % appended mirror image). To show more of the pattern that emerges, we % redefine the transformation to cut the scale in half. Thalf = maketform('affine',[1 0; a 1; 0 0]/2); R = makeresampler({'cubic','nearest'},'circular'); Bc = imtransform(A,Thalf,R,'XData',[-49 500],'YData',[-49 400],... 'FillValues',orange); figure, imshow(Bc); title('Pad Method = ''circular'''); %% R = makeresampler({'cubic','nearest'},'symmetric'); Bs = imtransform(A,Thalf,R,'XData',[-49 500],'YData',[-49 400],... 'FillValues',orange); figure, imshow(Bs); title('Pad Method = ''symmetric'''); %%