RSS/Atom feed Twitter
Site is read-only, email is disabled

Gaussian blur: Silly question or buffer error?

This discussion is connected to the gimp-developer-list.gnome.org mailing list which is provided by the GIMP developers and not related to gimpusers.com.

This is a read-only list on gimpusers.com so this discussion thread is read-only, too.

3 of 3 messages available
Toggle history

Please log in to manage your subscriptions.

Gaussian blur: Silly question or buffer error? Alastair M. Robinson 04 Feb 22:27
  Gaussian blur: Silly question or buffer error? Bill Skaggs 04 Feb 23:56
  Gaussian blur: Silly question or buffer error? Stephane Chauveau 13 Feb 21:21
Alastair M. Robinson
2008-02-04 22:27:29 UTC (almost 17 years ago)

Gaussian blur: Silly question or buffer error?

Hi,

I may be missing something obvious here, but I'm trying to understand the workings of the Gaussian Blur plugin, since I need to implement something similar myself, and either there's something screwy here, or there's something obvious I'm missing.

In gimp-2.4.4/plugins/common/gauss.c, the gauss_iir() function, at line 960 we have four pointers initialised - two to the beginning of their respective buffers, and two to one tuple before the end.

sp_p = src; sp_m = src + (height - 1) * bytes; vp = val_p;
vm = val_m + (height - 1) * bytes;

But then the inner loop does this: for (b = 0; b < bytes; b++)
{
vpptr = vp + b; vmptr = vm + b; for (i = 0; i re on the subject, can anyone point me to an explanation of the maths behind this IIR approximation of the Gaussian filter? I understand Gaussian blurring well enough to implement a convolution-based version, but I want to implement a local-contrast-stretch filter - basically a gentle large-radius unsharp-mask, which would require unfeasibly large convolution matrices to do it that way.

All the best, --
Alastair M. Robinson

Bill Skaggs
2008-02-04 23:56:56 UTC (almost 17 years ago)

Gaussian blur: Silly question or buffer error?

On Feb 4, 2008 1:27 PM, Alastair M. Robinson wrote:

Hi,

I may be missing something obvious here, but I'm trying to understand the workings of the Gaussian Blur plugin, since I need to implement something similar myself, and either there's something screwy here, or there's something obvious I'm missing.

I'm not going to try to parse the code in an email message, but although it is quite difficult to read, it is set up to avoid referring to any unallocated memory (otherwise it would crash, or at least generate errors in valgrind).

The crucial fact, which may help you understand the code, is that a 2D Gaussian blur can be implemented by doing two 1D Gaussian blurs, first vertically, then horizontally. Thus, the code starts out by doing a 1D blur on each column of the image. When this is finished, the result is processed by independently blurring each row. It is a remarkable theorem that this sequence of two 1D convolutions gives exactly the same result as the full 2D convolution -- at least, it gives the same result if the region is rectangular and all pixels are fully selected and equally weighted.

Basically this happens because the kernel of the 2D Gaussian blur factors: exp (-(x^2 + y^2)) = exp (-x^2) * exp (-y^2). This allows the double integral in the 2D convolution to be factored into a product of two single integrals, over x and y. Unfortunately, I don't have a good reference to point you to, but the method is very widely used. (IIR and RLE are simply tricks for doing a 1D convolution that produce speedups in some common situations.)

-- Bill

Stephane Chauveau
2008-02-13 21:21:21 UTC (almost 17 years ago)

Gaussian blur: Silly question or buffer error?

The answer is given by the definition of 'terms':

terms = (row < 4) ? row : 4;

In pratice, that means that - with row=4 the loop is
for (i = 0; i
...
}

Alastair M. Robinson wrote:

Hi,

I may be missing something obvious here, but I'm trying to understand the workings of the Gaussian Blur plugin, since I need to implement something similar myself, and either there's something screwy here, or there's something obvious I'm missing.

In gimp-2.4.4/plugins/common/gauss.c, the gauss_iir() function, at line 960 we have four pointers initialised - two to the beginning of their respective buffers, and two to one tuple before the end.

sp_p = src; sp_m = src + (height - 1) * bytes; vp = val_p;
vm = val_m + (height - 1) * bytes;

But then the inner loop does this: for (b = 0; b < bytes; b++)
{
vpptr = vp + b; vmptr = vm + b; for (i = 0; i re on the subject, can anyone point me to an explanation of the maths behind this IIR approximation of the Gaussian filter? I understand Gaussian blurring well enough to implement a convolution-based version, but I want to implement a local-contrast-stretch filter - basically a gentle large-radius unsharp-mask, which would require unfeasibly large convolution matrices to do it that way.

All the best, --
Alastair M. Robinson