Using imrotate without losing quality
Mostrar comentarios más antiguos
I'm in a situation that I need to be able to randomly rotate (0-359 angle degrees) different images. I'm currently using imrotate() but considering that the images are small and the quality is important, I noticed that the images lose their qualities, specially in curve lines. I can still rotate my images 0, 90, 180 and 270 degrees without losing any qualities but I wanted to know if there is any way to rotate an image with more degrees without losing the quality.
11 comentarios
Walter Roberson
el 12 de Mzo. de 2018
Is this for creating new images or is it just for display purposes?
Milad
el 12 de Mzo. de 2018
Stephen23
el 12 de Mzo. de 2018
@milad mando: how do you define image rotation "without losing quality"? For example if I have a simple 4x4 grayscale image like this:
im = [0,0;1,1];
please rotate that image exactly 10/3 degrees "without losing quality", and show us what you would expect the output to be.
Walter Roberson
el 12 de Mzo. de 2018
If the new images need to be the same size as originals then you always loose quality at the other angles. Think of the pigeon hole principle: with other rotations and the same size image, other pixels need to start entering the frame because the angled lines will lead to some pixels from outside the original bounding box to be inside the bounding box of the rotated image. But those new pixels from previously outside take up space in the representation and if you do not permit the rotated image to be larger than the original then pigeon hole principle says that the amount of space available for the original pixels has to get lower. The worst case is rotation by 45 degrees, 135 degrees, etc, in which case half of size is being occupied by information about pixels not originally in the frame.
Milad
el 12 de Mzo. de 2018
Walter Roberson
el 12 de Mzo. de 2018
No, you always lose quality on a rotation unless you allow the rotated image to be larger than the original or you only use multiples of 90 degrees.
Did you try playing with the parameters of imrotate to choose the different methods of calculating the rotated image?
Milad
el 12 de Mzo. de 2018
Walter Roberson
el 12 de Mzo. de 2018
If the rotated image is permitted to be larger then you can use subpixel type calculation to get arbitrarily good rotated versions.
If it had been a matter of display then the hgtransform functionality would permit the original data and the rotation matrix to be sent to the graphics engine which would use antialiasing techniques on output.
Shafaq
el 4 de Jul. de 2024
Editada: Image Analyst
el 5 de Jul. de 2024
I want to rotate matrix as well as image and want to show that output is inavriant. Imrotate is affecting invariance so what should I do?
% Generate a random 50x30 matrix A and a 50x1 vector b
A = rand(8, 8);
b = rand(8, 1);
% A=[1 2;3 4];
% b=[1 2]';
% Least squares solution for the original problem
x = (A' * A) \ (A' * b);
theta=90;
theta= deg2rad(theta);
% Rotation matrix for 90 degrees
R = [cos(theta), -sin(theta); sin(theta), cos(theta)];
% Extend the rotation matrix to apply to the whole problem
R_ext = blkdiag(kron(eye(1), R), eye(0)); % Adjust size accordingly
% Rotate the matrix and vector
A_rot = R_ext * A;
b_rot= R_ext * b;
theta= rad2deg(theta);
A_rot=imrotate(A_rot,theta,'crop');
b_rot=imrotate(b_rot,theta,'crop');
% Display the original and rotated matrices using imagesc
% Least squares solution for the rotated problem
x_rot = (A_rot' * A_rot) \ (A_rot' * b_rot);
% Display results
fprintf('Original least squares solution (first 5 elements):\n');
disp(x(1:end));
fprintf('Rotated least squares solution (first 5 elements):\n');
disp(x_rot(1:end));
% Check invariance
invariance_check = norm(x )- norm(x_rot);
fprintf('Invariance check (should be close to zero): %f\n', invariance_check);
Image Analyst
el 5 de Jul. de 2024
Not sure what all that means. An image IS a matrix. And what do you mean by invariant? Invariant to what?
Why don't you start a new discussion thread and explain it?
If you have any more questions, then attach your data and code to read it in with the paperclip icon after you read this:
DGM
el 5 de Jul. de 2024
Respuesta aceptada
Más respuestas (2)
Image Analyst
el 12 de Mzo. de 2018
1 voto
See if using the ‘nearest’ option of imresize gives you something you like better.
2 comentarios
Milad
el 13 de Mzo. de 2018
Image Analyst
el 13 de Mzo. de 2018
Sorry - meant imrotate(). Let me know if that's any better. Otherwise (if not) your only option is to upsample your image like they already suggested.
Guillaume
el 12 de Mzo. de 2018
As per Walter's comments, the only way you can perform arbitrary rotations without loss of quality if by increasing the number of pixels in the image, so:
supersampled = imresize(yourimage, 4); %use whatever scale you which > 1. imresize uses bicubic by default which is the best.
rotatedimage = imrotate(supersampled, someangle, 'bicubic');
6 comentarios
Milad
el 12 de Mzo. de 2018
Guillaume
el 12 de Mzo. de 2018
I think it is you who misunderstood. Walter has repeatedly said you need more pixels.
if you do not permit the rotated image to be larger than the original then pigeon hole principle...
...unless you allow the rotated image to be larger...
In any case, what I've implemented above is basic pixel supersampling. This will result in better quality rotated image. As it's been said repeatedly, the only way you can get better quality out of a non-90 degree multiple rotation is by increasing the number of pixels, since some rotated pixels fall in between real pixels if you keep the number constant.
Stephen23
el 12 de Mzo. de 2018
"the number of pixels won't change"
The number of pixels must increase if you want non-90 degree rotation and a better "quality" image. There is no confusion about this.
Milad
el 13 de Mzo. de 2018
Image Analyst
el 13 de Mzo. de 2018
Did you even TRY or even see my solution (below)? If you just want the image rotated but want sharp edges, not blurry edges, then it might work. Of course you will get jaggies for certain angles, but the edges will be sharper.
Guillaume
el 13 de Mzo. de 2018
imresize is used to upsample the image. A feature that was occupying a single pixel now occupy more. Since we use 'bicubic interpolation' you also get antialising. You now have more resolution for your feature, so you loose less quality when you rotate it.
Categorías
Más información sobre Read, Write, and Modify Image en Centro de ayuda y File Exchange.
Productos
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!

