Reputation: 3510
The following code descripes the affine transformation of an image, I,
T = [sx, 0, 0;...
0, sy, 0;...
0, 0, 1];
tform = maketform('affine', T);
[J,cdata,rdata] = imtransform(I,tform);
After obtaining the transformed image, J, I want to find the appropriate pixel value of I(5,5) on image J.
What should I do?
My code is
function test()
sx = 0.5; sy = 1;
theta = pi/4;
Ts = [sx, 0, 0;...
0, sy, 0;...
0, 0, 1];
Tr = [cos(theta) -sin(theta) 0;...
sin(theta) cos(theta), 0; ...
0, 0, 1];
T = Ts*Tr;
I = imread('image_0002.jpg');
tform = maketform('affine', T);
[J,xdata,ydata] = imtransform(I,tform);
h = ydata(2) - ydata(1);
w = xdata(2) - xdata(1);
%%
gridOx = meshgrid(1:50:size(I,2), 1:50:size(I,1));
gridOy = meshgrid(1:50:size(I,1), 1:50:size(I,2))';
go = [gridOy(:), gridOx(:), ones(length(gridOx(:)),1)];
for i=1:size(go,1)
I = makept(I, go(i,1), go(i,2));
end
imshow(I);
%%
gt = T*go';
TL = T*[1,1,1]';
BL = T*[size(I,1), 1, 1]';
TR = T*[1, size(I,2), 1]';
BR = T*[size(I,1), size(I,2), 1]';
minr = min([TL(1), TR(1), BL(1), BR(1)]);
minc = min([TL(2), TR(2), BL(2), BR(2)]);
%%
gt = int32(round(gt));
r = gt(1,:) - minr+1;
c = gt(2,:) - minc+1;
figure,hold on;
for i=1:length(r)
J = makept(J, r(i), c(i));
plot(gt(1, i), gt(2, i));
end
figure, imshow(J);
close all;
end
function I = makept(I, r, c)
mr = max(r-2,1);
mc = max(c-2,1);
maxr = min(r+2,size(I,1));
maxc = min(c+2,size(I,2));
I(mr:maxr, mc:maxc,:) = 0;
I(mr:maxr, mc:maxc,1) = 255;
end
Upvotes: 6
Views: 11205
Reputation: 3510
I found another way.. use 'tformfwd'.. we need to apply a scaling as well as explained in http://blogs.mathworks.com/steve/2006/02/14/spatial-transformations-maketform-tformfwd-and-tforminv/
function [new_im, grn, gcn] = transformImage(I, gr, gc, TM)
[new_im xdata ydata] = imtransform(I, TM);
w = xdata(2)-xdata(1) +1;
h = ydata(2)-ydata(1)+1;
scalex = size(new_im,2)/w;
scaley = size(new_im,1)/h;
% cartesian coordinates
go = [gc(:), gr(:)];
%% cartesian coordinates
NPt = tformfwd(TM, go);
% convert to image coordinates
NPtImage(:,1) = NPt(:,1) - xdata(1) + 1;
NPtImage(:,2) = NPt(:,2) - ydata(1) + 1;
NPtImage(:,1) = NPtImage(:,1)*scalex;
NPtImage(:,2) = NPtImage(:,2)*scaley;
NPtImage = round(NPtImage);
grn = NPtImage(:,2);
gcn = NPtImage(:,1);
grn = reshape(grn, size(gr,1), size(gr,2));
gcn = reshape(gcn, size(gc,1), size(gc,2));
showimgs = false;
if showimgs
I = uint8(I);
new_im = uint8(new_im);
figure, imshow(I), hold on;
for i=1:size(go,1)
plot(go(i,1), go(i,2), 'r*');
end
figure, imshow(new_im, 'XData', xdata, 'YData', ydata);
hold on
axis on
for i=1:size(go,1)
plot(NPt(i,1), NPt(i,2), 'r*')
end
tmpim = new_im;
for i=1:size(NPtImage,1)
tmpim = makept(tmpim, NPtImage(i,2), NPtImage(i,1), 'b');
end
figure, imshow(tmpim);
end
end
function I = makept(I, r, c, color)
mr = max(r-2,1);
mc = max(c-2,1);
maxr = min(r+2,size(I,1));
maxc = min(c+2,size(I,2));
I(mr:maxr, mc:maxc,:) = 0;
if strcmp(color, 'r')
I(mr:maxr, mc:maxc,1) = 255;
else
I(mr:maxr, mc:maxc,3) = 255;
end
end
Upvotes: 1
Reputation: 14251
You transform the pixel coordinates just like you transformed the image.
appropriatePixel = J(T*[5;5;1]);
The code you posted was already quite close. Always remember that with images, the origin for images is in the top left and that the order of image dimensions is columns-rows, unlike with matrices. You took this into account in some places, but not everywhere.
The code below should fix the problem. gt = T*go
was changed to use the transpose of T, and minc
and minr
were swapped.
function airplane()
close all
sx = 0.5; sy = 1;
theta = pi/4;
Ts = [sx, 0, 0;...
0, sy, 0;...
0, 0, 1];
Tr = [cos(theta) -sin(theta) 0;...
sin(theta) cos(theta), 0; ...
0, 0, 1];
T = Ts*Tr;
I = imread('airplane2.png');
tform = maketform('affine', T);
[J,xdata,ydata] = imtransform(I,tform);
%%
gridOx = meshgrid(1:50:size(I,2), 1:50:size(I,1));
gridOy = meshgrid(1:50:size(I,1), 1:50:size(I,2))';
go = [gridOx(:), gridOy(:), ones(length(gridOx(:)),1)];
figure; imshow(I); hold on;
scatter(go(:,1), go(:,2), 25, 'rs', 'filled');
%%
gt = T'*go';
TL = T*[1,1,1]';
BL = T*[size(I,1), 1, 1]';
TR = T*[1, size(I,2), 1]';
BR = T*[size(I,1), size(I,2), 1]';
minc = min([TL(1), TR(1), BL(1), BR(1)]);
minr = min([TL(2), TR(2), BL(2), BR(2)]);
%%
gt = int32(round(gt));
r = gt(1,:) - minr+1;
c = gt(2,:) - minc+1;
figure; imshow(J);hold on;
scatter(c, r, 25, 'rs', 'filled');
end
Result:
Upvotes: 7