12
$\begingroup$

I need to downscale an image in a factor of $s_x$ horizontally and $s_y$ vertically ($s_x$, $s_y$ < $1$).

I want to use a finite $n\times m$ low-pass filter before downsampling.

How should I determine the low-pass filter parameters ($n, m$ and the Gaussian $\sigma$) to get it as a function of $s_x$ and $s_y$?

Specifically, I'm interesting in the case where $s_x=s_y=1/\sqrt{2}$.

$\endgroup$
7
  • $\begingroup$ question related to [the one asked here][1] [1]: stackoverflow.com/questions/3149279/… $\endgroup$
    – isrish
    Nov 18, 2012 at 13:27
  • 1
    $\begingroup$ Thanks, but this question is not about how to determine the filter parameters as a function of the downscaling factor. $\endgroup$
    – Ben-Uri
    Nov 18, 2012 at 13:36
  • $\begingroup$ How much do you want to filter? What's your goal? $\endgroup$
    – Franco Callari
    Nov 19, 2012 at 16:34
  • 1
    $\begingroup$ I want to use a low pass filter before down sampling to avoid aliasing. I want to preserve as much as possible information without aliasing. $\endgroup$
    – Ben-Uri
    Nov 19, 2012 at 20:21
  • 1
    $\begingroup$ You need to look at the Fourier transform of the filter to know how well it will cut the aliasing frequencies while keeping the frequencies below the Nyquist limit of the sampled result. A gaussian's transform is another gaussian, meaning there's no sharp cutoff. There's almost always a better choice. $\endgroup$ Apr 10, 2013 at 23:05

5 Answers 5

5
$\begingroup$

You have to think about the change in Nyquist frequency between both images. If the Nyquist frequency of the original image is N, the downsampled image will have a lower Nyquist frequency, xN, where x is related to the ratio of sizes between the final image and the initial one. You would need to remove those spatial frequencies which are higher than xN in the original image before downsampling it.

The power spectrum of a Gaussian in the image space, is also a Gaussian in the frequency space. If we ignore for a moment the second dimension, the Gaussian in the image space is defined as exp(-x^2/s^2), where x represents your pixels. This is mapped to the frequency space as exp(-w^2*s^2), where w is the frequency. The sigma parameter (s) shows that a broad Gaussian in the image space, corresponds to a narrow Gaussian in the frequency space.

You would like to choose a sigma parameter that yields a very low value in frequency space at the frequency that corresponds to the Nyquist frequency of the down sampled image.

$\endgroup$
4
  • $\begingroup$ Right, but how do I translate this to a discrete convolution kernel? (this was the question) $\endgroup$
    – Ben-Uri
    Apr 14, 2013 at 9:38
  • $\begingroup$ see the edit pls... $\endgroup$
    – NoNameNo
    Apr 14, 2013 at 15:14
  • $\begingroup$ Thanks, but still is there a formula to find the sigma as a function of the maximum frequency that should be in the output result? $\endgroup$
    – Ben-Uri
    Apr 14, 2013 at 19:19
  • $\begingroup$ i don't know any formulas. $\endgroup$
    – NoNameNo
    Apr 14, 2013 at 19:50
1
$\begingroup$

It's already been pointed out that $n$ and $m$ are to be chosen based on $\sigma$.

I've spent some time thinking on how to pick $\sigma$ best. Here are my considerations. tl;dr: Maybe I made some mistake, but $\sigma^2\approx3.37$ looks like a good choice for down-sampling by factor 2.

$\endgroup$
0
$\begingroup$

If you were doing a large downsize (say 2x, 3x, 4x) you can do pixel averaging to achieve good anti-aliasing. That's actually why anti-aliasing uses a lot of additional CPU/GPU in order to make video games look crisper.

Since you're going from a 1000x1000 to a 707x707 image (just an example for the scale factor) you're correct that aliasing might be an issue.

Thankfully this is a problem that many people have run into already and done quite a bit of work to solve. In many cases a bicubic interpolation is the way to go. There are some examples of what the different interpolation methods look like here:

http://www.compuphase.com/graphic/scale.htm

OpenCV's resize has several of those methods built-in:

http://opencv.willowgarage.com/documentation/cpp/geometric_image_transformations.html#cv-resize

If you have already played around with several of those interpolation methods and they don't work well, please post some kind of a sample source image and sample result image showing the shortfall. We'll need this in order to diagnose the problem and try and come up with a good solution to it.

$\endgroup$
1
  • $\begingroup$ remark that, while it is fast, pixel averaging is not the ideal solution for quality. pixel averaging effectively applies a rect filter. in the frequency space, this is equivalent to multiplying by a sinc function that oscillates with zero crossings at the harmonics of Nyquist. this has two problems: 1. it attenuates high frequency but not that much 2. it inverts phase at every other side lobe. Both (1) and (2) can contribute to aliasing. $\endgroup$
    – thang
    Jan 20, 2013 at 8:19
0
$\begingroup$

I don't really have a good answer for you, but here are 2 options that you could try:

  • in Computer Vision , this rescaling factor is usually handled by applying a Gaussian filter of width (in pixels) between 5 and 9. You can find the corresponding $\sigma$ of the Gaussian because the pixel width is classically equal to $3 \sigma$.
  • if you are willing to do fine signal-sampling computations, then why not using Fourier transform ? Take the FFT of your image, keep only the subpart that corresponds to your target size, and invert the transform. This will apply an anti-aliasing filter on your spectrum. If there are too many artifacts (ripples, ringing) for you, then apply on your spectrum of Gaussian filter whose width corresponds to your target size .
$\endgroup$
1
  • $\begingroup$ I have a similar task to do, that is downsampling an image using a Gaussian filter. I am troubled with this task for several months. The main problem is that my scaling factor is non-integer. Any help would be greatly appreciated. $\endgroup$
    – Nikos
    Nov 1, 2022 at 23:44
0
$\begingroup$

For the case $s=1/\sqrt{2}$, the classic Gaussian kernel in 2D is of the form: $$[1, 2, 1]^T[1, 2, 1]$$

$\endgroup$
4
  • $\begingroup$ You are wrong. Did you forget a scale factor of 0.25? ...and if so, this is a common choice for s=1/2 not 1/sqrt(0.5). $\endgroup$
    – Ben-Uri
    Sep 28, 2013 at 21:28
  • $\begingroup$ Any comment on @Ben-Uri's take? The system is flagging this post as low-quality because of the length. Please consider revising or removing it. $\endgroup$
    – Peter K.
    Oct 3, 2013 at 14:19
  • 1
    $\begingroup$ @PeterK. - I think Ben-Uri is confusing $s$ with $s^2$ $\endgroup$ Oct 3, 2013 at 16:30
  • $\begingroup$ I thought that you were using $s$ for the scale factor (as I used in my question). Did you use $s$ for the Gaussian $\sigma$? I asked what is the $\sigma$ as a function of the downscale factor ($s_x,s_y$), and I don't see how your solution solves it. $\endgroup$
    – Ben-Uri
    Oct 5, 2013 at 17:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.