change imref2d so that image is in center

I have asked in a previous question how I can change the origin of a transformationmatrix for application. The initial situation was that it seemed that the transformationmatrix was apllied onto a simulated image with the wrong origin. For information the simulated image contains a plane as an object. So the image after tranfomration should be a square beginning at matrix indeces approx. (26;26). And the image is the size of 2049x2049px. The previous question can be found here: https://de.mathworks.com/matlabcentral/answers/1598324-transformation-matrix-projective2d-change-of-origin-at-application?s_tid=srchtitle
Now with the help of these answers and additional research I applied different parameters of imwarp() and got this far:
With
pixelExtendInWorldX=(203.53*2)/2049; %I know that the image plane in real world is in x-direction 203.53*2 mm long.
pixelExtendInWorldY=(1390-984.41)/2049; %the distancce in y-direction is 1390-984.41
outputimref2d=imref2d(size(origimage), pixelExtendInWorldX, pixelExtendInWorldY);
realdectcorroutputview2 = imwarp(origimage,tmatrix, 'nearest','OutputView', outputimref2d);
With this I get an result which begins at matrix indeces (93,92) and is then cut off. So it appears that the center is too much in the lower right direction. But the result seems to be a square (the desired shape) as the visible edges are straight lines. As the image is cut off only two of four edges are visible.
I tried the answers from my first question as well, which I wrote as
xWorldLimits2=[-203.54 203.54];
yWorldLimits2=[984.41 1390];
outputimref2dwl=imref2d(size(origimage) ,xWorldLimits2,yWorldLimits2);
realdectcorroutputview2wl = imwarp(origimage,tmatrix, 'nearest', 'OutputView', outputimref2dwl);
This resulted in an image, beginning at indeces of (1117/1118), going straight downwards, but having a protruding edge at the end in the right direction from this image.
I also tried
xWorldLimits2=[-203.54 203.54];
xWorldLimits2=xWorldLimits2-mean(xWorldLimits2);
yWorldLimits2=[984.41 1390];
yWorldLimits2=yWorldLimits2-mean(yWorldLimits2);
outputimref2dwl=imref2d(size(origimage) ,xWorldLimits2,yWorldLimits2);
realdectcorroutputview2wl = imwarp(origimage,tmatrix, 'nearest', 'OutputView', outputimref2dwl);
which did not really change the result.
And
Rin=imref2d(size(origimage));
Rin.XWorldLimits=Rin.XWorldLimits-2*mean(Rin.XWorldLimits);
Rin.YWorldLimits=Rin.YWorldLimits-2*mean(Rin.YWorldLimits);
realdectcorrRin = imwarp(origimage,Rin, tmatrix, 'nearest');
did not work at all.
So the first attempt seems to yield the best results yet, but how can I additionally change (supposably) the imref2d-object, that the final image is not cut off anymore, but more centered?
Any help is appreciated.

5 Comments

