Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Affine Transformation Rescaling

I detected a salient region in an image to which I perform a series of operations, the most important being an affine normalization (transforming ellipses into circles and trapezoids to equilateral rectangles).

The affine normalization is a combination of shearing and scaling in a matrix that looks as follows:

Chol=[a,b           
      0,c]

with a,c in [0,1] and b in [-1,1] (For those of you who are interested, it's the inverse of the Cholesky decomposition of the covariance matrix of the detected region).

Everything works fine until here, but when I apply the transformation to the original frame

AffineFrame=cv.warpAffine(RealFrame,[Chol,[0;0]],... 
                          'DSize',[RealFrameSize(1),RealFrameSize(2)]);          
% that's dst=cv.warpAffine(src,trafo) with trafo: 2x3 Matrix (here Chol and [0,0] translation) 

I get an image unscaled in both, the transformation and the image size:  image unsacled in both, the transformation and the image size.

What I actually want - and achieved only for this particular frame by trial and error with this line

AffineFrame=cv.warpAffine(RealFrame,[Chol,[0;0]]*S,... 
                          'DSize',[RealFrameSize(1)*X,RealFrameSize(2)*Y]);  

would look something like this:

Want!.

I know the problem is in the scaling of S, X and Y. If anyone knows how to calculate this, you would be saving me a long journey back to school geometry! (I already have all the geometric information that can be extracted from second image moments like mayor and minor axis with respective magnitudes, eccentricity, and so on.)

Edit: Some typical values (not necessarily this case):

Chol = 0.43  -0.23
       0      0.67

The idea I had for X and Y: with L and W the magnitude of the main and minor axes (varies a lot depending shape normally around 5 and 50):

X=(1+L/(L+W));
Y=(1+W/(L+W));

Works only if the shearing from Chol is not to big. S does a good job between 5 and 30 depending on the shapes.

like image 537
McMa Avatar asked Nov 23 '22 15:11

McMa


1 Answers

I am afraid there was no way around some simple maths (which was not that difficult either...)!

From our transformation matrix

Chol=L1 L2
     0  L3

being an enumeration of scaling, shearing, and rotationChol=Sc*Sh*Rot with

Sc=Sx 0  ,  Sh=1 m  , Rot= cos(alpha)  sin(alpha)   
   0  Sy       0 1         -sin(alpha) cos(alpha)

with alpha=0 follows:

L1=Sx , L2=m*Sx , L3=Sy , m=L1/L2.

To rescale the transformation you go with the inverse of the highest scaling factor Sy or Sx:

%MatLab
CholScale=Chol*[1/max(Chol(1,1),Chol(2,2)),0;0,1/max(Chol(1,1),Chol(2,2))];

and to rescale the image write down the transformation of extrema values:

 xmax'=xmax*Sx+m*ymax
 ymax'=ymax*Sy

in my code looks something like this

%MatLab
AffineFrame=cv.warpAffine(RealFrame,[CholScale,[0;0]],... 
                      'DSize',[RealFrameSize(2)*(1/max(Chol(1,1),Chol(2,2))*Chol(1,1))+RealFrameSize(1)*Chol(1,2)/Chol(1,1),...
                               RealFrameSize(1)*(1/max(Chol(1,1),Chol(2,2))*Chol(2,2))]); 

And Voila!

enter image description here

like image 112
McMa Avatar answered Jan 08 '23 18:01

McMa