- Index
- ImageMagick Examples Preface and Index
- Digital Camera Meta-Data, the EXIF Profile
- Digital Photo Orientation
- Color Improvements
- Photo Conversion Cookbook
One of the prime uses of ImageMagick is the handling and modification of
photographs that were taken with the new modern digital camera.
These cameras generally take quite large, high resolution photos, and include
in them meta-data about the time, scale, zoom, camera, orientation, and so on.
There are even plans to link cameras to mobile phones, so that it can even
make a guess as to where you were when the photo was taken and who might
be in the photo (from what mobile phones are in font of it).
Here we look at the basics of handling digital photos, and even converting
them for other purposes, such as artistic renderings.
Special thanks goes to Walter Dnes, a digital camera user, for his help in the
enhancement of digital photos.
Digital Camera Meta-Data, the EXIF Profile
When a digital camera takes a photo, it also includes a lot of extra
information in the JPEG save file. This meta-data is known as the EXIF
profile, and is provided specifically for photographic labs and development.
The ImageMagick "
identify
" with a "
-verbose
" setting will display
this Exif information.
Here is the EXIF data of a photo I took of a
Pagoda, Kunming Zoo, in Southern China.
identify -format "%[EXIF:*]" pagoda_sm.jpg |\
sed 's/\(.\{46\}\).*/\1/' | column -c 110
|
|
Scripted readers of EXIF data, or any identify output, should do so in a
case in-sensitive way. Many older versions of IM for example, will
output "EXIF: " (uppercase) rather than "exif: "
(lowercase).
|
There is a lot of information about this photo in the above.
For example
- My camera is a Panasonic ('
Make
'), DMC-LZ1
('Model
')
- The camera took photo rotated ('
Orientation
')
But I must have corrected that rotation without adjusting the EXIF data.
The camera was also tilted upward slightly, but that info is not recorded.
- The '
FocalLength
' of '37mm
show that I did not
make use of my cameras Optical Zoom feature. My camera could go up to a
6X optical zoom for a 'FocalLength
' of '366/10
'
or '222mm
.
- And '
DigitalZoomRatio
' shows I did not digitally zoom either.
- The camera also used a fast 1/8 second '
ExposureTime
', and
a aperture 'MaxApertureValue
' of 3mm, or
'FNumber
' of '5.6
' and a
'ISOSpeedRating
' of '64
'.
- The flash ('
LightSource
') was not used.
- The original image was 1728 by 2304 pixels
('
ExifImageLength
' and 'ExifImageWidth
').
Though the actual image, if you like to check is smaller, so I must have
cropped and/or resized it.
- And probably most importantly, it was taken around 14:05pm on 9th of
July 2005, according to the '
DateTime
' string. That assumes
that I had the cameras time set correctly (which I did).
Also included by not listed above is a small 'thumbnail' preview image that
the camera used on its own display.
There is also features to mark photos you want to be 'developed' or printed by
photographic printers, and to adjust other printing parameters. However this
is rarely used by most people.
In the future there is also talk of including things like, your GPS location
and compass direction (where and of what building you were photographing),
and who's mobile phones were nearby (who is possibly in the photo). Amazing
isn't it.
Many of these settings can be very useful to users, but the most useful to
people is generally the Date and Time of the photo. This of course assumes
Most people however are most interested in the Date/Time of the photo,
and the orientation of the image so they can rotate it correctly. That is what
we'll look at next.
All this data, and especially the preview image, can take up quite a lot of
space in the image. And it may be that I don't actually want everyone in the
world knowing that I was in Kunming, China in July 2005. As such you may like
to remove EXIF data from your images before actually publishing it on the
World Wide Web. Especially if you plan to make a small
thumbnail
Also the size of an image from a digital camera usually very large, allowing
you to print it at photo quality level, but is far too large for use of the
WWW, and especially not for thumbnails. As such unless you want users to
actually print photo quality images, I would not publish the original image
directly.
The above image for example has been cropped and resized for IM examples
usage, but I purposely left the EXIF data intact for the example. Normally I
would not do this for published images.
Digital Photo Orientation
I have been told that Photoshop will automatically rotate digital images based
on the EXIF '
Orientation
' setting, IM will also do this by
including a "
-auto-orient
" operator, after reading in the image.
However, and this is important
JPEG Format is Lossy
What this means is that any time to decode and save the JPEG file format you
will degrade the image slightly. As a general image processor, IM will always
completely decode and re-encode the format, as such it will always degrade
JPEG images when it re-saves the image. For more information on the nature of
the JPEG format see
JPEG Image File Format.
The point is to only use IM to correct digital photo orientation (using
"
-auto-orient
")
when you are also performing other image modifying operations, such as
Thumbnail Creation,
Annotating Images,
Watermarking or even
Exposure Adjustments.
FUTURE: quick thumbnail example
IM can extract the current orientation (as a number) from the photo using an
Image Property
Escape...
|
identify -format '%[exif:orientation]' pagoda_sm.jpg
| |
|
IM provides a special "
-orient
" operator (use "
-list orientation
" to see possible values).
|
convert pagoda_sm.jpg -orient bottom-right \
-format '%[exif:orientation]' info:
| |
|
These meta-data setting methods, allow you to adjust the orientation of photos
you have modified, especially ones you have rotated. Note that a correctly
orientated photo has a orientation of '
Top-Left
' or 1.
Of course you should not remove the EXIF meta-data (using either "
-strip
" or "
-thumbnail
"), if you plan to
use "
-auto-orient
"
later in the image processing. Use it before stripping the image meta-data.
If you do want to correct the orientation of your photo, without degrading or
otherwise modifying your image, I suggest you use the
JHead program. For example
here I correct a photos orientation, and delete the built-in preview thumbnail
all the digital photos in a directory.
The
JHead program will
also let you adjust the photos date (if your camera time was set wrong, or you
have travelled to different time zones), extract/remove/replace the preview
thumbnail, set the comment field of the image, remove photoshop profiles, and
do basic image cropping (to remove that stranger exposing himself ;-) so on,
without degrading the JPEG image data.
I recommend this program, or other programs like it (see
Other JPEG Processing Programs), to fix
this information. Just be sure that it does not actually decode/re-encode the
JPEG image data.
FUTURE: pointer to articles on Digital Photo Handling
Under Construction
One final point about orientation. If you pointed your camera almost straight
up or down, the EXIF orientation setting may not resolve correctly. The same
goes for angled or slanted shots. The orientation (and cameras) just have no
senses for these situations.
Your only choice for such photos is to do the rotates yourself using the lower
level non-lossy "
jpegtrans
", or IM "
-rotate
", and then either reset
the EXIF orientation setting (using
JHead or the IM "
-orient
" operator), or just strip
the EXIF profile.
Other IM Lossy Modifications...
If you are also resizing or otherwise modifying the image, such as reducing
its quality and size for use on the web, then data loss is already a fact.
As such during those operations IM can do similar things, allowing you to do
all the required operations in a single 'load-save' cycle.
Rotate ALL images to landscape -rotate 90\<
portrait -rotate -90\>
Color Improvements
Before proceeding, it is recommended that you first look at
Color Modifications for an introduction to the color
processing options that will be used.
Normalizing (using "
-normalize
") high-contrast
line art and graphics can be great. But normalized photos may look unreal,
and, as was said earlier, may not print well either. The "
-contrast-stretch
"
operator can limit the "boundaries" of the normalization, but the "
-levels
" and/or "
-sigmoidal-contrast
"
operator can make "smoother" adjustments (see
Color
Adjustments for a lower level discussion of what these operators do).
The above input is courtesy of "Tong" form the IM Mailing List.
Brightening Under-exposed Photos
Contributed by Walter Dnes
Sometimes there simply isn't enough available light to allow for a proper
exposure. At other times, you may have to use shorter exposure times than
optimal, in order to eliminate motion-blur.
Underexposed digital photos can have darker areas preferentially brightened,
without blowing highlights, by using the "
-sigmoidal-contrast
"
operator, with a '
0%
' threshold level. See
Sigmoidal Non-linearity Contrast for more
details.
Here is a minor underexposure example, which was taken at a free concert after
sunset. This has lots of brightly lit areas, which are clear, but also
dark areas I would like to make more visible.
convert night_club_orig.jpg -sigmoidal-contrast 4,0% night_club_fixed.jpg
|
|
As always, you should use a non-lossy format like TIFF or PNG for
intermediate work. The JPEG format is only used here to reduce disk
space and download bandwidth for web publishing.
Select image to see the enlarged version actually used by the examples
rather than the small thumbnail shown.
|
And here is a major underexposed example, which was a night-time shot from my
balcony looking southwards towards the city of Toronto.
convert night_scape_orig.jpg -sigmoidal-contrast 10,0% night_scape_fixed.jpg
|
The main parameter controls the amount of brightening. The more brightening
required the higher value used. And the grainier the output picture will
look. This is due to the smaller pixel errors also being enhanced.
Sigmoidal contrast brightening tends to de-emphasize the red end of the
spectrum. You may end up having to select a parameter that results in the
most natural flesh tones, rather than the brightness level you really want.
In the case of major underexposure, you will end up with a glorified grainy
black-and-white image after brightening. This is a physical limitation of
digital image enhancement. If there's no colour data present, IM won't
generate it for you. In real life the bricks on the right-hand side of my
balcony are reddish, and the trees below are green.
Binning -- Reducing Digital Noise
Contributed by Walter Dnes
A lot of serious photographers are unhappy with the side-effects of
the "megapixel race" by digital camera manufacturers.
Manufacturers pack more megapixels into a digital camera's sensor by making
them smaller. Smaller pixels result in a noisier picture at the same ISO
setting, which forces people to use lower ISO settings. Using lower ISO
ratings to avoid noise requires longer exposure times. This, in turn, means
that most consumer digital cameras are effectively useless indoors
beyond the 10-foot range of their built-in flash for anything except a
still-life picture taken with the camera on a tripod.
Many digital camera users would gladly trade some pixels for less noisy
pictures at higher ISO settings, but the marketeers who control the companies
refuse to consider this as an option.
Fortunately, the trade-off can be done after the fact on digital
photos. The technical term is 'binning'. The simplified theory goes
like so...
- Take an n-by-n grid of pixels, and average their components to obtain
one "super-pixel".
- Signal is proportional to the combined pixel area, which means that
the amount of signal has increased by a factor of n^2
- Noise is random. Which means that it is proportional to the square root
of the combined pixel area, a factor of n. The net result is that SNR
(signal-to-noise ratio) has increased by a factor of n. See Photo
Glossary, Binning for more details.
When a 1600x1200 digital photo is binned down to 800x600 (i.e. a 2x2
grid) the signal-to-noise ratio is doubled. Similarly, a 2560x1920
picture binned 3x3 to 853x640 pixels will have a factor of 3 improvement
in signal-to-noise ratio.
|
In order to make use of binning, the photo image must be a whole number
multiple of the final desired size.
|
In ImageMagick, the special "
-filter
" setting '
box
' will average groups of pixels
down to a single pixel when you "
-resize
" an image (See
Resize
Filters for details. This means that to do a 'binning' you only need to
resize the image correctly.
Under Construction
Walter Dnes also provided the original script
binn
to perform the calculations, minimally crop the image and perform the
'binning'.
Binning examples 3
Binning examples 4
Photo Conversion Cookbook
Overlapping Photos
Creating a series of overlapping photos is a common task, but one that can be
tricky to do unless you have the right knowledge of IM operators.
The simplest method is to use a
Masked
Composite of the two images, and a mask to select which image to overlay.
First however you need to do some mathematics. For this example, I am using
two thumbnail images 120x90 pixels in size and I want to overlap them
horizontally by 40 pixels. This means the resulting image should be 120 + 120
- 40 pixels long or a 200x90 pixel image.
Next we need a mask. This needs to black one one side, white on the other,
with a 40 pixel gradient in the middle, the size of the final output image.
That is 120 pixels - 40 pixel gives an 80 pixel area for each of the two
non-overlapped areas.
So lets generate a masking image...
convert -size 90x80 xc:white xc:black -size 90x40 gradient: \
+swap -append -rotate 90 overlap_mask.png
| |
|
An alternative way of generating the masking image is to use Fred Weinhaus's
"
plmlut
" horizontal gradient generator script. This has finer
controls for the curvature of the gradient rather than a sharp linear gradient
I generate above.
Now that all of the math is out of the way, all that is left is to do a three
image masked composition, using the mask we just generated. However we will
also need to enlarge the destination (left) image so as to provide enough
space for the overlapping right image (any color), and position the second
image correctly using the appropriate gravity (right, or '
East
').
convert holocaust_tn.gif -extent 200x90 spiral_stairs_tn.gif \
overlap_mask.png -gravity East -composite overlap_photos.jpg
|
And we now have two images, which are overlapped using a linear gradient.
Of course the two commands can be merged into a single command, so that you
don't need to save the 'mask' intermediate image. This is left as an exercise
to the reader.
A slight improvement is to use a more curved gradient over a larger overlap
between the images. This reduces the sharp change visible at the start and
end of the overlap area of the final image. Especially with images contain
large areas of very different colors.
For example, this uses some
Distorted
Gradient techniques to not only generate a smoother gradient curve,
but also to rotate that gradient so as to have a highly angled overlap.
convert -page +0-15 -size 1x30 gradient: \
-sigmoidal-contrast 5,50% -contrast-stretch 0 \
-set option:distort:viewport 180x90-90-45 \
+distort SRT 115 +repage \
holocaust_tn.gif -extent 180x90 +swap \
spiral_stairs_tn.gif +swap \
-gravity East -composite overlap_angled.jpg
| |
|
Yes, the above is rather complex, but it shows just what is possible.
If you plan to do more than two images, a better method is to use the mask to
directly set the transparency of the second and later images. The multiple
images can then be overlaid together all in one go using a
Programmed Positioning of Images. This
technique does not require you to enlarge the original image for the
composition as we did above because IM will do that work for you. You only
need to make sure you position the images correctly.
For example, here I add a 30 pixel gradient to a second and third image,
requiring the images to be placed every 90 pixels (width 120 minus 30 pixel
overlap) from each other. When all images are given the appropriate
transparency and positioning, we just
Mosaic
the layers together, letting IM figure out the final canvas size.
convert -size 90x90 xc:white -size 90x30 gradient: -append -rotate 90 \
hatching_tn.gif \
\( holocaust_tn.gif -clone 0 \
-compose CopyOpacity +matte -composite -repage +90+0 \) \
\( spiral_stairs_tn.gif -clone 0 \
-compose CopyOpacity +matte -composite -repage +180+0 \) \
\( chinese_chess_tn.gif -clone 0 \
-compose CopyOpacity +matte -composite -repage +270+0 \) \
-delete 0 -compose Over -mosaic overlap_series.jpg
|
This can be continued to a longer sequence with relative ease, especially
using the looped technique shown in
Programmed
Positioning of Images. However overlapping photos like this works best
for images with a reasonably common overall color.
One point with such overlapping images. You may notice that for the images at
the end of the sequence, a centered subject may not look very centered due to
the overlap on one side of the image only. This problem can be improved
either by fading the outside edge of those images into transparency, or
chopping of some of outside edge to help re-center the subject of those
images.
ASIDE: It may be that overlaying in a different colorspace may work
better. Anyone like to experiment and report on your results, good or bad?
More complex examples of overlapping and layered images are provided in
Programmed Positioning of Layered Images.
Double Exposures
With old time film based cameras, there was a technique where a picture was
take two or more times without 'rolling' the film. This allowed you to create
what was known as double exposures, where two images taken at slightly
different times were merged together. The result was often a ghosting or
dimming of parts of the image which moved or changed.
However with careful control of the subjects in the image, the lighting
effects, and even the development process, it became possible to make some
very weird or even 'impossible' photos. With digital images it is even
easier as you have even better control of the images.
Basically...
Seeing may be believing, but camera lie!
For example suppose I wanted a image in which I appear in twice! Well that is
easy to do. Here for example are the thumbnails of two quick photos I took
specifically for this example, using a tripod and timer, which I'll use
directly.
Perhaps you can supply a better more amusing photo set?
I will apply the double exposure techniques directly to these thumbnails,
though more typically I would do this using original image files as inputs, so
as to get a result of the highest quality.
Now if I used a traditional film-like 'double exposure' with a old style
camera, the result would be an average of these two images, generating
see-thru 'ghosts' of myself. Here is the digital simulation of this
technique...
convert anthony_1.jpg anthony_2.jpg -average anthony_ghosts.jpg
| |
|
However, what if I don't want ghosts, but properly solid images of myself.
Well then you need to use a mask to select which parts you want to come from
which image.
This mask can be generated in two ways. You can just manually create the mask
by dividing the image along the static or unchanging parts. A rather simple
matter in this particular case...
convert -size 100x90 xc: -draw 'rectangle 0,0 50,89' \
-blur 0x3 anthony_mask.jpg
| |
|
Note that I blurred the mask, so as to 'feather' the cut-over between the two
images. And here I use a
Masked Composition
to merge the images.
convert anthony_1.jpg anthony_2.jpg anthony_mask.jpg \
-composite anthony_doubled.jpg
| |
|
How if you had two (or more) family photos, where some people had eyes closed,
were speaking, pulling faces, or just looking away. You could pick and choose
each 'head' from different images and merge the multiple images to form a
montage, so as to get a photo where everyone is looking at the camera, and
have their eyes open.
By swapping the input images, or just negating the mask, you can remove me
completely from the image, so get an unrestricted view of the static
background.
convert anthony_2.jpg anthony_1.jpg anthony_mask.jpg \
-composite anthony_removed.jpg
| |
|
This can be handy when taking photos of a public monument, where you can't
afford the expense of crowd control. Just take lots and lots of photos from a
tripod, and hopefully you can combine them to remove everyone from the scene!
Generating the average image as a guide can be helpful with process,
especially if you generate masks using the second method (see next)...
The other way of generating the mask image is by taking the time to get a
photo of the scene without the subject in it (or generate one like in the last
example). Or in the case of a 'busy' scene using an average of hundreds of
images, so as to turn all the people into a light haze of 'ghosts' that can be
discounted.
With a clean background photo, we we can threshold a difference image to mask
out the parts of the image that changed. You may need to use some further
blurring and threshold to expand that mask appropriately to cover not only the
object within the image, but any shadows or reflections it may cast on the
background scenery. A little trial and error may also be needed to get it
right.
convert anthony_removed.jpg anthony_2.jpg \
-compose difference -composite \
-threshold 5% -blur 0x3 -threshold 20% -blur 0x3 \
anthony_automask.jpg
| |
|
Now lets use this mask to mix my 'ghosts' image with the original image so it
looks like my conscience is 'haunting' me for making such 'impossible'
pictures.
convert anthony_1.jpg anthony_ghosts.jpg anthony_mask.jpg \
-composite anthony_haunted.jpg
| |
|
As a final point, all the above techniques assumes the photos were taken from
a camera that was locked down securely on a stationary tripod. If this was
not that case but just taken from a hand held position, I can guarantee that
the images will not match-up or 'align' properly, no matter how hard you tried
to do it right. In such cases you may require some
Affine or even
Perspective distortion of at least one of
the two images to get the backgrounds to align properly. The more complex the
background, the more exacting the needed re-alignment.
If a flash was used, or the day was cloudy with variable light, you may also
need some brightness adjustments to the photo. The cause is that most cameras
'auto-adjust' the brightness of the images, and a flash, or variable light can
change its handling of the 'auto-level' adjustment for each and every image.
As a final example, here is another image I created from two separate photos,
of my nephew fencing with himself, in front of a climbing wall. As I was
holding the camera and used a flash, I did need to do some affine distortion
adjustments, as well as slight brightness adjustment to get the seamless
result you see.
Jacob vs Jacob
If you were trying to decide if this photo was fake or not, you would look at
the lighting, shadows and reflections. In the above, a close examination of
the floor will show that the right 'Jacob' does not have a proper reflection
on the floor (it was clipped by the photos edge). But you would really need to
study the photo well to notice this!
Now think of the possibilities you can use this 'double exposure' technique
for. For example how about some
Funny
Mirrors. Email me your results!
If you like to get into this further The research paper "
Interactive Digital Photomontage", goes into using "Double Exposures" (or
as it terms it "photo montage"), but making use of user selections expanded to
define "image segmentation", to select what parts of the image is to come from
where.
One example is if you have a number of photos of a large group of people, in
each photo someone does not 'look good'. You can use this technique to
select which person comes from which image so that you can get a perfect group
photo where everyone is: facing front, with eyes open, and smiling!
Protect Someone's Anonymity
(or hide the naughty bits)
The above technique of using a 3 image composite mask can also be used in
other ways. For example you can 'pixelate' and image, then use a mask to
limit the effect to just the face of a person, so as to "Protect their
Identity".
convert zelda_tn.gif -scale 25% -scale 400% zelda_pixelate.gif
convert zelda_tn.gif -gamma 0 -fill white \
-draw 'circle 65,53 50,40' zelda_face_mask.gif
convert zelda_tn.gif zelda_pixelate.gif zelda_face_mask.gif \
-composite zelda_anonymity.png
|
Of course you can do this all in one go, and even smooth the change from
pixelated to normal. For example..
convert zelda_tn.gif \( +clone -scale 25% -scale 400% \) \
\( +clone -gamma 0 -fill white \
-draw 'circle 65,53 50,40' -blur 10x4 \) \
-composite zelda_anonymity.jpg
| |
|
Of course rather than pixelate the offending part, you can also blur the area
instead. Just replace the two "
-scale
" operators with a single "
-blur
" to fuzz out the details.
Removing text and Logos
Often you have an image with unwanted text or logo on it. If that text or
logo is in a clean area of the image it is usually quite easy to just paint it
out, but with photos that use very rarely the case. More commonly than not, the
text is written somewhere within the image proper.
For example here I create a image with some ugly text overlaid.
convert zelda_tn.gif -gravity Southwest -annotate +8+20 Zelda zelda_text.jpg
| |
|
Now the first step in removing any unwanted material from an image, just as
it was with
Double Exposures and
Protecting Someone's Anonymity is to create a mask of the part of the
image that is unwanted.
This is naturally complex and highly dependant on the image involved, so I
will not go into it here
(future link to section on mask generation),
so I'll just generate a mask for our purposes here.
convert zelda_text.jpg -gamma 0 -fill white -stroke white -strokewidth 2 \
-gravity Southwest -annotate +8+20 Zelda zelda_text_mask.gif
| |
|
The mask will completely overlay the unwanted part, including any and all
anti-aliasing semi-transparent pixels. So it is generally a good idea to
ensure it is at least one pixel larger, so as include these pixels.
You can check its coverage by overlaying the mask on the image.
convert zelda_text.jpg \
\( zelda_text_mask.gif -background white -alpha shape \) \
-flatten zelda_mask_overlay.jpg
| |
|
By adjusting the color of the mask overlay you can remove the text, though
the result is rarely very nice.
What you want is to color the masked area based on the colors surrounding the
mask. And that can be achieved by cutting out the area, making it transparent,
then blurring the image so as to 'fill in' the hole.
convert zelda_text.jpg \( zelda_text_mask.gif -negate \) \
-alpha off -compose CopyOpacity -composite \
-channel RGBA -blur 0x2 +channel -alpha off \
zelda_text_fill.jpg
| |
|
The trick with the above is to blur the colors into transparency, which IM
knows has
no defined color. This results in the hole becoming
semi-transparent, with a color based on the closes
defined colors. At
that point the transparency is just turned off, to leave hole filled.
Now you have the replacement colors, you can do a 3 image masked overlay
just as we've done before.
convert zelda_text.jpg zelda_text_fill.jpg zelda_text_mask.gif \
-composite zelda_text_removed.png
|
And the text has been removed.
Of course you can do the last two steps in the same command, and in fact
as you use the mask to cut a hole in the image, you can use that as a short
cut in the processing.
convert zelda_text.jpg \( zelda_text_mask.gif -negate \) \
-alpha off -compose CopyOpacity -composite \
\( +clone -channel RGBA -blur 0x2 +channel -alpha off \) \
+swap -compose Over -composite \
zelda_text_remove_2.jpg
| |
|
Of course it is not very neat, as the blurring of colors in that area makes it
obvious that something was removed. You can especially see this in the
blurring of the background window frame.
Here is another removal example, this time removing Zelda's cheeky grin, in a
way reminiscent of "The Matrix".
convert zelda_tn.gif \( +clone -gamma 0 -stroke white -strokewidth 4 \
-draw 'stroke-linecap round line 59,60 70,59' -negate \) \
-alpha off -compose CopyOpacity -composite \
\( +clone -channel RGBA -blur 0x2.5 +channel -alpha off \) \
+swap -compose Over -composite \
zelda_lips_removed.jpg
| |
|
There are better ways of 'filling' the blank space, than a simple blurring.
For example filling in color using color morphology 'closures' can produce a
much better result. This is shown by Fred Weinhaus's replay in the IM
Discussion Forum on
Text Removal.
Even better methods involves linking up similar colors on either size of the
mask image so that any continuing lines, details and patterns are not
destroyed, but made to continue across the cleared space. One of the best
algorithms for this is part of
GrayCStation Image Inpainting. A technique I would love to see added to
IM.
If you have any ideas on better 'fill' methods, please let me know.
Add a Texture to an Image
The
Hardlight alpha compositing method
provides a way to give an image a texture pattern.
For example here I add a texture of course fabric to a photo I took of a
pagoda at the Kunming Zoo, in southern China.
convert tile_fabric.gif -colorspace gray -normalize \
-fill gray50 -colorize 70% texture_fabric.gif
composite texture_fabric.gif pagoda_sm.jpg \
-tile -compose Hardlight photo_texture.jpg
|
Note that if you want to actually tile the texture over the image you need to
use the "
composite
" command rather than the more versatile
"
convert
" command, though there are ways to get around that.
Also note that when adding a texture like this, the smaller details in the
original photo tend to be lost by the noise of the overlaid texture.
To use an image pattern as a texture it should be modified so that a perfect
gray color is used for areas that is unchanged in the original image. That is
the average color of the image should be about 50% gray. In the example I
demonstrate one way that you can do this with just about any tileable image,
though this specific method may not always work well.
Such textures can be found all over the web, as various background patterns
for web pages. They may not even look like a texture, be colorful, or even
very bright or very dark. After adjustment however you will find that you can
get some very interesting effects.
In the above the original tile image was not a gray-scale texture, but it
contained the pattern I wanted to produce, so only a quick adjustment was
needed, to generate the desired effect.
As an aside, I also recommend you look at the
Overlay alpha compositing method, which is simply the same as
Hard_Light composition, but with the two
images swapped. In other words, rather than adding texture to an image,
Overlay will add color to a gray-scale object.
Artist Charcoal Sketch of Image
The
Charcoal Sketch Transform, offers
users a very simple way of generating a simplified gray-scale rendering of the
image.
It does not work well for 'busy images' but for simpler images it can produce
a very striking result.
convert holocaust_sm.jpg -charcoal 5 charcoal.gif
|
Children's Color-In Image
In a long discussion about
Generating Coloring-In Pages on the IM Users Forum, the following
cookbook recipe was developed to convert a simple photo into something
children can color in.
Here is the best result we have so far, applied to a photo I took of the
holocaust memorial, Berlin.
convert holocaust_sm.jpg \
-edge 1 -negate -normalize \
-colorspace Gray -blur 0x.5 -contrast-stretch 0x50% \
color-in.gif
# For heavily shaded pictures...
# #-segment 1x1 +dither -colors 2 -edge 1 -negate -normalize \
|
The final operations in the above attempt to smooth out the lines and improve
the overall result.
Of course the above technique is only useful for images with good sharp color
changes, and preferably a higher resolution image than I used above.
For cartoon images that already have black outlines with a light colored
background, the use of
Edge Detection with
the above method will directly produce a 'twinning' effect of the black
outlines. You can see this effect in the twinned lines of tiles on the path
leading into the memorial, in the lower-left corner.
This is an artifact of the way
Edge
Detection works, and you can see more examples of this in that section of
IM Examples.
The solution is to negate images of this type before using "
-edge
" to outline the colored
areas.
convert piglet.gif -background white -flatten \
-colorspace Gray -negate -edge 1 -negate -normalize \
-threshold 50% -despeckle \
-blur 0x.5 -contrast-stretch 0x50% \
color-in_cartoon.gif
|
I also "
-threshold
"
so I can then remove individual dots that "
-edge
" seem to like to generate.
After that I again attempt to smooth out the aliased lines in the image.
Pencil Sketch
Using a
Photoshop (PSP)
tutorial on converting images to
Pencil Sketches,
dognose
from the
IM Users Forum, managed to create the
equivalent ImageMagick commands. Here is his conversion, simplified into a
few IM commands, allowing you to batch process lots of images into a 'artists
pencil sketch' form.
First we need a special "
pencil.gif
" image. This can take a long
time, so for this example I made it a bit smaller, while preserving its
ability to be tiled across larger images. See
Modifying Tile Images for details of the techniques.
This only needs to be done once and can then be re-used. As such you can
generate a much larger one for your own use, so as to avoid any tiling
effects. Ideally make it as large as the images you plan to convert.
convert -size 256x256 xc: +noise Random -virtual-pixel tile \
-motion-blur 0x20+135 -charcoal 1 -resize 50% pencil_tile.gif
| |
|
Now it is only a matter of overlaying and blending this 'pencil' shading image
with a photo. The pencil image is tiled to make a canvas the same size as the
image we are processing. Then it is applied to the image using techniques
found in
Tiled Canvases. This is then merged
into a gray-scaled copy of the original image.
convert pagoda_sm.jpg -colorspace gray \
\( +clone -tile pencil_tile.gif -draw "color 0,0 reset" \
+clone +swap -compose color_dodge -composite \) \
-fx 'u*.2+v*.8' sketch.gif
|
Note that as the "
-blend
"
operator of the "
composite
"
command is not available to the "
convert
" command, I opted to do
the equivalent using the DIY "
-fx
" operator. There are probably better, faster but more
complicated ways of doing this. (suggestions are welcome)
This is not the final version, as the operator misses some edge enhancement
aspects needed for outline some of the more lighter but sharp color changes in
the image. Can you improve the above?
The above algorithm was built into IM as a artistic transform "
-sketch
", though without the
"
-resize
" smoothing for
the generated 'pencil tile'...
convert pagoda_sm.jpg -colorspace gray -sketch 0x20+120 sketch_new.gif
|
Vignette Removal
When taking photos (digital or otherwise, the camera lens generally darkens
the edges and corners of the image. This is called 'vignetting'. In fact this
lens effect is so common, it is often faked on purpose using the "
-vignette
" operator. See the
Vignette Transform.
Martin Herrmann <Martin-Herrmann@gmx.de> wanted to remove camera
vignetting from the photos. Basically he took a photo of a white sheet of
paper in a bright light without using a flash. He then wanted to combine this
with his actual photos to brighten the edges and corners of the image
appropriately.
Basically what we want to do is divide the original photo by the grey-scale
image of the photo of the brightly lit white piece of paper and it will then
brighten the parts of the image by the amount that the 'white paper' photo was
darkened.
This is basically the compose method '
Divide
' which divides the 'source' image by the 'background'
image. For example,
However as the photo of the 'white paper' will probably not be a true white,
and you probably do not want to brighten the image by this 'off-white' color.
To fix this we need to multiply the divisor image by its the center
pixel color.
Here is the final solution provided to Martin, which used the very slow
FX DIY Operator. The white photo was also grey
scaled to remove any color distortion as well, note that I changed the
ordering which will also preserve any 'meta-data' that was in the original (as
it is the 'destination' image in this case.
convert vegas_orig.jpg \( nikon18-70dx_18mm_f3.5.jpg -colorspace Gray \) \
-fx '(u/v)*v.p{w/2,h/2}' vegas_fixed_fx.jpg
| |
|
If you look carefully at the enlarged photos, particularly the top-left and
top-right 'sky' corners, you can see the vignetting effects, and the
correction that was made.
It is not a perfect solution, and could use a little more tweaking. For
example rather than using a scaling pixel, we could pre-process the 'white
page' image, and also adjust it for a better vignette removal result.
Note that using JPEG is not recommended for any sort of photographic work, as
the format can introduce some artifacts and inconsistencies in the results.
The format is only good for storage and display of the final results.