よちよちpython

独習 python/Qpython/Pydroid3/termux/Linux

【Pillow】全フィルタ一覧

Pillow公式

ImageFilter Module — Pillow (PIL Fork) 5.1.0 documentation



公式サイトに載っているPillowのフィルターを全て試す。

使用環境

  • Python3.8
  • JupyterNotebook
  • Pillow



元の画像

from PIL import Image

img = Image.open("scohen_jinja.jpg")
img

f:id:chayarokurokuro:20200908055511j:plain



以下、上のスーパーギタリストの画像を使って各種フィルターを掛けて行きます。

filterメソッド一覧




<filter 1>ImageFilter.BLUR


ぼかし

from PIL import ImageFilter

img_blur = img.filter(ImageFilter.BLUR)
img_blur

f:id:chayarokurokuro:20200908055622j:plain

引数がないようなのでボカシ具合は既定値か



<filter 2>ImageFilter.CONTOUR


輪郭

img_contour = img.filter(ImageFilter.CONTOUR)
img_contour

f:id:chayarokurokuro:20200908055725j:plain

これも引数がない。木版画のよう。輪郭(contour)を浮き上がらせる。



<filter 3> ImageFilter.DETAIL


ディテール

img_detail = img.filter(ImageFilter.DETAIL)
img_detail

f:id:chayarokurokuro:20200908055830j:plain

ハッキリした高画質っぽい画像になった。細かい部分を強調させてる?



<filter 4> ImageFilter.EDGE_ENHANCE


エッジ強調

img_edge_enhance = img.filter(ImageFilter.EDGE_ENHANCE)
img_edge_enhance

f:id:chayarokurokuro:20200908055910j:plain

粗い画像になった。画像の輝度が大きく変化している所をエッジという。鮮明にするためにエッジを強調させた処理。



<filter 5> ImageFilter.EDGE_ENHANCE_MORE


よりエッジを強調

img_edge_enhance_more = img.filter(ImageFilter.EDGE_ENHANCE_MORE)
img_edge_enhance_more

f:id:chayarokurokuro:20200908055944j:plain

更に粗い画像になった。



<filter 6> ImageFilter.EMBOSS


エンボス。

img_emboss = img.filter(ImageFilter.EMBOSS)
img_emboss

f:id:chayarokurokuro:20200908060151j:plain

紙に型をプレス機で押し付けて凹凸をつけるエンボス版画という技法がある。その様な仕上がり。



<filter 7> ImageFilter.FIND_EDGES


エッジをみつける。

img_find_edges = img.filter(ImageFilter.FIND_EDGES)
img_find_edges

f:id:chayarokurokuro:20200908060247j:plain

contour(輪郭)の逆っぽい仕上がり。線彫りの版画風。



<filter 8> ImageFilter.SHARPEN


シャープにする

img_sharpen = img.filter(ImageFilter.SHARPEN)
img_sharpen

f:id:chayarokurokuro:20200908060336j:plain

detailと似て高画質っぽい仕上がり。



<filter 9> ImageFilter.SMOOTH


なめらか仕上げ。

img_smooth = img.filter(ImageFilter.SMOOTH)
img_smooth

f:id:chayarokurokuro:20200908060429j:plain

薄くボカシた感じ。



<filter 10> ImageFilter.SMOOTH_MORE


よりなめらか仕上げ。

img_smooth_more = img.filter(ImageFilter.SMOOTH_MORE)
img_smooth_more

f:id:chayarokurokuro:20200908060526j:plain

更にボカシた感じ。



<filter 11> ImageFilter.GaussianBlur(radius=2)


ガウスぼかし。引数に半径を指定

img_gaussian_blur = img.filter(ImageFilter.GaussianBlur(radius=10))
img_gaussian_blur

f:id:chayarokurokuro:20200908060557j:plain

ガウス関数を使ったボカシ処理。効果を強調させるために引数radiusの値を大きくしている。曇りガラス風に。



<filter 12> ImageFilter.BoxBlur(radius)


箱ぼかし。引数に半径を指定

img_box_blur = img.filter(ImageFilter.BoxBlur(radius=10))
img_box_blur

f:id:chayarokurokuro:20200908060729j:plain

引数radiusを大きくするほどボケる。radius=1はあるピクセル周りの1個分のピクセルで囲む箱形の範囲つまり合計9個のピクセルでボカシ処理する。
引数のradius=10でガウスボカシと 同じにしたんですけど、ボケ具合はこちらが薄い。



