Using imrotate without losing quality

20 次查看(过去 30 天)
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 个评论
Image Analyst
Image Analyst 2024-7-5
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:

请先登录,再进行评论。

采纳的回答

Milad
Milad 2018-3-13
(Thanks to guys for answering and helping me with this question. To sum things up I've decided to write an answer myself.)
It seems that rotation always reduces image quality unless we allow the rotated image to be larger than the original or only use multiples of 90 degrees.
The best option in imrotate() seem to be 'bicubic'. Even without resizing the image it gives a pretty good result.
  1 个评论
DGM
DGM 2024-7-5
编辑:DGM 2024-7-5
This is appropriate, but there are conceivable reasons why someone might overlook this fact or otherwise be confused to hear that it's true.
Consider the following rotation of a small test pattern
% a tiny 12x9 checkerboard
A = imread('tinycb.png'); % uint8
% rotate by 90 using two interpolation options
theta = 90;
B = imrotate(A,theta); % output is 9x12
C = imrotate(A,theta,'bilinear');
% upscale to prevent the forum display from
% doing interpolation on the tiny images
B = imresize(B,20,'nearest');
C = imresize(C,20,'nearest');
% display them side by side
montage({B,C},'border',[10 10],'backgroundcolor','m');
What if the angle were off by a small amount?
% the same tiny image
A = imread('tinycb.png');
% angle is off by the tiniest amount
theta = 90 + eps(90) % looks like 90, right?
theta = 90.0000
% rotate as before
B = imrotate(A,theta); % now the output is 10x13
C = imrotate(A,theta,'bilinear');
% upscale as before
B = imresize(B,20,'nearest');
C = imresize(C,20,'nearest');
% display them side by side
montage({B,C},'border',[10 10],'backgroundcolor','m');
% how far off was that?
format long
theta
theta =
90.000000000000014
Depending on how the angles are being obtained, it's possible to run into cases where one only assumes they're hitting 90, but aren't actually. The cause might be rounding error, or it might be as gross as an off-by-one error -- for example:
th = linspace(0,360,1001); % this will hit [0 90 180 270 360]
nnz(mod(th,90) == 0)
ans =
5
versus
th = linspace(0,360,1000); % this only hits 0 and 360
nnz(mod(th,90) == 0)
ans =
2
FWIW, in the case of 90d multiples, imrotate() internally just calls rot90(), so the interpolation options are actually circumvented.

请先登录,再进行评论。

更多回答(2 个)

Image Analyst
Image Analyst 2018-3-12
See if using the ‘nearest’ option of imresize gives you something you like better.
  2 个评论
Milad
Milad 2018-3-13
Of course I've seen your solution! Your answers are the most respected. But as I said, I don't want to use imresize(). And if you meant imrotate(), I've tried its methods too. Which still didn't give good results. I'll try the 'nearest' option of imrotate() once again to see if anything changes.
Image Analyst
Image Analyst 2018-3-13
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
Guillaume 2018-3-12
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 个评论
Image Analyst
Image Analyst 2018-3-13
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
Guillaume 2018-3-13
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.

请先登录,再进行评论。

类别

Help CenterFile Exchange 中查找有关 Read, Write, and Modify Image 的更多信息

Community Treasure Hunt

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

Start Hunting!

Translated by