Login

Unsharp Mask with PIL and PythonMagick

Author:
VidJa
Posted:
December 28, 2008
Language:
Python
Version:
1.0
Score:
1 (after 1 ratings)

A Magick PIL

I used to do my image conversions with ImageMagick and system calls back in my PHP days. With Django PIL is the obvious choice for most image stuff, but frustrated by the lack of a proper unsharp mask function for PIL I found some code in the bits and pieces of documentation for PythonMagick. (yes I know, Kevin Cabazon wrote PIL_usm, but I could not get it to work, probably due to my inexperience. Anyway, this code makes it easy to convert back and forth from PIL to PythonMagick (maybe not such a good idea on a memory tight high loaded production server, but no problem on my private server (Pentium-M @ 1.8 Ghz with 1 GB Mem.)

usage: usm takes a PIL image object. Radius and sigma is in pixels, amount 1 compares to 100% in photoshop, threshold 0.004 ~ (1/256) compares to 1 in photoshop: I'm using r=1,s=0.5,a=0.8,t=0.016 for roughly 800x600 images created from 3000x2000 (6MP) images. Experiment for your own preferences.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# we need PythonMagick for its unsharp mask functions
#

from PIL import Image
from PythonMagick import Image as PMImage #distinguish between PIL and PythonMagick 'Image' object
from PythonMagick import Blob 

#Convert Magick image to PIL (Python Imageing Library) image
#taken from ftp://ftp.imagemagick.net/pub/ImageMagick/python/README.txt (which contains an error:
#Image.data does not exist
#see Magick++ documentation for the PythonMagick functions

def convertMGtoPIL(magickimage):
    'works with grayscale and color'
    img = PMImage(magickimage)  # make copy
    img.depth = 8        #  this takes 0.04 sec. for 640x480 image
    img.magick = "RGB"
    w, h = img.columns(), img.rows()
    blb=Blob()
    img.write(blb)
    data = blb.data
    
    # convert string array to an RGB Pil image
    pilimage = Image.fromstring('RGB', (w, h), data)
    return pilimage

#Convert PIL image to Magick image

def convertPILtoMG(pilimage):
    'returns RGB image'
    if pilimage == None:
        return None
    if pilimage.mode == 'L':
        pilimage = pilimage.convert("RGB")
    size = "%sx%s" % (pilimage.size[0], pilimage.size[1])
    data = pilimage.tostring('raw','RGB')
    mdata = Blob(data)
    img = PMImage(mdata, size, 8, 'RGB')
    return img

#unsharp mask function, see ImageMagick docs for explanation of radius, sigma, amount and threshold
def usm(pilimage,radius,sigma,amount,threshold):
	img=convertPILtoMG(pilimage)
	img.unsharpmask(radius,sigma,amount,threshold)
	pilimage=convertMGtoPIL(img)
	return pilimage

More like this

  1. Template tag - list punctuation for a list of items by shapiromatron 11 months, 2 weeks ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 11 months, 3 weeks ago
  3. Serializer factory with Django Rest Framework by julio 1 year, 6 months ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 7 months ago
  5. Help text hyperlinks by sa2812 1 year, 8 months ago

Comments

dc (on December 29, 2008):

Why break a butterfly on the wheel when you can write own PIL filter or use builtin ImageFilter.SHARPEN?

#

Please login first before commenting.