You should attach an input image and demonstrate (i.e., Run
)
the code for us.
Ah, yes. Excuse me. I will do that.
So the realdect200 and realdect1802048 are the ones which have to be transformed. idealdect200 and idealdect1802048 are the ideal solutions. 200 and 180 in the names indicate the size of the object plane which is simulated to be visualized.
What I found out in the mean time as well, as I run the skript with realdect1802048 (the smaller version) is that even the most promising way from above has a protuding edge at the right. It is still cut off, but maybe the produting edge is not visible at the image acquired with a simulated bigger plane object.
load 'SimulationDataMathworks0612.mat';
origimage=realdect200; %or realdet1802028
Rin=imref2d(size(origimage));
Rin.XWorldLimits=Rin.XWorldLimits-2*mean(Rin.XWorldLimits);
Rin.YWorldLimits=Rin.YWorldLimits-2*mean(Rin.YWorldLimits);
realdectcorrRin = imwarp(origimage,Rin, tmatrix, 'nearest');
pixelExtendInWorldX=(203.53*2)/2049;
pixelExtendInWorldY=(1390-984.41)/2049;
outputimref2d=imref2d(size(origimage), pixelExtendInWorldX, pixelExtendInWorldY);
realdectcorroutputview2 = imwarp(origimage,tmatrix, 'nearest','OutputView', outputimref2d);
outputimref2dv2=imref2d(size(origimage), pixelExtendInWorldX, pixelExtendInWorldY);
outputimref2dv2.XWorldLimits=outputimref2dv2.XWorldLimits-2*mean(outputimref2dv2.XWorldLimits);
outputimref2dv2.YWorldLimits=outputimref2dv2.YWorldLimits-2*mean(outputimref2dv2.YWorldLimits);
realdectcorroutputview2v2 = imwarp(origimage,tmatrix, 'nearest','OutputView', outputimref2dv2);
xWorldLimits2=[-203.54 203.54];
xWorldLimits2=xWorldLimits2-mean(xWorldLimits2);
yWorldLimits2=[984.41 1390];
yWorldLimits2=yWorldLimits2-mean(yWorldLimits2);
outputimref2dwl=imref2d(size(origimage) ,xWorldLimits2,yWorldLimits2);
realdectcorroutputview2wl = imwarp(origimage,tmatrix, 'nearest', 'OutputView', outputimref2dwl);
outputimref2dv2wl=outputimref2dv2;
outputimref2dv2wl.XWorldLimits=[-203.54 203.54];
outputimref2dv2wl.YWorldLimits=[984.41 1390];
realdectcorroutputview2dv2wl = imwarp(origimage,tmatrix, 'nearest', 'OutputView', outputimref2dv2wl); %Beginn bei 1476/1109
f1=figure;
imshow(realdect200);
f2=figure;
imshow(realdectcorroutputview2);
f3=figure;
imshow(idealdect200);
For additional information: These simulated images are binary images, so they consists of 1 and 0. Visually you don't see a difference between realdect200 and idealdect200, because the difference is too small to be visible at an image with 2049x2049 pixel. But with the data I have and with which I simulated the images, the differences make an impact with these sizes, which is visible in the matrices of the images. I can not make an example where the differences are visible to the naked eye with the data I have and on which the transformation matrix relies on as well.
I hope this information helps and I added the information correctly.
Matt J
Matt J on 6 Dec 2021
Edited: Matt J on 6 Dec 2021
Ah, yes. Excuse me. I will do that.
No, you did not run your code for us with the Run button , like I suggested, so we don't know which images you are displaying and what code you used to display them. Also, you also need to explain what is wrong about the result you are displaying for us and what it should look like.
Sorry, that was my fault. I just changed that.
But I can not make the resulting matrices of the images (if I may call them so) appear on the comment. They are just too big. I only can attach images of sketches of them.
Here are some simple sketches, how the matrices look like. idealdect200 is the desired result and realdect200 is the image to be tranformed. The other are named like in the code. Ending at (2049/2049) indicates that there is a cut off. realdectcorroutputview2v2 is not sketched, as it only contains 0.

Sign in to comment.

Answers (2)

yes,sir,which tmatrix used in your code,may be upload the file and do some analysis,such as
clear all;clc;close all;
origimage = imread('football.jpg');
Rin=imref2d([size(origimage,1) size(origimage,2)]);
Rin.XWorldLimits=Rin.XWorldLimits-2*mean(Rin.XWorldLimits);
Rin.YWorldLimits=Rin.YWorldLimits-2*mean(Rin.YWorldLimits);
tmatrix = affine2d([1 0 0; .5 1 0; 0 0 1]);
realdectcorrRin = imwarp(origimage,Rin, tmatrix, 'nearest');
figure; montage({origimage,realdectcorrRin}, 'Size', [1 2], 'BackgroundColor', 'w', 'BorderSize', [2 2]);
The reason the output doesn't look like a square is because your tmatrix is wrong, not because of anything else:
load 'SimulationDataMathworks0612.mat';
origimage=realdect200; %or realdet1802028
mp=fliplr( [19,19; 19 2031; 2034 2034; 2034 16] );
fp=fliplr( [26,26; 26 2024; 2024 2024; 2024 26] );
tform=fitgeotrans(mp,fp,'projective');
realdectcorrRin = imwarp(origimage, tform, 'nearest');
imshow(realdectcorrRin,[])

3 Comments

Thanks for this answer.
or the simulated images are wrong. because I checked the caluclation of the tmatrix and I can not find any mistakes.
But why do you use fliplr()? I mean I know what it does, but why do you use it here?
Matt J
Matt J on 7 Dec 2021
Edited: Matt J on 7 Dec 2021
But why do you use fliplr()? I mean I know what it does, but why do you use it here?
Because, the data for the vertices of your quadrilaterals were in matrix coordinates, but fitgeotrans and imwarp expect things in the coordinate conventions of the Image Processing Toolbox. In that system, the x-axis goes horizontally from left to right across the image and the y-axis runs vertically from top to bottom.
I read that, but I completly forgot about that. But my input data for fitgeotrans() are world coordinates as you described. So at least that is correct.

Sign in to comment.

Products

Release

R2019b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!