ImageMorph Module ################# :doc: https://pillow.readthedocs.io/en/latest/reference/ImageMorph.html A `binary morphology `_ add-on for the Python Imaging Library. .. |ImageMorph_src1| image:: _static/exams/data/binary_shapes_01.jpg .. |ImageMorph_src2| image:: _static/exams/data/binary_noisy_letters_01.jpg .. |ImageMorph_src3| image:: _static/exams/data/binary_noisy_letters_02.jpg with known patterns ******************* .. |ImageMorph01.res01| image:: _static/exams/result/ImageMorph01_binary_noisy_letters_01_corner.jpg .. |ImageMorph01.res02| image:: _static/exams/result/ImageMorph01_binary_noisy_letters_01_dilation4.jpg .. |ImageMorph01.res03| image:: _static/exams/result/ImageMorph01_binary_noisy_letters_01_dilation8.jpg .. |ImageMorph01.res04| image:: _static/exams/result/ImageMorph01_binary_noisy_letters_01_edge.jpg .. |ImageMorph01.res05| image:: _static/exams/result/ImageMorph01_binary_noisy_letters_01_erosion4.jpg .. |ImageMorph01.res06| image:: _static/exams/result/ImageMorph01_binary_noisy_letters_01_erosion8.jpg .. |ImageMorph01.res07| image:: _static/exams/result/ImageMorph01_binary_noisy_letters_02_corner.jpg .. |ImageMorph01.res08| image:: _static/exams/result/ImageMorph01_binary_noisy_letters_02_dilation4.jpg .. |ImageMorph01.res09| image:: _static/exams/result/ImageMorph01_binary_noisy_letters_02_dilation8.jpg .. |ImageMorph01.res10| image:: _static/exams/result/ImageMorph01_binary_noisy_letters_02_edge.jpg .. |ImageMorph01.res11| image:: _static/exams/result/ImageMorph01_binary_noisy_letters_02_erosion4.jpg .. |ImageMorph01.res12| image:: _static/exams/result/ImageMorph01_binary_noisy_letters_02_erosion8.jpg .. |ImageMorph01.res13| image:: _static/exams/result/ImageMorph01_binary_shapes_01_corner.jpg .. |ImageMorph01.res14| image:: _static/exams/result/ImageMorph01_binary_shapes_01_dilation4.jpg .. |ImageMorph01.res15| image:: _static/exams/result/ImageMorph01_binary_shapes_01_dilation8.jpg .. |ImageMorph01.res16| image:: _static/exams/result/ImageMorph01_binary_shapes_01_edge.jpg .. |ImageMorph01.res17| image:: _static/exams/result/ImageMorph01_binary_shapes_01_erosion4.jpg .. |ImageMorph01.res18| image:: _static/exams/result/ImageMorph01_binary_shapes_01_erosion8.jpg .. literalinclude:: _static/exams/ImageMorph_01.py .. list-table:: * - |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 :code:`op_name="erosion4"` .. code-block:: pycon >>> 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. >>> # '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 `_. .. code-block:: pycon >>> 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. >>> # ... 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