- Index
- ImageMagick Examples Preface and Index
- 'Neighbourhood' of Convolution Operators (Under Construction)
- Sharpening Images (Under Construction)
- Blurring Images
- Generating Shadows
- Specialised Blurs
- Feathering Shapes (under construction)
- Convolution Kernels (under construction)
These operators make changes to images one pixel at a time until all the
pixels in the image has been operated on, and copied to the new replacement
image Also each pixel is usually only modified slightly and only in response
to other nearby pixels in the local neighbourhood.
In other words the color of a specific pixel in an image is only modified
based on the colors and transparency of the other nearby pixels. As such big
block of color in one part of the image will have little if any effect on
another distant area of the image.
These special image operations, known as 'convolutions', are typically used to
blur, sharpen, clean up, or even make an image look dirty. They are also some
of the most important image operators and are used to generate a huge range of
effects.
'Neighbourhood' of Convolution Operators
As each pixel is modified depending on the values of the pixels around it,
each pixel depends on a 'neighbourhood' surrounding it. The larger the
neighbourhood, the more pixels that are involved in calculating the final
result.
Under Construction
FUTURE:
MOVE Discussion of radius and sigma values from blur below to
here, as part of the general overall discussion of convolution operators.
Demonstration with circles and bell curve graphs.
Sigma is a density function in Statistics, as represents a distance for
with in which 90% of the effect (whatever that is) applies.
The sigma value determines the 'neighbourhood'.
The radius just limits the overall distance from the pixel and is more a
'memory' and processing speed factor. (graph example)
If you must set its value set it to at least 2 times that of the sigma.
Otherwise set it to zero and let IM decide on a good value to use (which
internally can be very large).
In other words 0x5 will set the value of the current pixel, based on all the
pixels surrounding with 90% of the effect from the pixels within 5 pixels
radius.
The Game of Life
A mathematical 'game' of Cellular Automation, a good introduction of
convolution.
Basic image modifications
-despeckle -enhance
-sharpen -unsharp
-noise -spread -displace
-median
Set pixel to the median of all pixels within a given radius (median =
half pixels on one side, half on the other). A way of "de-speckling" an
image (such a dust in a scan). It could distort edges and remove thin
lines.
This filter is the best technique to use for removing Salt & Pepper
noise.
It is suggested that a trim for an original image, should use the
diagnostic output from the median operation to find the bounding box.
-adaptive-sharpen radius x sigma
Adjust sharpening so that it is restricted to close to image edges
as defined by edge detection.
-adaptive-blur radius x sigma
Blur images, except close to the edges as defined by an edge detection
on the image. Eg make the colors smoother, but don't destroy any
sharp edges the image may have.
-adaptive-resize
Resize but attempt not to blur across sharp color changes
Sharpening Images
Sharpening is a the computer graphics algorithm that is most often see on TV
shows and movies. Picture the police force 'cleaning up' a 'zoomed in' photo
of a licence plate of a bank robbers car, or the face of a man on a fuzzy shop
camera video, and you see what I mean.
Basically what they are doing is attempting to recover the fine detail of an
image which was lost due to an image natural blurring from camera lens or low
scale resolution images.
Sharpen Arguments? (expand)
The most important factor is the sigma. As it is the real control of the
sharpening operation. It is only due to historical accident it is the second
term in the above.
It can be any floating point value from .1 for practically no sharpening to
3 or more for sever sharpening. 0.5 to 1.0 is rather good.
Radius is just a limit of the effect as is the threshold.
Radius is only in integer units as that is the way the algorithm works, the
larger it is the slower it is. But it should be at a minimum 1 or better
still 2 times the sigma.
First forget the first number, just use 0 which will then use the best number
for the 'sigma' factor you give. The larger the sigma the more it sharpens.
-sharpen 0x.4 | very small
|
-sharpen 0x1.0 | about one pixel size sharpen
|
-sharpen 0x3.0 | probably getting too large
|
The "
-sharpen
" operator
is sort of an inverted blur. In fact it works in just about the same way. For
examples which show how this is related to blur see,
Image
Processing By Interpolation and Extrapolation.
For example lets blur a simple image then attempt to sharpen it again
to remove the blur.
convert -font Gecko -pointsize 72 label:A A_original.jpg
convert A_original.jpg -blur 0x3 A_blur.jpg
convert A_blur.jpg -sharpen 0x3 A_blur_sharp.jpg
convert A_blur_sharp.jpg -sharpen 0x3 A_blur_sharp_x2.jpg
|
As you can see the result is not perfect, as spreading the pixels out will
make the sharp corners of the image less distinct. Particularly notice the
extra thickening that resulted at the corner of the two lines at the very top
of the image, as well and the near disappearance of the thin lines.
Even repeating the operation or increasing the size of the area of the sharpen
will not help return the image back to the exact original as you have
basically lost the finer detail from the image blurring. However the macro
detail can be recovered quite well.
It is sharpening algorithms which can recover of finer detail in a blurred, or
heavily zoomed image, that makes big money in software packages used by
police forces, astronomers, and government spy agencies.
Under Construction
Unsharp? How does this differ to sharpen?
convert A_blur.jpg -unsharp 0x5 A_blur_unsharp.jpg
|
Blurring Images
Blurring images so they become fuzzy may not seem like a useful operation, but
actually is very useful for generating background effects and shadows. It is
also very useful for smoothing the effects of the 'jaggies' to
anti-alias the edges of images, and to round out
features to produce highlighting effects.
Blurring is so important it is an integral part of
image resizing, though a different method of blurring, which is restricted
to within the boundaries of a single pixel of the original image.
Their are two general image blurring operators in ImageMagick. The "
-gaussian
" spread and "
-blur
". The results of the two as
very close, but as "
-blur
"
is a faster algorithm, it is generally preferred to the former even though the
former is more mathematically correct. (See
Blur vs
the Gaussian operator.)
Blur/Gaussian Arguments
The arguments for "
-blur
"
and "
-gaussian
" are
the same, but to someone new to image processing, the argument values can be
confusing.
-blur {radius}x{sigma}
The important setting in the above is the second
sigma value. It can
be thought of as an approximation of just how much your want the image to
'spread' or blur, in pixels. Think of it as the size of the brush used to
blur the image. The numbers are floating point values, so you can use a very
small value like '
0.5
'.
The first value
radius, is also important as it controls how big an
area the operator should look at when spreading pixels. This value should
typically be either '
0
' or at a minimum double that of the
sigma.
To show you the effects of the options lets take this simple image, with a lot
of surrounding space (blur operators need lots of room to work), and create a
table of the results for various operator settings. I also purposely used a
font that contains both thick and thin lines see the fuzzing of small line
details and large areas of color.
convert -font Gecko -pointsize 48 label:A \
-bordercolor white -border 20x10 blur_source.png
| |
|
A small radius limits any effect of the blur to a circle of that size. As such
using a very small
radius such as '
1
' effectively turns
off blurring.
Also notice that for a smallish
radius but a large
sigma you see
a slight squaring of the result. Especially for the output of
"
-blur 5x8
". This is caused by the small radius 'cutting
off' the area blurred in a detrimental way. As such...
Never use a radius smaller than the sigma for blurs
The exception to this and the ideal solution is to use a
radius of zero
(See the last line of the above table). In that case the operator will try to
automatically determine the best
radius for the
sigma given. The
only time I would use a
radius was when the IM starts reporting that it
has become too large for the image involved. So..
When possible use a radius of zero for blurring operations
Small values for the
sigma are typically only used to fuzz lines and
smooth edges on images for which no anti-aliasing was used (see
Anti-Aliasing for more info). In that situation I
find a blur of '
1x0.3
' a useful value to remove most of the
'jaggies' from images. Did I mention all values are floating point numbers?
Large values however are useful for producing fuzzy images, for backgrounds or
shadow effects (see
Compound Fonts), or even image
highlighting effects (as shown thought the
Advanced
Examples page).
Due to the way IM handles '
x
' style of arguments, the
sigma in the above is optional. However it is the more important
value, so it should be
radius that is optional, as
radius can be
automatically determined and has little effect on the result. As such the a
single value argument to these type of convolution operators is useless. This
is unlikely to change as it has been this way for a very long time, and would
break too many things.
Blur uses the Channel Setting
To demonstrate blur, lets start simply by generating a fuzzy black circle on a
light blue background...
convert -size 70x70 xc:lightblue \
-fill black -draw 'circle 35,35 20,25' circle_on_blue.png
convert circle_on_blue.png -blur 0x8 circle_on_blue_blur.png
| |
|
As you can see a blurring a plain image like this has no problems. It just
works, as you would expect.
But if we try this again with an image containing a transparent background...
convert -size 70x70 xc:none \
-fill black -draw 'circle 35,35 20,25' black_circle.png
convert black_circle.png -blur 0x8 black_blurred.png
| |
|
Hang on, what happened! The image didn't change!
Well in actual fact the operator did work. But "
-blur
" as a grey-scale channel
operator, is limited by the "
-channel
" setting, to just the three colour channels.
That means only the three color channels of the image were blurred, leaving
the transparency or alpha channel of the image as is.
In the above however, the image is a fully opaque circle on a background
canvas of the color '
none
', which IM defines as fully-transparent
black! That which means we have a black circle, on a transparent black
background. In other words a image in which all the colors are black, with
some parts opaque, and other parts
transparent.
Consequently when we blurred the image we only blurred black with black, which
as you can probably guess, produced, black! Thus the result had no change in
color.
Also we never touched the alpha or transparency channel of the image, so we
just ended up with the transparency of the image being unchanged. That is a
black circle!
What we really wanted to do, is blur all four image channels, particularly the
alpha channel. To do this we set the "
-channel
" setting to all four
channels of the image (EG: using a value of '
RGBA
').
convert black_circle.png -channel RGBA -blur 0x8 black_blurred_RGBA.png
| |
|
Just to summarize...
Always use a "-channel RGBA
" setting
when blurring images with transparency.
|
IM version 5.5.7 would have blurred all four color channels automatically
but the operator has other, buggy effects for images with transparency.
See Blur with Transparency Bug for
more details.
|
|
Some image formats such as GIF and JPEG do not handle semi-transparent
pixels. As such I suggest you use PNG format for any images with some
form of semi-transparent colors, if possible.
|
As you can see from the above, the "
-channel
" setting is very important for a grey-scale operator such
as "
-blur
". But is not
the only thing that can be important when using such an operator.
For example lets try that last 'forgot the "
-channel
" setting' example
again, but this time with a yellow circle.
convert -size 70x70 xc:none \
-fill yellow -draw 'circle 35,35 20,25' yellow_circle.png
convert yellow_circle.png -blur 0x8 yellow_blurred.png
| |
|
Notice that instead of getting unchanged image as we did with a black circle,
we instead produces a horrible looking yellow circle with black creeping in
around the edges. Yuck!
This problem is caused by a fact that few new IM users realise.
Transparent pixels has Color, even if you can't see it.
In the above case that transparent color was black, which leaked into the
yellow circle.
Of course we can fix this by setting the "
-channel
" setting correctly for
a transparent image, things do work as expected.
convert yellow_circle.png -channel RGBA -blur 0x8 yellow_blurred_RGBA.png
| |
|
Blur Internals
Lets take this step further with a more complicated example, which will let
use explore exactly what "
-blur
" is doing internally.
Here we create a very special image of a yellow circle, which has been drawn
on a fully-transparent red background. This will let us see the effect of a
transparent color has when blurring images.
convert -size 70x70 xc:'#F000' \
-fill yellow -draw 'circle 35,35 20,25' yellow_on_red.png
| |
|
We can see the color of the transparent parts of the image by effectively
deleting the alpha or matte channel of the image using the "
+matte
" operator.
convert yellow_on_red.png +matte yellow_on_red_matte.png
| |
|
Now lets try blurring just the colors of the image again, using the default
'
RGB
', "
-channel
" setting.
convert yellow_on_red.png -blur 0x8 yellow_on_red_RGB.png
| |
|
As you can see the fully-transparent red background of the image has now crept
into the visible yellow circle, giving it an interesting orange edge, as as it
did previously. You may like this effect, but their are better ways of
generating it, than to rely on invisible fully-transparent colors.
Just prove you can blur this image correctly, lets do it properly...
convert yellow_on_red.png -channel RGBA -blur 0x8 yellow_on_red_RGBA.png
| |
|
The reason that blurring with the alpha channel produces no orange colors as
it did previously, is that when the "
-blur
" operator sees that the alpha channel is involved (according
to the current "
-channel
" setting), it will only blur using the pixels which are
visible according to that alpha channel. If the alpha channel is not
involved, it will completely ignore it, and the fully-transparent red will
blur with the yellow to produce various shades of orange.
Basically the blur algorithm has been modified to ignore all the
fully-transparent pixels in the image, no matter what color they may have.
Any semi-transparent pixels are still involved, but their effect on the result
is also moderated by just how visible they are. The result is that the circle
has become a fuzzy semi-transparent yellow spot. Just what the user probably
was trying to achieve.
If you really like you can blur both the colors and the alpha channel
separately, thus effectually disconnecting the algorithms 'visibility
adjustment' on the color channels. The result is more like a sun
shining through a dirty brown haze.
convert yellow_on_red.png -channel A -blur 0x8 \
-channel RGB -blur 0x8 yellow_on_red_GS.png
| |
|
This last example produced what a pure grey-scale operator would have produced
if there was absolutely no interaction between the alpha channel and the
colors within the image (transparent or otherwise). That is each of the red,
green, blue, and alpha channels are blurred completely separately to each
other as if they were each a separate grey-scale image.
Just remember, as the default "
-channel
" setting is '
RGB
', the default action is not
to blur the alpha channel,
and to blur invisible colors with the
visible color within the image.
Aren't you glad that "
-blur
" is no longer always a pure grey-scale operator. Though you
can use it in that way if you really want. You didn't always have this choice
however...
|
Before IM version 6.2.4-4, the "-blur ", and "-gaussian " operators were applied as pure grey-scale
operation, and as such did not adjust colors according to their alpha
channel 'visibility'. The result was that any form of blurring with
transparency, almost always produced horrible 'black halo' effects, such
as purposefully generated in the previous example.
This was classed as a major long term bug within the IM distribution, and
one that was very hard to workaround. For more details of this problem,
see the Blur with Transparency Bug page.
|
FUTURE: Blur and Trimming Images.
Blur vs Gaussian
There has been some confusion as to which operator, "
-blur
" or the "
-gaussian
" is better for blurring
images. First of all "
-blur
"
is faster, but it does this using two stage technique. First in one axis,
then in the other. The "
-gaussian
" operator on the other hand is more mathematically
correct as it blurs in all directions simultaneously, using a proper
'convolve' operation, but at a large speed cost.
In a more technical context, "
-blur
" is a 2 pass, 1 dimensional orthogonal convolution filter,
while "
-gaussian
" is a
2 dimensional cylindrical convolution filter. For a blurring function, the
results should be the same, unlike the use of other 'filtered' convolution
operations. However the two pass system means that there is an intermediate
stage in which rounding, or quantum effects, can occur.
Cristy also bears this out when he reported... You should always use "
-blur
" instead of "
-gaussian
" because its faster.
Some pixels will be different on the interior due to rounding, and the edge
pixels may be different because '
BlurImage()
' uses a different
edge algorithm to the '
GaussianBlur()
' API.
In summary, the two operators are slightly different, but only minimally. As
"
-blur
" is much faster, use
it. I do.
Generating Shadows
The "
-shadow
" operator
is a advanced operator that was developed with the IM example pages.
Basically it represents a very complex blur and re-coloring of transparency
shape of the given image. This is an operation that IM users performed all
the time, but required a good deal of knowledge to figure how to achieve
correctly.
The operator will take an image (usually a clone, and may already have some
transparency) and convert it into a shadow image that can then be positioned
under the original image at given offset, (generally by using the special
Layer Merge operator.
Here for example is a standard method of shadowing an existing image, using a
navy shadow color to match this web page.
convert rose: \( +clone -background navy -shadow 80x3+5+5 \) +swap \
-background none -layers merge +repage shadow.png
| |
|
Note how the shadow image is correctly offset from the image.
You can even zero the blur '
sigma' value and create a hard shadow, but
semi-transparent shadow.
convert rose: \( +clone -background navy -shadow 60x0+4+4 \) +swap \
-background none -layers merge +repage shadow_hard.png
| |
|
The use of "
-layers
merge
" to layer shadow images with the original image makes it easy to
generate shadows from a light source from any direction, not just the upper
left side.
convert rose: \( +clone -background navy -shadow 80x3-5+5 \) +swap \
-background none -layers merge +repage shadow_other.png
| |
|
Shaped Shadows
Now "
-shadow
" was designed
with shaped images in mind, (and this is the reason for its complexity).
For example here is a typical shadowed font.
convert -background none -stroke black -fill white \
-font Candice -pointsize 48 label:A -trim
\( +clone -background navy -shadow 80x3+3+3 \) +swap \
-background none -layers merge +repage shadow_a.png
| |
|
|
The Layers Merge method was added to IM
v6.3.6-2. Before this you would need to use the similar layer flattening
operator "-mosaic "
instead. However this operator has problems (see next).
|
Shadows and the Offset Problem
The problem with shadow is that a blurry shadow extends in all directions. To
compensate the "
-shadow
"
operator enlarges the actual original image by adding a border 2 times the
size of the blur '
sigma' value given. That is if you blur a shadow
using '
x3
', it will enlarge the image by 12 pixels (2 times 3
pixels on every side).
To compensate for this enlargement, a shadow image is also given an
appropriate negative
Virtual Canvas Offset so
that it will be positioned correctly relative to the image being shadowed. For
a normal image that means the shadow image generated will have a negative
offset.
This however generates a problem when your IM does not have a the "
-layers
" method
'
merge
' available. For example here we try to add a shadow on
the left side, of the image as if a light shone from the upper right.
convert rose: \( +clone -background navy -shadow 60x3-5+5 \) +swap \
-background none -mosaic shadow_left_clipped.png
| |
|
As you can see as the shadow, was clipped by the "
-mosaic
" operator, because of the
negative offset. Not good!
One solution is to add an initial offset to the original image so the
resulting shadow images offset will not be negative.
convert rose: -repage +11+0\
\( +clone -background navy -shadow 80x3-5+5 \) +swap \
-background none -mosaic shadow_left.png
| |
|
Another method is offset both images by an appropriate amount after the shadow
has been generated. This removes any negative offsets before you "
-mosaic
" them together.
this requires the use of a '
!
' flag with "
-repage
" to add the given offset
to both images.
convert rose: \( +clone -background navy -shadow 80x3-5-5 \) +swap \
-repage +11+11\! -background none -mosaic shadow_tl.png
| |
|
The amount of space need should be at least
2×'
sigma'-'
offset', or in this case 2×3--5 ⇒ 11
pixels, or you risk clipping the shadow. However space of about
'
sigma'-'
offset' usually produces an acceptable level of
clipping.
It is a lot easier to just use a
Layers Merge
if it is available.
Shadow Outlines
You can also use "
-shadow
" to generate a fuzzy outlines of shapes, such as text, but
you will need to offset the image to provide space on the top-left for the
effect, of at least 2 times the blur 'sigma' value.
convert -background none -fill white \
-font Candice -pointsize 48 label:A -trim -repage 0x0+6+6 \
\( +clone -background black -shadow 100x3+0+0 \) +swap \
-background none -layers merge +repage shadow_outline.png
| |
|
Here you can see one problem with using a blurred shape for outlining.
The edge of the shape will always be at least 50% transparent, by the very
nature of how blurring works.
To compensate you can either enlarge the shape of the image that will be
shadowed, (for an example see
Denser
Soft Outline Font). Or you can adjust the matte values of the shadow
image (using "
-level
") so
that 50% transparent at the shape edges becomes fully transparent.
convert -background none -fill white \
-font Candice -pointsize 48 label:A -trim \
\( +clone -background black -shadow 100x3+0+0 \
-channel A -level 50%,100% +channel \) +swap \
+repage -gravity center -composite shadow_outline_darker.png
| |
|
The above also shows another method of handling the shadow offset. Basically
I just junked all "
-shadow
" generated offsets (using "
+repage
"), and center overlaid
the original image on the larger shadow image.
You can use that method for normal shadowing too, by adding a appropriate
composition "
-geometry
" offset the image, instead of getting "
-shadow
" to offset the generated
shadow image.
convert -background none -fill white -stroke black \
-font Candice -pointsize 48 label:A -trim \
\( +clone -background navy -shadow 80x3 \) +swap \
+repage -gravity center -geometry -3-3 -composite \
shadow_geometry_offset.png
| |
|
The offset is a negative as you are offsetting the original image relative to
the shadow.
This method will however clip the original source image, rather than the
shadow image if the offset becomes larger that twice the blur 'sigma'. As
such it can not be used for 'hard shadows' (using a '
x0
' blur
'sigma'), unless you again add some extra space to the shadow image for the
original to be added.
For some practical examples of shadowing see
Thumbnail shadowing and
Better 3-D
Logo Generation.
Shadow in the Montage Command
As of IM v6.3.1 the "
montage
" "
-shadow
" setting, started to make
use of the soft 'shaped' shadows this operator provides.
montage -label Rose rose: \
-background none -geometry +5+5 -shadow shadow_montage.png
| |
|
However as you can see no controls over the color, fuzziness and offset of
that shadow is provided. Though "
montage
" never did provide such
controls, beyond a simple on/off option.
Shadow Internals
Internally "
-shadow
" is
extremely complex. Basically not only does it need to enlarge an image to
accommodate a 'soft blurry shadow', but it also needs to blur the existing
shape of the image, set its color appropriately, and finally adjust virtual
page/canvas offsets; all to the users specifications.
For example given the following "
-shadow
" command...
convert image_clone.png -shadow 60x4+5+5 image_shadow.png
|
The equivalent IM operation would be...
convert image_clone.png -matte \
-bordercolor none -border 8 -repage -8-8\! \
-channel A -virtual-pixel transparent \
-blur 8x4 -evaluate multiply .60 +channel
-fill {background_color} -colorize 100% \
-repage +5+5\! image_shadow.png
|
Note that the value 8 in the above is two times the blur sigma, so as to
provide enough space for the blurred shadow. However this means the final
image will be 4 times sigma pixels larger. To compensate an equal amount of
negative offset is also added.
Now as 2 time sigma negative offset will be added to the generated image,
care should be taken to avoid the shadow being clipped, or incorrectly
positioned relative to the original image. That can be done by either giving
the original image an initial positive offset (such as 8-5 or +3+3 pixels),
or using
Layers Merge which understands
negative offsets without clipping the final image.
Basically as previously mentioned caution is advised to correctly handle
the offsets involved with shadow images.
|
The PNG, and MIFF formats are the only image formats I know that can
handle a negative offset, as well as semi-transparent pixels. I
recommended PNG be used if saving shadow images, for future use.
|
As I said "
-shadow
" is a
very complex operation.
Of course while the above example is close to what "
-shadow
" does internally, it is
not exactly the same.
The actual "
-shadow
"
operator, does not change any of the global settings, such as
border/background/fill colors, or the current virtual-pixel setting. Also it
will short circuit the use of the "
-blur
" operator if the blur sigma is set to 0, to prevent
the blur function from giving a warning for a zero sigma or radius.
FUTURE: overlaying multiple shadows
Overlaying two images with shadows, produces a unrealistic darkening of the
shadow where the shadow overlaps. This darkening would be correct if each
object was lit by separate light sources, but more commonly the objects are
lit by the same light source.
For an example, see the line of photos across the top in..
http://sempre-crescendo.nl/test/im
The solution is to overlay the one image over the other (shadow of one image
over the other), then mask out and re-create the background shadow of both
images together. That is the background shadow should be generated
separately to the shadow falling on the behind object.
This complexity gets worse when you have three objects shadowing each other.
Also the offset and blurring from the shadow of each object should technically
be separate. To generate that level of complexity, probably a 3-d ray-tracing
program should be used instead (sigh).
Specialized Blurs
There are a few other sorts of blurs that have been added to IM version 6,
which have very special uses. These operate in specific directions, and not
in all directions as most other 'convolve'-style operations do.
WARNING: All these blurs are experimental, and syntax has NOT been finalized!
Radial Blur
You can blur the image around in a circle using a "
-radial-blur
", as if it was
spinning around and around. Though technically this is a rotational or
angular blur, rather than a radial blur.
Note however that like a normal "
-blur
" operator, "
-radial-blur
" is affected by the "
-channel
" setting.
convert -size 70x70 xc:none \
-stroke red -strokewidth 15 -draw 'line 35,5 35,65' \
-stroke yellow -strokewidth 9 -draw 'line 35,5 35,65' \
-channel RGBA -radial-blur 30 radial_blur.png
| |
|
You can place the object off center (by adding some space to an image) for
more interesting "
-radial-blur
" effects.
convert -size 70x70 xc:none \
-stroke red -strokewidth 15 -draw 'line 5,50 65,50' \
-stroke yellow -strokewidth 9 -draw 'line 5,50 65,50' \
-channel RGBA -radial-blur 90 radial_blur_90.png
| |
|
The blur argument is the angle the radial-blur covers. That is half that angle
in each direction from the original image. So an angle of 180 is over a half
circle, while 360 degrees will blur the image in a full circle.
convert -size 70x70 xc:none \
-stroke red -strokewidth 15 -draw 'line 5,50 65,50' \
-stroke yellow -strokewidth 9 -draw 'line 5,50 65,50' \
-channel RGBA -radial-blur 180 radial_blur_180.png
| |
|
convert -size 70x70 xc:none \
-stroke red -strokewidth 15 -draw 'line 5,50 65,50' \
-stroke yellow -strokewidth 9 -draw 'line 5,50 65,50' \
-channel RGBA -radial-blur 360 radial_blur_360.png
| |
|
You can even add a little
Image Warping to
make the effect more interesting...
convert -size 70x70 xc:none \
-stroke red -strokewidth 15 -draw 'line 5,50 65,50' \
-stroke yellow -strokewidth 9 -draw 'line 5,50 65,50' \
-channel RGBA -radial-blur 180 -swirl 180 radial_swirl.png
| |
|
The full circle radial blur, can be used to generate a rough circular
gradients. However formulating the correct shape to generate the correct
gradient can be extremely difficult, and probably not worth the effort.
convert -size 80x80 xc:lightblue -fill red \
-draw "path 'M 40,40 C 43,43 47,47 50,40 \
S 52,23 40,20 S 14,22 10,40 S 15,75 40,79 Z'" \
radial_gradient_pre.gif
convert radial_gradient_pre.gif -radial-blur 360 radial_gradient.gif
| |
|
Motion Blur
You can add a linearly fading blur in one direction only (giving a radius and
sigma, plus an the angle in which the blur should occur), by using a "
-motion-blur
".
This gives your image a look as if it (or the camera) was moving very very
fast.
convert -size 70x70 xc:none -channel RGBA \
-fill yellow -stroke red -strokewidth 3 \
-draw 'circle 45,45 35,35' -motion-blur 0x12+45 motion_blur.png
| |
|
Note that not only does the object get a trail, but the edges in the direction
of motion also has the background blurred into it.
This leading edge blurring can be improved by re-drawing or overlaying the
original image and re-applying a smaller "
-motion-blur
" multiple times.
convert -size 70x70 xc:none -channel RGBA \
-fill yellow -stroke red -strokewidth 3 \
-draw 'circle 45,45 35,35' -motion-blur 0x8+45 \
-draw 'circle 45,45 35,35' -motion-blur 0x6+45 \
-draw 'circle 45,45 35,35' -motion-blur 0x2+45 \
motion_blur_redraw.png
| |
|
Multiple motion blurs can be made to effect some spread of the trailing
tail of the moving object. Sort of like dissipating smoke or flames.
convert -size 70x70 xc:none -channel RGBA \
-fill yellow -stroke red -strokewidth 3 \
-draw 'circle 45,45 35,35' -motion-blur 0x12+25 \
-draw 'circle 45,45 35,35' -motion-blur 0x12+55 \
-draw 'circle 45,45 35,35' -motion-blur 0x12+40 \
motion_blur_spread.png
| |
|
This technique can be used to generation a spreading shadow on the ground.
Alternatively you could generate a motion blur, then radial blur it a little
though that requires some image shifting to get the center right.
FUTURE example of a spreading shadow -- in compound fonts
You can also add some extra
Image Warping
to make things even more interesting...
convert -size 70x100 xc:none -channel RGBA \
-fill yellow -stroke red -strokewidth 3 \
-draw 'circle 35,80 45,70' -motion-blur 0x20+90 \
-background none -rotate 50 -wave 5x25 -rotate -50 \
-gravity center -crop 70x100+0+0 +repage \
-draw 'circle 35,80 45,70' -blur 0x2 \
motion_wave.png
| |
|
Note that while "
-radial-blur
" blurs in both directions, "
-motion-blur
" only
blurs in one direction.
In both cases I recommend you pad your image with extra space around the edge
(generally using "
-border
") as both of these specialized blurs have strong edge
effects that is best to avoid.
If you find a more practical or interesting example or use of the above please
email me a
copy.
Feathering Shapes
When you are cutting out a shape from an image, you often want to feather or
blur the edges of the shape a little to give it a smoother look, and to
de-emphasise any parts outside the shape that may have accidentally been
included, or jsut allow the image to fit into the background more.
For example here I have a GIF image which I overlay a light colored baground
convert shape.gif -background wheat -flatten overlaid.png
| |
|
However as I am overlaying a GIF image with boolean transparency, and as a
result has highly aliases, or staircase-like edges, the image looks very much
out of place on the background. If you were dealing with real life images,
the above result would look very artifical.
But by bluring the image transparency a little, I can make the overlay
fit onto the background more smoothly.
convert shape.gif -alpha set -virtual-pixel transparent \
-channel A -blur 0x0.7 -level 0,50% +channel \
-background wheat -flatten edge_blured.png
| |
|
This by the way is the exact same technique used from generating
Soft Edges on thumbnails.
For more examples of this look at the results of Fred Weinhaus's "
feather" masking
script.
As you can see this works very well for simple cases, when there is a high
contrast between the overlaid image and the background. However there are
serious problems when you want to use either a much larger feathering blur
factor, or the two images are both very light colors.
Under Construction
Note that as blur extends both into and out of the are the alpha channel has
to be adjusted so that the edge of the shape is zero (fully-transparent), but
quickly becomes fully-opaque as to get further from the edge. An example of
just such an alpha channel adjustment is provided by
Color Lookup Tables with Transparency
This adjustment is critical, otherwise instead of de-emphasising the area
outside the shape, you add a semi-transparent shadow or halo of the area
outside the shape.
However blur has a particularly nasty problem in also smoothing the outline of
the shape. For example...
convert -size 100x60 xc: -draw 'polygon 5,5 50,30 5,55 95,30' \
sharp_angles.gif
| |
|
If you blur this particular shape you get...
convert sharp_angles.gif -blur 0x5 feather_blurred.gif
| |
|
Notice how the points of the mask was de-emphesised more than the the edges.
Also how the internal angle seemed to be 'filled in', so as to show even more
of the original background.
You can see this more clearly if we threshold the image.
convert feather_blurred.gif -threshold 50% feather_blur_thres.gif
| |
|
This is the problem of using 'blur' as a method of fethering images. And is
especially of concern when dealing with things like fingers, and ears as well
as the areas between the legs. That is the appendages themselves and the
spaces in between.
If the image has a cartoon like border outline, then this is not as big a
problem for a '1 pixel' feather. But for real life images (with no definitive
borders), it is a real problem.
A proper solution would be to find some sort of measure about how distant a
point if from an edge of the shape, but such that two close edges do not add
there effects together.
A set of convolution operators called Morphology.
Convolution Kernels
Convolution Kernels...
General Convolution Operator...
-convolve -bias
-convolve 1 does not modify the image
-bias {number} -convolve 1 adds a fixed 'bias' to each pixels result.
-bias 16384 -convolve .5 half color values, add 1/4 to each pixel
reduces black - grey25 and white to grey75
More info at
http://www.gamedev.net/reference/programming/features/imageproc/page2.asp
http://www.dfanning.com/ip_tips/sharpen.html
A basic 'kernel' for simple blur is
0,1,0
1,1,1
0,1,0
or..
convert source.png -bias 0 -convolve 0,1,0,1,1,1,0,1,0 blur.png
Sharpening using a laplacian convolution 'kernel'
-1, -1, -1
-1, 9, -1
-1, -1, -1
That is multiply each pixel by 9, then subtract a copy of each of its 8
neighbouring pixels.
A sharpening-mask ???
-1, -1, -1
-1, 8, -1
-1, -1, -1
Emboss an image
-1,-1, 1
-1, 0, 1
0, 1, 1
However you may need to darken the result
to prevent it being 'clipped' so a bias may also be needed...
-bias 10000 -convolve -1,-1,0,-1,0,1,0,1,1
Thanks to Krzysztof Gajda, aka 'cra3y' on the IM Forums, for the above info.
NOTES: The results of convolve is normalized (should it?)
EG: -convolve 0,0,0,0,.5,0,0,0,0
should produce a image multiplied by .5 but is then normalized!
It is such a low level routine, I would not expect it to normalize the
results.
Morphology....
If you want to generate a kernel that is all ones.
for example a 7x7 array of 1's you can use a extrememly large
sigma and specify the appropriate radius, in a gaussian blur.
As such
-convolve 1,1,1,1,1,.....
for a total of 49 ones is equivelent to
-gaussian 3x65535
This allows you to generate square kernel for binary mophological operators
'Dialate' for a 3x3 square kernel (radius=1) is thus
-gaussian 1x65535 -threshold 0
'Erode' is thus
-gaussian 1x65535 -threshold 99.999%
'Open' is naturally a 'Dialate' followed by a 'Erode'
and a 'Close' is a 'Erode' followed by a 'Dialate'
A larger square kernel can be specified using larger radii
Create your own convolution
-fx with relative pixels EG: p[-1,-1]
also see -virtual-pixel setting
Created: 19 April 2004
Updated: 6 October 2007
Author: Anthony Thyssen,
<A.Thyssen@griffith.edu.au>
Examples Generated with:
URL: http://www.imagemagick.org/Usage/convolve/