画像処理はじめました。

AI/AR/VRという近未来的な言葉に惹かれ、その技術分野に参戦するために立ち上げたブログです。日々の格闘結果を記録に残してゆこうと思います。

1-5 「ポスタリゼーション」

モチベーション

画像が表現できる色数を減らすことで実写を手書き風の画像へ変換できます。

やり方

PILライブラリを使用し、グレースケールで画像を読み込みます。読み込んだ画像は、uint8型なので 0~255 の値をとります。これら各画素値に対して、階調を減らす作業がポスタリゼーションです。

例えば、0~255値の256階調で表現されている値を、5階調へ落とす作業を考えてみます。
その場合、256段階で 0~51の値をとっていた画素を、5段階表示では、全て25に置き換えたり、同様に、51~102の範囲の値を76へ置き換えたりします。

256段階表示 5段階表示 区間の中央値
0~51 25 25 = (0+51)/2
51~102 76 76 = (51+102)/2
102~153 127 127 = (102+153)/2
153~204 178 178 = (153+204)/2
204~255 229 229 = (204+255)/2

プログラム

グレー画像をPILで取得しNumpy配列化します。
256段階から5段階の画素値へ置き換える場合、区間の値を中央値に置き換えることで実現しています。

#!/usr/bin/python
# -*- coding: utf-8 -*-

# ポスタリゼーション

from PIL import Image 
import numpy as np
from matplotlib import pylab as plt

# 画像の読み込み
im = np.array(Image.open('input.bmp').convert('L'))
print(im.shape, im.dtype)
# ((540L, 960L), dtype('uint8'))


# 画像の表示
plt.title("before")
plt.gray()           # 表示カラーマップをグレースケールとする
plt.imshow(im)
plt.show()


# 画像サイズを取得
height= im.shape[0]
width = im.shape[1]

#量子化レベルを (1/q) とする
#q=5の場合、256階調を5階調へ変換することになる
q=5

#全画素を走査し、量子化レベルを変換する。
for x in range(height):
    for y in range(width):
        for l in range(q):
            t1 = l*((255)/q);
            t2 = (l+1)*((255)/q);

            # ポスタリゼーション処理            
            if t1 <= im[x,y] and im[x,y] < t2:
                im[x,y] = (t1+t2)/2
                break
    

print(im.shape, im.dtype)
# ((540L, 960L), dtype('uint8'))

# 画像の表示
plt.title("after")
plt.imshow(im)
plt.show()

#保存
Image.fromarray(im).save('output.bmp')

実行結果

f:id:genetaka1810:20191109152543p:plain

補足

f:id:genetaka1810:20191109152808p:plain