Sign in to follow this  
snooty

2D Scaling

Recommended Posts

Hi, I'm quite new to graphics programming, so please forgive me if my question sounds stupid. I'm trying to implement a 2D scaling routine that handles any scaling factor. Scaling above factor 0.5 is fine (I just do simple bilinear interpolation to smooth things out), but smaller than that, problems occur. For example, when scaling with factor 0.2, for 1 destination pixel there are 5 x 5 corresponding source pixels. How do I interpolate them?

Share this post


Link to post
Share on other sites
Well, you interpolate them in exactly the same way you always do - weight the source pixels by the proportion of the resulting area they occupy.

However, you really can't cram much information into a small space, no matter how hard you try - when scaling down, some quality needs to be sacrificed. If bilinear filtering is totally unsatisfactory, you probably won't find anything too much better.

If performance isn't an issue, there are many other filters available. A bicubic filter will preserve a little more detail, but don't expect magic. 'Edge-preserving' scales exist, which can give the illusion of detail presrevation, although the result is less faithful to the original than a bilinear/bicubic.

You may want to Google 'texture min-filtering' for more general information.

Regards
Admiral

Share this post


Link to post
Share on other sites
Quote:
Original post by TheAdmiral
Well, you interpolate them in exactly the same way you always do - weight the source pixels by the proportion of the resulting area they occupy.


Thanks for the reply.

The problem is I don't know what weight a pixel should have in this situation. Using the example in my original post, should each of the 25 pixels weigh 1/25? Or should it be a Bartlett filter or something else?

Share this post


Link to post
Share on other sites
Imagine overlaying, on to the existing image, a grid that has one-fifth the resolution in each dimension. The grid-blocks respresent the pixels on the new image. Then each pixel in the source image will lie in one, two or four of these blocks.
In a bilinear filter, each source pixel should contribute to every block that it appears in, according to the proportion of that block's area it occupies.

In general, this is a non-trivial calculation, but if you are scaling an image down by a dual factor of 5 and the source image's dimensions are both multiples of 5, then the blocks will map perfectly to 5x5 areas in the source, so indeed, each pixel contributes 1/25 of the colour of its (unique) destination pixel.

Of course, this will kill a lot of the entropy - blending 25 pixels into one - but the destination image is one twenty-fifth of the area, so there's nothing more you can hope to achieve.

If you are coding such a filter yourself, you could iterate over the source pixels, placing the data into the destination, but I feel it is more intuitive to do things the other way around: iterate over the destination image, determining which of the source pixels contribute to each dest-pixel, then, for each mapping, further calculate the area of intersection, before taking the weighted sum.

Regards
Admiral

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this