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')
実行結果
補足