ImageMagick v6 Examples --
Digital Photo Handling

Index
ImageMagick Examples Preface and Index
Digital Camera Meta-Data, the EXIF Profile
Digital Photo Orientation
Color Improvments
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 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 enhancment of digital photos.


Digital Camera Meta-Data, the EXIF Profile

When a digitial 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 | column -c 110
[IM Text]

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 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 posibly 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 and 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 usally 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 purposally left the EXIF data intact. 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 modifing 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 a "-format" percent escape...

  identify -format '%[exif:orientation]' pagoda_sm.jpg
[IM Text]

IM provides a special "-orient" operator (use "-list orientation" to see posible values).

  convert pagoda_sm.jpg -orient bottom-right \
                 -format '%[exif:orientation]'   info:
[IM Text]

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 modifing your image, I suggest you use the JHead program. For example here I correct a photos orientation, and delete the builtin preview thumbnail all the digital photos in a directory.

  jhead -autorot  *.jpg

The JHead program will also let you adjust the photos date (if your camera time was set wrong, or you have traveled 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 recomend 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 articals 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) jsut 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 simular 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 recomended that you first look at Color Modifications, for a 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 discusion of what these operators do).

The above input is curtisy of "Tong" form the IM Mailing List.

Brightening Under-exposed Photos Contrib 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
[IM Output] ==> [IM Output]

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
[IM Output] ==> [IM Output]

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 Contrib 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 noisey 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 deatils.

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


Special Photo Processing

Under Construction

Cross-Fading

First determine the overlap needed.  For panoramic crossfades this is
estremily difficult (suggestions). But for dissimilar images this is just a
matter of preference.

You then need to add an appropriate fading transparency to one edge of the
image, by designing the appropriate alpha channel, adding it to one image, and
overlaying that image over the other, with the appropraite offset.

The best way to generate an alpha channel is generate a gradient near the edge,
say the right edge of a 120x80 pixel image, with a 40 pixel overlap.  You will
need to adjust numbers to suit your situation.

Linear fadeoff

 convert gradient:'[80x40]' -rotate 90   xc:black'[80x80]' \
         +swap +append  fade_linear.png

This is not very good fade, but can be improved with a -blur to smooth
out the sharp change into the linear gradient.  Of course the gradient
will ome slightly steeper.

 convert gradient:'[80x40]' -rotate 90 -blur 0x10 -normalize \
         xc:black'[80x80]' +swap +append    fade_linear_blurred.png

Or you can use a -sigmodial-contrast on a larger gradient to make it a very
nice smooth curve. Note that this operator is designed so that black and white,
will remain remain, black and white, in the final result.

 convert gradient:'[80x40]' -rotate 90 -sigmoidal-contrast 4x50% \
         xc:black'[80x80]' +swap +append    fade_sigmoidal.png

Now add this 'matte channel' to our image, and overlay them.


Cutout objects for use in other images...

The problem with this is at it is very hard to automate as each picuture will
probably have a different object.  Better to do this with a interactive
graphics program, such as  "Gimp" or "PhotoShop".


Adding 'Speech Ballons' to images...

Photo Conversion Cookbook

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
[IM Output] ==> [IM Output] ==> [IM Output]

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 overlayed 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 tilable 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 greyscale 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 examply 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 greyscale object.

Artist Charcoal Sketch of Image

The Charcoal Sketch Transform, offers users a very simple way of generating a simplified greyscale 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
[IM Output] ==> [IM Output]

Childrens 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 \
[IM Output] ==> [IM Output]

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 a black outlines, with a light colored background, using Edge Detection the above method directly will 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
[IM Output] ==> [IM Output]

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 equivelent 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
[IM Output]

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, before being 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
[IM Output] ==> [IM Output]

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 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
[IM Output] ==> [IM Output]

Vignettation Removal

When taking photos (digital or otherwise, the camera lens generally darkens the edges and corners of the image. This is called 'vignettation'. 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 vignettation 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.

This was perfectly suited to the "-fx" operator. Basically we 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.

If the photo was the first image ('u'), and the 'white paper' photo was the second ('v') then the image operation "-fx 'u/v'" would do the job.

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' factor, some extra scaling is needed. For this we multiply the result by the center pixel of the 'white page' photo.

Here is the final solution provided to Martin. The white photo is also grey scaled to ensure no color distortion is added.

    convert vegas_orig.jpg \( nikon18-70dx_18mm_f3.5.jpg -colorspace Gray \) \
            -fx '(u/v)*v.p{w/2,h/2}'   vegas_fixed.jpg
[photo]  + [photo] ==> [photo]
(click to see larger photo image)

If you look carefully at the enlarged photos, particularly the top-left and top-right 'sky' corners, you can see the vignettation 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 vignettation 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.

Of course if you like to add vignettation to an image, this is a standard IM image transformation operator "-vignette".


Created: 21 July 2006
Updated: 4 October 2006
Author: Anthony Thyssen, <A.Thyssen@griffith.edu.au>
Examples Generated with: [version image]
URL: http://www.imagemagick.org/Usage/photos/