Page 1 of 1

Angles Blurs (via Convolution kernels)

Posted: 2012-05-10T17:40:44-07:00
by fmw42
Future: I also want to add some convolution kernels called 'filter1d' and 'filter2d' that generates linear and cylindrical kernels based on the current filter settings, for direct use in -convolve (which is now an alias for -morphology Convolve). Of course I would include in radius and scale kernel arguments with defaults set to support and 1.0 (no-op filter) scaling.
While noting things for the future, it would be nice to have a 1D gaussian of arbitrary direction, much like the -motion-blur, but which is symmetric, not one half of the gaussian as I expect motion-blur is doing. Basically an arbitrary direction 1D gaussian blur.

It can have several uses, one of which is to simulate linear motion blur like from a moving object photographed by a camera. That kind of blur is symmetric and represent proper real-world motion-blur and not an "effect"-like blur such as in -motion-blur. It may also be effective in simulating a crosshatch effect, especially if it can be done like some of your filters to do it in both +- 45 degrees together, rather than trying to combine 4 -motion-blur filters at 45, 225, -45, -225 angles.

Re: Angled Blurs (via convution kernels)

Posted: 2012-05-10T18:13:06-07:00
by anthony
Mapping this to a new topic!
fmw42 wrote:
Future: I also want to add some convolution kernels called 'filter1d' and 'filter2d' that generates linear and cylindrical kernels based on the current filter settings, for direct use in -convolve (which is now an alias for -morphology Convolve). Of course I would include in radius and scale kernel arguments with defaults set to support and 1.0 (no-op filter) scaling.
While noting things for the future, it would be nice to have a 1D gaussian of arbitrary direction, much like the -motion-blur, but which is symmetric, not one half of the gaussian as I expect motion-blur is doing. Basically an arbitrary direction 1D gaussian blur.
I have this as a note. But this involves creating a 'generate rotation distortion' for kernels. In my thinking, a simple interpolation rotation much like what you get with...
http://www.imagemagick.org/Usage/distorts/#lookup
would go the job. But needs to be applied to a array of floating point numbers, converting a given 1-d array into a 2-d array.
Another example of this type of rotation is "rotation of a thin line"
http://www.imagemagick.org/Usage/misc/#interpolate_line
If you think of the input line representing a 1-d kernel of all '1.0 values, you can see we need to generate a rotated 'line' of values with extra 'anti-aliasing' values in the generated 2-d kernel.


At the moment the specialized convolution, Motion Blur
http://www.imagemagick.org/Usage/blur/#motion-blur
works by rotatingeach discrete value in the 1-D kernel into a single direct lookup. Only one lookup per value. The result is that you do not get a 'smooth line' of bluring, but a very 'dotty' look. You can see this dotty effect in the advanced 'comets' example
http://www.imagemagick.org/Usage/advanced/#stars
Essentially the result is like 'forward mapping' the '1-d line' into 2-d lookups, resulting in 'skips' and duplications
such as you get in the distort forward map example.
http://www.imagemagick.org/Usage/distor ... rd_mapping
It works, but the result is not very nice.


It can have several uses, one of which is to simulate linear motion blur like from a moving object photographed by a camera. That kind of blur is symmetric and represent proper real-world motion-blur and not an "effect"-like blur such as in -motion-blur. It may also be effective in simulating a crosshatch effect, especially if it can be done like some of your filters to do it in both +- 45 degrees together, rather than trying to combine 4 -motion-blur filters at 45, 225, -45, -225 angles.
I agree. I want this as well. Not just for 'motion' or true 'radial' blurs. (remember IMv6 radial-blur is really a 'rotation blur')
But also for morphology searches for angled lines, though that may require a different technique.

Hmmm you can get angled motion blurs (both directions) using Variable Blur Ellipses!!!!
http://www.imagemagick.org/Usage/mapping/#blur_ellipse
You would just use a 'solid color map' that represents the angle, width, and length of the elliptical blur wanted.

In fact this technique may be used TODAY to generate specialized angled blurs, radial blurs, and even psuedo-rotational blurs. But only 'bidirectional' blurs, not 'comet-like' blurs.

Re: Angles Blurs (via Convolution kernels)

Posted: 2012-05-10T18:27:52-07:00
by fmw42
Hmmm you can get angled motion blurs (both directions) using Variable Blur Ellipses!!!!
http://www.imagemagick.org/Usage/mapping/#blur_ellipse
You would just use a 'solid color map' that represents the angle, width, and length of the elliptical blur wanted.
Interesting, but ...
I am not sure I understand the width value. What does it mean? Is it the thickness of the ellipse (minor axis) or is it just an equal width all along the length? What does width=0 mean as opposed to width=0? How are they different?

Is length the radius or sigma from the gaussian function?

I would like to have the option to make it linear like in -blur radiusx65000 as well as the equivalent of 0xsigma.

