ImageMorph Module

doc:http://pillow.readthedocs.io/en/4.1.x/reference/ImageMorph.html

A binary morphology add-on for the Python Imaging Library.

with known patterns

import os
from PIL import Image, ImageMorph
from PIL.ImageMorph import LutBuilder, MorphOp

for bn in (
    "binary_shapes_01",
    "binary_noisy_letters_01",
    "binary_noisy_letters_02",
    ):

    img = Image.open(os.path.join("data", bn + ".jpg"))
    img.load()  # MorphOp.apply expects image are loaded.

    for op_name in (
        'corner',
        'dilation4', 'dilation8',
        'erosion4', 'erosion8',
        'edge',
        ):
        lb = LutBuilder(op_name=op_name)
        mop = MorphOp(lb.build_lut())
        _, dimg = mop.apply(img)
        dimg.save(
            os.path.join(
                "result",
                "ImageMorph01_" + bn + "_" + op_name + ".jpg"))
ImageMorph_src1 src ImageMorph_src2 src ImageMorph_src3 src
ImageMorph01.res13 corner ImageMorph01.res01 corner ImageMorph01.res07 corner
ImageMorph01.res14 dilation4 ImageMorph01.res02 dilation4 ImageMorph01.res08 dilation4
ImageMorph01.res15 dilation8 ImageMorph01.res03 dilation8 ImageMorph01.res09 dilation8
ImageMorph01.res16 edge ImageMorph01.res04 edge ImageMorph01.res10 edge
ImageMorph01.res17 erosion4 ImageMorph01.res05 erosion4 ImageMorph01.res11 erosion4
ImageMorph01.res18 erosion8 ImageMorph01.res06 erosion8 ImageMorph01.res12 erosion8

with custom structuring element

Example 1: identical to op_name="erosion4"

>>> import numpy as np
>>> from PIL import Image, ImageMorph
>>> from PIL.ImageMorph import LutBuilder, MorphOp
>>> img = Image.open("data/binary_shapes_01.jpg")  # mode="L"
>>> img.load()  # MorphOp.apply expects image are loaded.
<PixelAccess object at 0x0000000002B1DB90>
>>> # 'erosion4': [
... #     '4:(... .1. .0. )->0'
... # ]
... lb1 = LutBuilder(op_name='erosion4')
>>> _, dimg1 = MorphOp(lb1.build_lut()).apply(img)
>>> #
... erosion4_identical1 = [
...      '1:(... .1. .0.)->0',  # B -> out pixel off if fit
...      '1:(... .10 ...)->0',  # B.rotate(90) -> out pixel off if fit
...      '1:(.0. .1. ...)->0',  # B.rotate(180) -> out pixel off if fit
...      '1:(... 01. ...)->0'   # B.rotate(270) -> out pixel off if fit
...      ]
>>> lb2 = LutBuilder(patterns=erosion4_identical1)
>>> _, dimg2 = MorphOp(lb2.build_lut()).apply(img)
>>> # identical?
... all(np.array(dimg1.getdata()) == np.array(dimg2.getdata()))
True
>>> #
... erosion4_identical2 = [
...      '1:(... .1. .0.)->0',  # B -> out pixel off if fit
...      'M:(... .10 ...)->0',  # B.rotate(90), B.rotate(270) -> out pixel off if fit
...      '1:(.0. .1. ...)->0',  # B.rotate(180) -> out pixel off if fit
...      ]
>>> lb3 = LutBuilder(patterns=erosion4_identical2)
>>> _, dimg3 = MorphOp(lb3.build_lut()).apply(img)
>>> # identical?
... all(np.array(dimg1.getdata()) == np.array(dimg3.getdata()))
True

Example 2: ‘N’ (Negate)

Warning

This demo doesn’t work with pillow version <= 4.1.1. See issue #2590.

>>> import numpy as np
>>> from PIL import Image, ImageMorph
>>> from PIL.ImageMorph import LutBuilder, MorphOp
>>> img = Image.open("data/binary_shapes_01.jpg")  # mode="L"
>>> img.load()  # MorphOp.apply expects image are loaded.
<PixelAccess object at 0x0000000002B3DC30>
>>> #
... my_se1 = [
...      '''1:(000
...            010
...            000)->1''',
...      ]
>>> lb1 = LutBuilder(patterns=my_se1)
>>> _, dimg1 = MorphOp(lb1.build_lut()).apply(img)
>>> #
... my_se2 = [
...      '''N:(111
...            101
...            111)->0''',  # Negate
...      ]
>>> lb2 = LutBuilder(patterns=my_se2)
>>> _, dimg2 = MorphOp(lb2.build_lut()).apply(img)
>>> # identical?
... all(np.array(dimg1.getdata()) == np.array(dimg2.getdata()))
True