Sharpen images with Perl and GIMP
Image Sharpener
How do you sharpen a digital image? A short introduction to the principles and a Perl plugin for GIMP help amateur digital photographers polish their snapshots in a professional way.
If you look at a photograph, you can see at a glance whether or not it is in focus. But what does in focus mean? An image that is in focus has clearly defined transitions from light to dark. A black line with a thickness of just a couple of pixels against a white background is the pinnacle of focus. If the transition between black and white is unsharp – that is, if there is a gradient of dark gray and light gray between the black and white – the line no longer looks crisp. In other words, focus means keeping the light/dark transitions in an image as narrow as possible while at the same time keeping as much contrast as possible.
Photographers can do a number of things to set the stage for creating crisp images. For example, strong, direct sunlight gives contours more contrast than a cloudy sky, which softens up the transitions. Moreover, additional light lets you use a lower ISO setting. Higher ISO values on your camera mean that the sensor produces noisy images that appear grainy and out of focus. Also, it is useful to focus on the main subject of the image: the part of the image the viewer sees first should be sharp, other parts are less sensitive and can be slightly unsharp without the viewer gaining the impression of an out-of-focus image. For example, if the eyes are in focus in a portrait, nobody will worry about the nose being slightly out of focus.
In some cases, accidental focus occurs in the wrong places. For example, most people won't appreciate you capturing the details of wrinkly facial skin in portrait photography. Some fuzziness is preferable in this case, so never take these photographs in direct sunlight. Instead, find a shady place. Soft transitions and less contrast are desirable here, although you might want to sharpen the eyes or mouth in the final shot. If you have used an expensive, digital SLR camera to take RAW images, you will appreciate the benefits of this loss-free storage approach. The difference in sharpness is particularly noticeable when you need to crop the image to focus on a part of it. In contrast, the JPEG format loses fine details and sharpness.
One clever method of finding the crispest image from a series of identical snapshots is to check the file size. Because focused, high-detail transitions are more difficult to compress than unsharp ones, sharper JPG images will typically occupy more memory space. Thus, the largest file in a series is typically also the sharpest.
Retrospective Sharpening
GIMP's sharpening function, Filters | Enhance | Sharpen, is perfect for sharpening parts of an image. Resizing an image for web publishing often involves compromising its focus, giving the image a low-contrast, washed-out look. The slider in GIMP's Sharpen menu has a range of 0 through 100, where values between 20 and 40 typically give you the best results (Figure 1). What this does is to shorten the color and brightness transitions at high contrast points of the image. Higher sharpen values result in excessive noise, or unnatural (digital) looking jumps in brightness.
Sharpening methods all work along the same principle: An algorithm finds the edges and corners of the image and shortens their light-dark transitions, possibly emphasizing them by making the light sides lighter and the dark sides darker. Discovering edges is important as widespread sharpening will give you unnatural artefacts in slow tonal transitions, such as in faces.
If you look closely at Figure 2, you will see a vertical, red line I added to the lower left part of the image. Figure 3 shows you the brightness values for this test line before and after sharpening. The curve progression in the original is green, and the sharpened pixels are red. GIMP's Sharpen function quite obviously emphasized the light-dark transition, instead of a flat progression, and the graph shows a peak at the transition point in these areas.
Unsharp Masks
The Unsharp Mask approach takes this one step further by finding transitions and making their dark sides darker, and their lighter sides lighter. This artificially increases the color or brightness transitions at edges and corners and gives viewers an impression of improved focus; however, the real advantage of this approach is the ability to tweak three different parameter buttons to set the intensity of the effect.
Figure 4 shows the GIMP dialog with configurable values for Amount, Radius, and Threshold. The Amount value specifies the contrast enhancement as a percentage. For example, 0.5 reduces the brightness at an edge on the dark side by 50 percent, while increasing it by 50 percent on the light side. A Radius of one or more extends the influence of the filter to the surrounding pixels. If you set a value of 0, the results will be unnatural (digital), and values of more than 2 can compromise valuable detail because GIMP will then apply standard distributed noise to extend the effect.
The Threshold value specifies the parts of the image to which GIMP should apply the filter. To allow this to happen, GIMP internally creates a unsharp copy of the image and compares it pixel by pixel with the original. If the difference between the pixels is greater than the Threshold value, GIMP triggers the filter and enhances the contrast between the neighboring pixels; otherwise, GIMP just leaves the pixel as is. A higher Threshold value limits the effect of the filter to just a few parts of the image with high contrast fluctuations, whereas a Threshold of 0 will sharpen the whole image – this typically causes more noise and artefacts in gradual transitions, such as sky or skin colors, in the original. Use the Amount value carefully; 1 corresponds to 100 percent overmodulation.
The graph in Figure 5 shows the red pixel line in Figure 2 before and after calling Unsharp Mask with two different parameter sets. The green graph represents the brightness of the original pixels. Using an Amount value of 65 percent causes the orange line with considerable overemphasis of the light-dark contrast at its edges (Figure 7). The red line overdoes the effect by using an Amount value of 150 percent leading to the oversharp image shown in Figure 6.
Different motifs require different settings of Unsharp Mask. Photo expert Scott Kelby recommends editing portraits with Radius 1, Amount 1.5, and Threshold 10 [2]. The high Threshold value applies the filter to those areas that already have peak contrast changes. Silky smooth skin is not affected by this. In contrast to this, Kelby recommends R=3, A=0.65, T=2 for urban structures such as buildings. For all other subjects, the recommend values are R=1, A=0.85, T=4. Of course, these values are simply a starting point for your experiments, especially considering the fact that Kelby is actually referring to Photoshop rather than GIMP, and that perfect focus depends on your personal preferences. The Unsharp Mask function in GIMP's role model, Photoshop, tends to create similar results with the same values, as you can see in Figure 8. Photoshop CS3 also includes revolutionary new tools such as Smart Sharpen (with proprietary algorithms).
Selective Sharpening
If an image comprises sections with different degrees of focus, it doesn't normally make sense to sharpen the whole image, as the relatively high levels of enhancement needed to sharpen the fuzzy parts will lead to artefacts (halos) in parts that are already relatively sharp. GIMP has a selective sharpening tool for this; however, it is difficult to script because the user must specify what to sharpen to what extent before applying the function.
A filtering technique leads to automating the process: If you apply a high-pass to filter parts of the image with contrasting light-dark transitions, the subsequent Unsharp mask can concentrate on these parts of the image while leaving the rest of the image untouched. The GIMP script in the smartsharp Listing implements this do-it-yourself sharpening method. Line 18 creates a menu entry at the bottom of GIMP's Image dialog, which pops up when you right click an image (Figure 9).
The exit main() instruction in Line 25 is required by the GIMP API. The smartsharp function in Line 28 does the real work, starting by acquiring a reference to the active layer of the image currently being edited in Line 34. Sharpening takes place in a copy of the layer, which the $sharp_layer variable holds a reference to. To allow this to happen, the layer_copy() method copies the active layer to a new one, which does not appear in the Layer dialog until image_add_layer() is called. The overlay mode for the new layer is set to OVERLAY_MODE in Line 58.
The plug_in_unsharp_mask function in Line 49 performs an unsharp mask transformation on the layer copy, titled sharp, using parameters of Radius 1, Amount 1.0, and Threshold 0 – that is, it affects the whole image. We are using a high pass filter to define where to apply the Unsharp Mask algorithm rather than relying on GIMP's own function. Line 59 creates the mask as a new, temporary layer, which is labeled mask in Line 63. The $mask_layer variable stores a pointer to it. Following this, the plug_in_neon method, an edge detector with a radius of 10 and an effect enhancement value of 0.1, filters those parts of the image with pronounced local light-dark fluctuations. The plug_in_gauss_irr() method, which is then called, applies Gaussian noise to extend the results of the filter and fuzzes the edges to avoid abrupt application of the mask later on (Figure 10).
Now Lines 75 through 86 simply need to apply the mask layer as the layer mask for the sharp layer to make sure that GIMP only sharpens where the mask contains true values. edit_paste() followed by floating_sel_anchor() does this trick. The mask layer at the top is no longer needed and is thus deleted in Line 89.
To merge the two remaining layers, the masked sharp layer and the original image, image_merge_down pushes the top layer into the bottom one. The result is the modified original layer. It is important for the smartsharp function, which we called via the GIMP menu, to return a reference to the manipulated image object; failure to do this will prompt a storm of protest from GIMP. The final result is the sharp image in Figure 11.
Listing 1
smartsharp
Buy Linux Magazine
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs
Subscribe to our ADMIN Newsletters
Support Our Work
Linux Magazine content is made possible with support from readers like you. Please consider contributing when you’ve found an article to be beneficial.
News
-
Red Hat Enterprise Linux 9.5 Released
Notify your friends, loved ones, and colleagues that the latest version of RHEL is available with plenty of enhancements.
-
Linux Sees Massive Performance Increase from a Single Line of Code
With one line of code, Intel was able to increase the performance of the Linux kernel by 4,000 percent.
-
Fedora KDE Approved as an Official Spin
If you prefer the Plasma desktop environment and the Fedora distribution, you're in luck because there's now an official spin that is listed on the same level as the Fedora Workstation edition.
-
New Steam Client Ups the Ante for Linux
The latest release from Steam has some pretty cool tricks up its sleeve.
-
Gnome OS Transitioning Toward a General-Purpose Distro
If you're looking for the perfectly vanilla take on the Gnome desktop, Gnome OS might be for you.
-
Fedora 41 Released with New Features
If you're a Fedora fan or just looking for a Linux distribution to help you migrate from Windows, Fedora 41 might be just the ticket.
-
AlmaLinux OS Kitten 10 Gives Power Users a Sneak Preview
If you're looking to kick the tires of AlmaLinux's upstream version, the developers have a purrfect solution.
-
Gnome 47.1 Released with a Few Fixes
The latest release of the Gnome desktop is all about fixing a few nagging issues and not about bringing new features into the mix.
-
System76 Unveils an Ampere-Powered Thelio Desktop
If you're looking for a new desktop system for developing autonomous driving and software-defined vehicle solutions. System76 has you covered.
-
VirtualBox 7.1.4 Includes Initial Support for Linux kernel 6.12
The latest version of VirtualBox has arrived and it not only adds initial support for kernel 6.12 but another feature that will make using the virtual machine tool much easier.