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: .
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:
.
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.
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!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With