<filter 13> ImageFilter.UnsharpMask(radius=2, percent=150, threshold=3)


デジタル・アンシャープ・マスキング処理。引数に半径、パーセント、敷居値。

各種引数をそれぞれ適当に変えて処理の効果を確かめてみます。

img_unsharp_mask_1 = img.filter(ImageFilter.UnsharpMask(radius=200, percent=150, threshold=3))
img_unsharp_mask_1

f:id:chayarokurokuro:20200908060929j:plain

img_unsharp_mask_2 = img.filter(ImageFilter.UnsharpMask(radius=20, percent=1500, threshold=3))
img_unsharp_mask_2

f:id:chayarokurokuro:20200908061017j:plain

img_unsharp_mask_3 = img.filter(ImageFilter.UnsharpMask(radius=20, percent=1500, threshold=30))
img_unsharp_mask_3

f:id:chayarokurokuro:20200908061109j:plain

元の画像より明るくなっているのは分かる。



<filter 14> ImageFilter.Kernel(size, kernel, scale=None, offset=0)


畳み込みカーネル作成。引数のsize=(幅,高さ)で(3,3)か(5,5)、kernelの重み、scaleはスケール係数、offsetはスケール係数を指定した場合スケール係数で除算された後結果に追加される。

# 自前のカーネル 
#size=(3,3)で合計9個のリストを適当な数値で埋めた
my_kernel=[1,5,0,
           1,5,-9,
           1,5,-10]

img_kernel = img.filter(ImageFilter.Kernel(size=(3,3), kernel=my_kernel, scale=None, offset=0))
img_kernel

f:id:chayarokurokuro:20200908061211j:plain

引数のsize=(3,3)か(5,5)にしなければならない。(3,3)の場合は3*3=9で、次の引数のkernelには9個の数値を適当に入れられた上の画像になった。
scaleはデフォルトでNoneで、Noneのときはoffsetは無効。
よく分かりませんが、kernelの数値をイジると効果が様々に変わる。効果を自作できる関数か。



<filter 15> ImageFilter.RankFilter(size, rank)


ランクフィルターを作成。指定されたsizeのウィンドウ内のすべてのピクセルを並べ替え、rank番目の値を返します。

img_rank_filter = img.filter(ImageFilter.RankFilter(size=13, rank=7))
img_rank_filter

f:id:chayarokurokuro:20200908061357j:plain

写真を水性ペンで塗ったみたい。



<filter 16> ImageFilter.MedianFilter(size=3)


中央値のフィルター。sizeで指定したサイズのウィンドウのピクセルの中央値を返す。

img_median_filter = img.filter(ImageFilter.MedianFilter(size=21))
img_median_filter

f:id:chayarokurokuro:20200908061438j:plain

引数の数値をあげるごとにボケていく。少し計算時間が掛かる。



<filter 17> ImageFilter.MinFilter(size=3)


最小値のフィルター。指定カーネルsizeの最小値を返す。

img_min_filter = img.filter(ImageFilter.MinFilter(size=15))
img_min_filter

f:id:chayarokurokuro:20200908061527j:plain

幼稚園児に水性ペンで落書きされた写真。



<filter 18> ImageFilter.MaxFilter(size=3)


最小値のフィルター。指定カーネルsizeの最大値を返す。

img_max_filter = img.filter(ImageFilter.MaxFilter(size=15))
img_max_filter

f:id:chayarokurokuro:20200908061615j:plain

幼稚園児に白のペンで落書きされた写真。最大値を返すので明るめ。



<filter 19> ImageFilter.ModeFilter(size=3)


モードフィルター。指定されたサイズのボックスで最も頻度の高いピクセル値を選択します。1回または2回しか発生しないピクセル値は無視されます。ピクセル値が2回以上発生しない場合、元のピクセル値が保持されます。

img_mode_filter = img.filter(ImageFilter.ModeFilter(size=15))
img_mode_filter

f:id:chayarokurokuro:20200908061755j:plain

印象派の油絵風か。引数のsizeを大きくしていくとどんどん雑な油絵に。



以上、Pillowが定義しているフィルターを公式ページの順で全て実行しました。

各種の画像処理技術については詳しく調べておりませんが、数式や色彩学、人間の視覚的感覚を数値化した経験則、処理のアルゴリズムなどふんだんに盛り込まれていて難しい。気が向いたらまたその時にでも。