2-2 「ガンマ補正」
モチベーション
画像全体を明るくしたり暗くしたりできます。
バイアス値を加えて作成する直線的な画像変換よりも、より自然な出力が得られます。
PCで表示される明るさはディスプレイによってさまざまであり、見え方の差を補正するためにγ補正が用いられることがあります。
やり方
PILライブラリを使用し画像を読み込みます。
各画素値にガンマ変換を適用し計算結果を新たな画素値とします。
プログラム
#!/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')) print(im.shape, im.dtype) # 画像の表示 plt.title("before") plt.imshow(im) plt.show() # 画像サイズを取得 height= im.shape[0] width = im.shape[1] # γ値 g = 2.2 ##全画素を走査し、γ補正を適用する for x in range(height): for y in range(width): im[x,y] = 255.0 * pow( im[x,y]/255.0, 1.0/g ) # 画像の表示 plt.title("after") plt.imshow(im) plt.show() #保存 Image.fromarray(im).save('output.bmp')
実行結果
解説
折れ線型トーンカーブでは、トーンカーブの切り替わり前後で画素値が急激に変換されてしまいますが、ガンマ補正は曲線のトーンカーブで 次のように表現されます。
ガンマ値を変化させたときのグラフを以下に示します。 γ > 1の時は上に凸、γ < 1 のときは下に凸のトーンカーブとなります。
ガンマ補正のトーンカーブ
#!/usr/bin/python # -*- coding: utf-8 -*- # ガンマ補正のトーンカーブ # # 参考 # ガンマ関数 # ディジタル画像処理(CG-ARTS協会)P85 # 折れ線型トーンカーブでは、トーンカーブの切り替わり前後で画素値が急激に変換されてしまう # ガンマ補正は曲線のトーンカーブで y = 255 * (x/255)^(1/γ) と表現される。 # γ > 1の時は上に凸、γ < 1 のときは下に凸のトーンカーブとなる。 # numpy.empty関数 # https://deepage.net/features/numpy-empty.html # # np.empty 値の初期化を行うことなくNumPy配列を生成する # 第一引数に配列数、第二引数にはデータ型を指定 # 実行速度が早く値を初期化する必要がないときはnp.emptyを使う # numpy.clip関数 # https://note.nkmk.me/python-numpy-clip/ # # np.clip 配列要素の値を任意の最小値・最大値にクリッピングする # 第一引数にNumpy配列、第二引数に最小値、第三引数には最大値を指定する。 import numpy as np import matplotlib.pyplot as plt p = np.empty(256, np.uint8) for gamma in np.array([0.33, 0.5, 0.66, 1.0, 1.5, 2.0, 3.0]): for i in range(256): p[i] = np.clip(pow(i / 255.0, 1 / gamma) * 255.0, 0, 255) if (gamma >= 1) : plt.plot(p, label=str(gamma)) else: plt.plot(p, label=str(gamma), linestyle="dashed") plt.legend() plt.xlabel("INPUT") plt.ylabel("OUTPUT") plt.show()