-2

See the image below :

As you can seen in the image the written text in rotated by 90 deg angle and I want to rotate only the text to be horizontal. By what ever angle it is rotated I want to make it horizontal as in below :

I don't want the complete image to the rotated. I want that the text only is bounded and the angle by which the text is rotated is measured and then rotated by that angle to make it horizontal.

Can you suggest me a way to do so and then fit an ellipse onto the text ?

Thank you.

Shai
  • 111,146
  • 38
  • 238
  • 371
Ritz
  • 180
  • 1
  • 12
  • Similar task: http://stackoverflow.com/questions/32227347/how-can-i-detect-the-dimensions-of-an-object-under-an-angle-in-this-picture-in-m/32228759#32228759 – Shai Jan 30 '16 at 17:05

2 Answers2

6

First, let's find x-y coordinates of all the dark pixels

bw = imread('http://i.imgur.com/0LxC6bd.png');
bw = min( bw, [], 3 ) < 50 ; % dark pixels - intensity lower than 50
[y x] = find( bw ); % note that find returns row-col coordinates.

Compute the covariance matrix of the text coordinates

mx = mean(x);
my = mean(y);
C = [ mean( (x-mx).^2 ),     mean( (x-mx).*(y-my) );...
      mean( (x-mx).*(y-my) ) mean( (y-my).^2 ) ];

You can get the orientation of the ellipse from the eigen vectors and eigen values of C:

[V D] = eig( C );
figure; imshow( bw ); hold on;
quiver( mx([1 1]), my([1 1]), (V(1,:)*D), (V(2,:)*D), .05 );  

Looking at the eigenvectors and eigen values:

V =
-0.9979   -0.0643
-0.0643    0.9979

D = 
1.0e+003 *
0.1001         0
     0    1.3652

You can see that the eigen-vectors (columns of V) are approximately the pointing to the -X direction (first column) and the Y direction (second column). Examining the eigen values (diagonal of D) you can see that the second eigen value is much larger than the first - this is the major axis of your ellipse. Now you can recover the orientation of the ellipse:

[~, mxi] = max(diag(D)); % find major axis index: largest eigen-value

Recover the angle from the corresponding eigen-vector

or = atan2( V(2,mxi), V(1,mxi) ) * 180/pi ; % convert to degrees for readability
or =
93.6869

As you can see the major axis of the ellipse is almost 90deg off the horizon. You can rotate the image back

imrotate( bw, -or );

enter image description here


Drawing an ellipse given the covariance matrix:

th = linspace(0, 2*pi, 500 );
xy = [cos(th);sin(th)];
RR = chol( C ); % cholesky decomposition
exy = xy'*RR; %//'
figure;imshow( bw ); hold on;
plot( 2*exy(:,1)+mx, 2*exy(:,2)+my, 'r', 'LineWidth', 2 );

enter image description here

Shai
  • 111,146
  • 38
  • 238
  • 371
  • I understood most of it but is there a function 'quiever' in MATLAB, I am using MATLAB R2012b, I didn't find any function like that, I get something like 'quiver' http://www.mathworks.in/help/matlab/ref/quiver.html – Ritz Jan 15 '14 at 08:30
  • @Ritz my typo - corrected. Thanks. – Shai Jan 15 '14 at 08:31
  • Hello Sir, I used your code and assembled it together http://pastebin.com/aPVzQEdp But I didn't get the required output : http://imgur.com/TjFK2lq – Ritz Jan 15 '14 at 09:00
  • @Ritz, by putting all the code together and not seperating it into functions/blocks you ran over the stored value of `mx` - the mean of `x` coordinates (in the function `[mx mxi] = max( diag(D) );`. restore the valus of `mx` and you should be fine. – Shai Jan 15 '14 at 09:25
  • I am now getting the ellipse perfectly but, I am still not getting the rotated text. Can you please divide them into modules and mail the .m files to me seperately. My mail id is firunscall@gmail.com – Ritz Jan 18 '14 at 14:38
  • @Ritz the code is already diveded into modules. Use `r = imrotate(bw, -or);` to get the rotated image in variable `r`. `figure;imshow(r);` will display the rotated image. – Shai Jan 19 '14 at 09:12
0

I used this solution:

bw = im2;
bw = sum((1-im2).^2, 3) > .5; 
%bw = min( bw, [], 3 ) < 50 ; % dark pixels - intensity lower than 50
[y x] = find( bw ); % note that find returns row-col coordinates.

mx = mean(x);
my = mean(y);
C = [ mean( (x-mx).^2 ),     mean( (x-mx).*(y-my) );...  
      mean( (x-mx).*(y-my) ) mean( (y-my).^2 ) ];
[V D] = eig( C );

quiver( mx([1 1]), my([1 1]), (V(1,:)*D), (V(2,:)*D), .05 );
[~,mxi] = max(diag(D)); % find major axis index: largest eigen-value
or = atan2( V(2,mxi), V(1,mxi) ) * 180/pi ; % convert to degrees for readability
rotate = imrotate( im2, or-180 );

axes(handles.axes2);

imshow( rotate );  
set(handles.text3, 'String',or-180);

screen shot

Jan Eglinger
  • 3,995
  • 1
  • 25
  • 51