So I would like to control: width (nominally 1 pixel), radius, sigma and angle.

Re: Angles Blurs (via Convolution kernels)

Posted: 2012-05-10T18:41:01-07:00
by anthony
Variable Blur can take three maps. Width, Height, and Rotation which defined how the resampling ellipse (the blur area)
is calculated, Typically the last (as a blue channel) is NOT used.

If you make all three maps just white (a single white image map) You can then set width, height, and angle via the compose arguments for the variable blur, and forget about the 'variable' aspect.

Rememebr the 'blue channel angle map' is only used if a range of angles is given, but ensuring the red and green channels are ay maximum, ensures the ellipse is at the maximum size you specify via arguments.

Re: Angles Blurs (via Convolution kernels)

Posted: 2012-05-10T18:48:12-07:00
by fmw42
Sorry I had not read the docs thoroughly enough. I missed the linear gradient map issue. But what is the sigma value that is used in this kind of application or is it linear (sigma very large) as defined by the linear gradient? (The sigma I am referring to is the "graylevel" roll-off of the gaussian weighing function as in -blur.) If it is linear not gaussian, then I guess a half-gaussian profile "gradient" map would be needed to make the result a one-sided gaussian blur (similar to -motion-blur), correct? Also, am I correct that I would need to solarize the gradient to make it symmetrical at each pixel?

Or have I misunderstood more than I thought?

Re: Angles Blurs (via Convolution kernels)

Posted: 2012-05-10T19:14:04-07:00
by anthony
The width and height values are defined in terms of 'sigma'. As such set the X width to the sigma you want. If the height is set to 0.5 you get an effective linear kernel (though it is still actually long thin 'anti-aliased' ellipse!).

Note the actual real resampling ellipse is much larger, and is defined according to Gaussian filter support, which is defaulting to a value of 2.0 when sigma is 0.5, so the actual ellipsis is 4 times lather than the values you specify.

Note that due to this support limits, the variable blur currently will become no-op when the variable value of sigma falls below 0.25. In other words the 'radius' part of the blur is fixed at 4 times sigma. Though this is also an elliptical limit, and not a square limit, as you get for real convolutions.

WARNING: at this time expert filter options can override these values. I have not 'disabled' them for this operation!
As such experrt filter options can interfere with the operators normal working behaviour. For example you also could replace gaussian filter using a "filter:filter" setting! This is not recommended!

Re: Angles Blurs (via Convolution kernels)

Posted: 2012-05-10T19:42:26-07:00
by fmw42
Still not sure I follow. Do you mean Width is the length (sigma) of the x axis of the ellipse and Height is the length (sigma) of the y axis of the ellipse? And that the actual lengths in width and height are 4 times the value specified as sigma is converted to radius (actual lengths)

So there is no way I can control the radius independent of the sigma?

If that is the case, then what does the linear gradient do? Would it not be better to have the map for width and height be a gaussian roll-off independent of the radius, which would be the width and height arguments, so that one could control the sigma independent of the radius. Then a linear gradient would be like having a very large sigma (as in -blur) and and a user supplied radius. Then this would really be like a true camera motion blur (i.e. a 1D version of -blur radiusx65000) at an arbitrary direction.

Does zero for width or height mean then that the ellipse is 1 pixel thick in the minor axis direction?

I will experiment with it tomorrow, to see if I can get a better understanding of its limitations and functionality for doing what I would like.

Simple experiments with a white square on black background and a solarized gradient, do indeed show a gaussian roll-off that is symmetrical on both sides of the white square (using im_profile).

Would be nice if this were linear roll-off, but I can experiment with my scripting tests using this.

Re: Angles Blurs (via Convolution kernels)

Posted: 2012-05-14T23:25:57-07:00
by anthony
fmw42 wrote:Still not sure I follow. Do you mean Width is the length (sigma) of the x axis of the ellipse and Height is the length (sigma) of the y axis of the ellipse? And that the actual lengths in width and height are 4 times the value specified as sigma is converted to radius (actual lengths)
Without rotation (the default with not + arguments in the "compose:args") that is it exactly.

You use the arguments to set height to 0.5 and width to whatever you want, and give a single rotation angle, and for the mapping image, a pure white image, the same size (no variability)

For example:

Code: Select all

   convert logo:  \( +clone -fill white -colorize 100% \)  \
          -define compose:args="20x0-30" -compose Blur -composite show:
Not height of ellipse is 0 but it will be clamped to sigma 0.25 (actually the ellipse support radius height is clamped to 1 so support to the radius is 2.0 so sigma reduces from 0.5 to 0.25)

Note this is a perfectly uniform blur, not a one directional 'smear' that you get with -motion-blur
In many ways it is far better than motion blur!

