• Home
  • About
    • MR_U (beta) photo

      MR_U (beta)

      A personal website (beta)

    • Instagram
    • Medium
    • Github
  • Posts
  • Documents
  • Projects
  • Resume

PIL image preprocess tricks using Python

Created date: 2020 Jan 13, Mon

Reading time ~3 minutes

import numpy as np 
from PIL import Image
from PIL import ImageFilter
from PIL import ImageEnhance

Preprocess images using PIL

  • Open
  • Filter
  • Contrast Change
  • Grey scale
  • Tricks to denoise
  • Binarize
  • Crop

We can use PIL package to preprocess images in order to do some other stuff(?). For example, we have the following image and we want to extract clear character from the images.

# Open images 
img = Image.open('./code.png')
img

png

# Filter
# There are many filters, like averaging and maximgum filter. 
# Each one is used for different purpose.
# Here, we use a median fileter to keep the edge and the details of the imgage
img = img.filter(ImageFilter.MedianFilter(5)) 
img

png

# Contrast Change
# Change paramters 'factor' to change the contrast
# We can increase the contrast to highlight characters in compare to other noise 
img = ImageEnhance.Contrast(img).enhance(1.3)#enhance()
img

png

# Scale change
# We do not care abhttps://mru4913.github.io/Night/posts/img/20200113/out the color 
# change it to grey scale 
img = img.convert('L')
img

png

# However as you can seewe still have some unnecessary 
# lines in the background 
# we need to find a way to remove those lines 
# this approach has to be carefully used b
def remove_pixel(img, vrange=(150,220)):
    pixdata = img.load()
    w, h = img.size
    for j in range(h):
        for i in range(w):
            if pixdata[i,j] > vrange[0] and  pixdata[i,j] < vrange[1]:
                pixdata[i,j] = 255

    return img
img = remove_pixel(img)
img

png

This is another way to denoise. For each pixel, we look its surrounding pixels. If it has more than 2 surrounding pixels belong to background, we label as noise. However, it does not work well in this case.

def denoise(im):
    pixdata = im.load()
    w, h = im.size
    for j in range(1,h-1):
        for i in range(1,w-1):
            count=0
            if pixdata[i,j-1] > 245:
                count = count+1
            if pixdata[i,j+1] > 245:
                count = count+1
            if pixdata[i+1,j] > 245:
                count = count+1
            if pixdata[i-1,j] > 245:
                count = count+1
            if count > 2:
                pixdata[i,j] = 255
    return im
# Binarize
# Now, we can make the characters clearer to see by binarizing.
def binarizing(img, threshold):
    pixdata = img.load()
    w, h = img.size
    for j in range(h):
        for i in range(w):
            if pixdata[i,j] < threshold:
                pixdata[i,j] = 0
            else:
                pixdata[i,j] = 255
    return img
img = binarizing(img, 200)
img

png

# Crop
# Then we may need to crop imgages
n = 4
w, h = img.size
imgg_w = w/n
for i in range(n):
    img.crop((0 + imgg_w * i, 0, imgg_w * (i+1), h)).show()
# Numpy to PIL image 
Image.fromarray(np.random.randint(0,255,(30,30)).astype('uint8'))

png

# PIl image to array
np.array(img)
array([[255, 255, 255, ..., 255, 255, 255],
        [255, 255, 255, ..., 255, 255, 255],
        [255, 255, 255, ..., 255, 255, 255],
        ...,
        [255, 255, 255, ..., 255, 255, 255],
        [255, 255, 255, ..., 255, 255, 255],
        [255, 255, 255, ..., 255, 255, 255]], dtype=uint8)


EN Python CV