Main Topics
Browse All TopicsI need an efficient C or C++ code for rotating an image (in my case it is a float array and two integers representing the dimentions, but anything semilar is ok) by X degrees around the center, using BiCubic interpolation.
Any tips are welcome.
Please note that I'm developing under Linux (no DirectX or OpenGL).
Source code with SSE support will be even better.
This Question has been solved and asker verified All Experts Exchange premium technology solutions are available to subscription members.
Experts Exchange has been collecting answers to technology questions since 1996…3 million and counting! If you have a question, chances are we already have your answer.
If you can't find the exact answer you're looking for, ask our exclusive community of 50,000 experts. You’ll get a personalized answer from a trusted professional.
Thousands of free tech tips, tricks, how-to’s and tutorials are available in our peer reviewed articles section. See for yourself how smart our experts are, no login required.
Access the answers to your technology questions today.
30-day free trial. Register in 60 seconds.
Members of the expert community talk about why the experience at Experts Exchange is different than what you will find anywhere else.

Try it out and discover for yourself.
30-day free trial. Register in 60 seconds.
Join the community of experts here and help other tech pros by answering question in your area of expertise. You can earn FREE access to all Experts Exchange's premium features and resources.
ozo,
Thanks for your comment, but what I'm looking for, is the following:
Rotating an image using Bilinear interpolation is quick and easy, but, unfortunately does not yeild a high quality results. Using Shear transformations on the other hand will be too slow.
It seems to me that Bicubic interpolation is a good compramise. Unfortunately I could not find any efficient algorithms for BiCubic interpolation (it seems to me that since this is a well known problem probably there are well known efficient solutions as well).
Any help is very welcome.
Thanks
DirectX have a function to rotate a bitmap....
I tried it myself but didn't make it a year ago...
Maybe now it is possible...
Also GDI+ have such function also...
There are plenty of examples to rotate a bitmap but with a size larger than 200x200 its VERY slow.. About 2secs to do it with P4 2200 and GForceMX440 with 512Mb RAM...
GDI+ functions are 100% faster.. I had 1sec to rotate 5 degrees..
As you can see (the way I made it) both functions were slow...
I don't know about DirectX yet...
gtokas.
Actually, you can do it in two shear operations.
The wisest, as far as view accuracy is concerned, is to make the post-rotated image bigger (in terms of pixel count), so that you can maintain a bit more detail. Then, use pixel-averaging to dither the image back down:
1. Double the size (or whatever seems sufficient).
2. Shear horizontal
3. Shear vertical
4. Reduce resolution by pixel-averaging
Believe it or not, shearing twice is going to be blazingly fast compared to almost any other method.
guitaristx:
Thanks for your comment.
It seems you suggested a linear interpolation for resizing, then rotating and then another linear interpolation for shrinking (?).
In his case the interpolation method probably wont' do the job. I tried a few interpolation methods, including using a resizing operatin prior to the rotation and it seems that the best quality to efficiency ratio is for BiCubic interpolation.
Linear interpolation is not good enough (losing quality too fast).
Using resizing operations on the other hand are not better than BiCubic interpolation but are slower !
I can get some commercial licraries (like Intel's IPP) which has a "Image Rotation" functions, but since my images have some "special" properties I need to write the code myself.
Thanks,
Yaniv
First, I'm not recommending a linear interpolation for resizing, I'm recommending a resize operation that will scale the image up by a whole-number factor -- no interpolation required.
Your problem is that you'll have a trade-off on speed vs. accuracy. Two shears is how most of the imaging libraries work. I mentioned resizing the image because you say that you need extra accuracy. HOWEVER, that extra accuracy will cost you some speed.
I've dealt with this sort of thing before - I used to work as a software engineer for a company that specialized in image processing software. You just need to make sure that you're avoiding the slow operations: conditions, multiplication, division.
If two shear operations is not accurate enough, then you need to figure out a way to preserve more detail in the image, which means resizing. The first resize operation (if it's done right) should be relatively cost-free, since all you're doing is doubling the size. The second resize operation is what will be costly, especially if you're dealing with a color image. However, there are some tricks:
When you're averaging pixels, you're averaging the values of four bytes, which means that, mathematically, you add the four values together and divide by four:
(p1 + p2 + p3 + p4) / 4 = a
You'll do this once for a grayscale image, and three times for an RGB image.
However, you can change the above formula to look like this:
p1/4 + p2/4 + p3/4 + p4/4 = a
So, now you can generate a 256 byte lookup table where each value is the index divided by four, and you've eliminated division altogether, which makes for a significant speed increase.
What's "special" about your images?
An MMX programming primer:
http://codeproject.com/cpp
> Also, SSE doesn't apply here - you'll be doing integer math exclusively.
> MMX would apply. MMX applies to integer math, whereas SSE applies to floating-point math.
I just re-read your original post - SSE would apply, since you're dealing with floating-point arrays.
However, are you certain that you need your 'image' data as floating-point? Can you go into any details about the application/usage for these images?
guitarx,
My images are multi-layer images. You can think of it as a 3D image that should be rotated around one of the axes. They must be floating point, as they take part of an accurate optimization algorithm of image processing. Actually I had to make them floating point in order to gain efficiency since originally they were double, so I lost some accuracy.
I liked your tip about the efficient devision using lookup table, I'll keep it in mind.
It seems that although I'm an Image Processing algorithm developer I don't know enough about efficient code writting :(
Please let me know if you can think about anything else.
Thanks.
Using floating-point values for your pixel data is very out-of-the-ordinary for image processing as i know it. If I may, I would recommend running some analysis on your images, and find out the following:
minimum value
maximum value
minimum exponent
maximum exponent
percentage of data points that have another data point within some threshold (say, .1%)
The range of a single-precision float is (+/-)3.4e(+/-)38. Examine your data, and see what range your pixels fall into. Use some statistical analysis; ignore the upper and lower 5 or 10%, and consider the minimum and maximum values.
This will tell you whether or not you need a floating-point array to store your pixel data. If your data tends to fall within a very small range of what float can store, then you can safely reduce the precision of your pixels without sacrificing accuracy. Using floating-point values is going to slow your algorithm considerably, and I'm trying to warn you against using it unless it's ABSOLUTELY NECESSARY. It's very possible you could reduce the pixels to an unsigned short (16 bits) and maintain sufficient accuracy. It also makes that lookup table possible - the table size would be 64k, whereas the lookup table for float would be 4GB!
Float math is slooooow, avoid it if at all possible.
>Two shears is how most of the imaging libraries work.
oh yeah? what about >= 90 degrees? there's more logic involved.
>Can you explain the purpose
well if you'd walk through your image with those steps (if Paladin got em right), you'd have a choppy picture like if viewpoint would be rotated. if you'd plot your image using these to increment output coords, you'd have even choppiest rotated image. that was nice trick back on old, really slow machines, which allowed for only two extra multiplications for whole image to be rotated.
ygal,
I am not an expert in image processing but I wanted to include a couple of quick notes.
guitaristx, you talked about using MMX ops. As far as I understand MMX is actually slows down your program because it does not have it's own register set so it is necessary to clear the registers, reload the registers with your data, perform the ops and then reset the registers, which ends up taking longer than just doing the operations normally. SSE avoids this by having their own set of registers. It would be interesting to know if they've fixed the issue with MMX in newer CPUs.
Another option for speeding up your process is to perform the biCubic interpolation on the graphics card. Current graphics cards support 32 bit floating point numbers. We recently performed some tests and found nice speed improvements when writing a CG program to perform simple image processing algorithms. One thing to consider is that your users will need to have a compatable graphics card. A quick tip if you decide to go down this path, you stated that your image is multilayer. Do not attempt to use a 3d texture to hold your data. It will be much slower than using a 2d texture and then mapping it to a 3d texture inside of your cg program.
gkatz
Post a request here:http://www.experts-ex
Also - please in the future, try to answer to the experts:)
Business Accounts
Answer for Membership
by: ozoPosted on 2005-03-10 at 09:19:42ID: 13508354
You can do it with 3 simple shear transforms raphics/al gorithms-f aq/
see Subject 3.01: How do I rotate a bitmap?
in http://www.faqs.org/faqs/g