5

So here is my problem:

I have an image, that image is large (high resolution) and it needs to be small (much lower resolution).

So I do the naive thing (kill every other pixel) and the result looks poor.

So I try to do something more intelligent (low pass filtering using a Fourier transform and re-sampling in Fourier space) and the result is a little better but still fairly poor.

So my question, is there a perceptually motivated image down-sampling algorithm (or implementation)?

edit: While I am aware of a number of resampling techniques, my application is more concerned with preserving the perceptual features, rather than producing smooth images.

edit2: it is safe to assume I have some level of familiarity with digital signal processing, convolutions, wavelet transforms, etc

tzenes
  • 1,699
  • 2
  • 15
  • 31
  • OK, what kind of images are you trying to scale? Line drawings? Photographs? I've dealt mostly with video images, and scaling algorithms that work well on video might not work well when you try to preserve specific features (like lines in traditional animation, for example.) – Ori Pessach Nov 22 '09 at 23:23
  • For the moment let's say its the image of a bear (removed from its background) and once resized I want it to still look like a bear. – tzenes Nov 22 '09 at 23:45
  • 1
    Hand drawn bear? A photograph of a bear? Pedobear? By what factor are you scaling? From your description ("kill every other pixel") it sounds like you're only scaling by a factor of 2, so a good general purpose algorithm should still work nicely (unless your image is line art with lines 1 pixel wide, in which case it won't look that great...) I'd be curious to learn how that vectorization approach works for you. – Ori Pessach Nov 23 '09 at 04:01

6 Answers6

5

Read this:

http://www.dspguide.com/

OK, that's quite a read. But understanding filter design would be handy.

In general, the process for scaling an image from W1 x H1 to W2 x H2 where W1, W2, H1, H2 are integers, is to find new W3, H3 so that W1 and W2 are integer factors of W3 and H1 and H2 are integer factors of H3, and then pad the original image with zeros (used to space the pixels of the original image) so that it's now W3 x H3 in size. This introduces high frequencies due to discontinuities in the image, so you apply a low-pass filter to the image, and then decimate the filtered image to its new size (W2 x H2). Sounds like you might be trying to do this already, but the filtering can be done in the time domain so that the Fourier transform isn't really necessary.

In practice, the process I just described is optimized (you'll note that when applying a convolution filter to the upscaled image most of the terms will be 0, so you can avoid most of the multiplication operations in your algorithm, for example. And since you end up throwing away many of the filtered results, you don't need to calculate those, so you end up with a handful of multiplications and additions for each pixel in the target image, basically. The trick is to figure out which coefficients to use.)

libswscale in the ffmpeg project does something like this, I believe. Check it out:

http://gitorious.org/libswscale

As others pointed out, (and you apparently noticed) decimating the image introduces aliasing artifacts. I can't be sure about your resampling implementation, but the technique has interesting gotchas depending on the window size you use and other implementation details.

Ori Pessach
  • 6,777
  • 6
  • 36
  • 51
2

Bicubic interpolation is generally regarded as good enough, but there is no perfect solution, it depends on people and on the properties of the picture being resampled.

Related links:

I didn't even know that sharpness was also called acutance.

Aliasing is a problem that can occur when downsampling naively.

Pascal Cuoq
  • 79,187
  • 7
  • 161
  • 281
  • 2
    I'm familiar with the more mundane resampling techniques (gaussian, bicubic, Lanczos), they are effective for upscaling, but on downscaling they loose too much perceptually important information. I hadn't considered using an unsharp mask, that will probably solve most of my problems, but there will still be some issues where lines that should disappear preserved and vice versa, based on my settings. – tzenes Nov 22 '09 at 22:54
  • 1
    In this case, apart from seam carving already mentioned in another answer, I only see the "vectorization of the high-resolution image followed by displaying the vectorized version in lower resolution" approach. – Pascal Cuoq Nov 22 '09 at 23:59
  • A vectorization algorithm would definitely assist in that. Perhaps I could apply a saliency metric (ie. Itti) to give vectors relative weights and have them disappear past certain thresholds. Let me play with this a little, it might be the solution I'm looking for. – tzenes Nov 23 '09 at 00:02
  • I've decided this is the correct approach for my problem and I appreciate your responses – tzenes Nov 23 '09 at 01:17
  • 1
    Don't just say "bicubic interpolation"! People who read this will probably go and do the naive thing which 90% of software does and not filter the image before down-sampling it. – Timmmm Jan 17 '12 at 21:59
  • 1
    @Timmmm Thanks for leaving a comment, but you should really write your own answer. There you would have the leisure to provide the necessary details. As it is, someone reading this answer+your comment will have no idea what you mean. – Pascal Cuoq Jan 18 '12 at 00:30
1

Recommended ImageMagick "general purpose" downsampling methods are discussed here: http://www.imagemagick.org/Usage/filter/nicolas/#downsample

1

Pascal is right. Depends on the image, and on what you want. Some factors:

  • preserving sharp edges
  • preserving colours
  • algorithm speed

This is your method.

Some others:

Note that sometimes resampling down can get you a sharper result than, say, using a lower resolution camera, because there will be edges in the high-resolution image that cannot be detected by a lower-res device.

Side note: Many algorithms (especially Nearest Neighbour) can be optimised if you are scaling down by an integer (e.g. dividing by 4 or 6).

Artelius
  • 48,337
  • 13
  • 89
  • 105
  • 1
    Like most people, you have forgotten the vitally important step of low-pass filtering the image first. Just using one of the interpolation methods you've listed will result in aliasing and the image will look rubbish. – Timmmm Jan 17 '12 at 22:00
0

You could try a content aware resizing algorithm. See: http://www.seamcarving.com/

Caleb
  • 9,272
  • 38
  • 30
  • While image retargetting is more in line with what I'm trying to do, the actual application is insufficient. image retargting relies on identify important features and cropping them from a "background." Where as what I am looking at doing is taking the image of say, a bear, and resampling that – tzenes Nov 22 '09 at 23:02
0

Paint Mono (an OS fork of Paint.NET) implements Supersampling algorithm for image downsampling here: http://code.google.com/p/paint-mono/source/browse/trunk/src/PdnLib/Surface.cs?spec=svn59&r=59#1313

Igor Brejc
  • 18,714
  • 13
  • 76
  • 95
  • As far as I can tell this doesn't filter the image properly and shouldn't be used for downsampling. – Timmmm Jan 17 '12 at 22:03
  • Given that it _is_ used in Paint.NET for downsampling, I would say it does its job well. I've also started using it in my own software and the results are just fine: http://braincrunch.tumblr.com/post/13459650973/maperitive-beta-subpixel-accuracy – Igor Brejc Jan 18 '12 at 05:25
  • 2
    @Timmmm If you have something that you feel is important to say, explain it properly in your own answer. Commenting on all existing answers without ever giving details does not seem very constructive. This is not how this site works. – Pascal Cuoq Jan 18 '12 at 16:40
  • Ok, I'll make a proper answer. – Timmmm Jan 18 '12 at 17:13