When I get to it I'll add non-90 degree convolution rotations, especially 1D kernels (like comet or blur kernels). The 'hook' is present, I just need code to do the rotations of a floating point array (with appropriate array resize, and interpolation), and it can be done. Actually just about any good C programmer should be able to do it, it is just time that I have a problem with.
So there is no way I can control the radius independent of the sigma?
YES their is The expert filter settings can override the EWA Gaussian filter being used.

if you change the support, the Ellipse radius will change. Gaussian is using a support of 2.0 for its default sigma of 0.5.
As long as you do not effect the sigma, the blur input should not be effected.

(Err... Fingers crossed! Things always seem to give me trouble with variable blurs, but I believe I have it right!)


If that is the case, then what does the linear gradient do?
The size of the ellipse (actually the resample area and hence the sigma) is varied according to the 'map' the linear gradient makes the blur smaller to a hard limit EWA radius of 1 (sigma 0.25 minimum). In distorts this controlled the ellipse vectors using the 'derivative' of the distorts. You should know all about that.

As such 'red' channel maximum gives the sigma width the user supplied. 'green' maximum gives the height, and if (and only if) an two angles is given (as a range) 'blue' varies the angle of the ellipse, otherwise it is ignored.

The gradient thus linearly decreases the amount of blur from user maximum (white) to zero (actually a 0.25 sigma hard limit minimum) basically by changing the 'derivative vectors' used to define the resampling ellipse.

Would it not be better to have the map for width and height be a gaussian roll-off independent of the radius, which would be the width and height arguments, so that one could control the sigma independent of the radius. Then a linear gradient would be like having a very large sigma (as in -blur) and and a user supplied radius. Then this would really be like a true camera motion blur (i.e. a 1D version of -blur radiusx65000) at an arbitrary direction.
That map controls the variable blur, the map does not control the filter function! That is just a gaussian fixed by the filter support.

If you like a linear roll off filter try using -define filter:filter=Box -define filter:support=0.5
The radius will be exactly as you give as the arguments to the compose (Gaussian sigma is 0.5, and Box support is 0.5)

You are lucky I have not restricted expert options, only the -filter option is not used, and which the expert options can override!
Does zero for width or height mean then that the ellipse is 1 pixel thick in the minor axis direction?
The Ellipse axises is clamped to a minimum of 1.0, so as to ensure the ellipse can actually find pixels to sample in the filters suport range. With Gaussian the filter support is 2.0 so when this gets clamped to 1.0 minimum sigma is 0.25
You can use a height of 0 if you like, it will get clamped to the minimum.
I will experiment with it tomorrow, to see if I can get a better understanding of its limitations and functionality for doing what I would like.

Simple experiments with a white square on black background and a solarized gradient, do indeed show a gaussian roll-off that is symmetrical on both sides of the white square (using im_profile).

Would be nice if this were linear roll-off, but I can experiment with my scripting tests using this.
Try overriding the internals using Box as mentioned above.

Hmmm

Code: Select all

 convert logo:  \( +clone -fill white -colorize 100% \) \
       -define filter:filter=Box  -define filter:support=0.5 \
       -define compose:args="20x0-30" -compose Blur -composite show:
Well it looks like a linear blur to me! Though it is abusing the intended design of the operation!

The Ellipse is producing a few artifacts as the support radius is rather 'hard' without any tapering effect.

Re: Angles Blurs (via Convolution kernels)

Posted: 2012-05-15T10:17:42-07:00
by fmw42
My tests show that using -define filter:filter=Box -define filter:support=0.5 is very close to linear, but not exact. Nevertheless, I will test that further in my script. I just tested using a white square in the center of a black background. Then used my profile script. Your im_profile does not seem to be working right now.

Re: Angles Blurs (via Convolution kernels)

Posted: 2012-05-16T21:12:33-07:00
by anthony
My "im_profile" works fine for me!

Re: Angles Blurs (via Convolution kernels)

Posted: 2012-05-16T21:34:25-07:00
by fmw42
anthony wrote:My "im_profile" works fine for me!
Try this. It hangs for me:

convert -size 1x256 gradient: -rotate 90 miff:- im_profile -

Re: Angles Blurs (via Convolution kernels)

Posted: 2012-05-17T03:29:13-07:00
by magick
Shouldn't that be
  • convert -size 1x256 gradient: -rotate 90 miff:- | im_profile -

Re: Angles Blurs (via Convolution kernels)

Posted: 2012-05-17T11:18:25-07:00
by fmw42
magick wrote:Shouldn't that be
  • convert -size 1x256 gradient: -rotate 90 miff:- | im_profile -

Yes, you are right. At the time that the following did not work


convert -size 1x256 gradient: -rotate 90 grad256x1.gif
im_profile grad256x1.gif


I think I had the pipe right, but both were failing

Now both work.

Sorry for the false alarm on the piping. I am not sure why I did not catch that or I had it right originally and then mistyped it later.

Very embarrassed! :oops: