カテゴリー別アーカイブ: matplotlib

(99) OpenCV #4 : ガンマ補正で画像を見やすく調整

(99) OpenCV #4 : ガンマ補正で画像を見やすく調整

1. やりたいこと

Pythonで OpenCVの第 4回目、今回は OpenCVの Look up table を使って画像のガンマ補正(gamma correction)をやってみる。

2. ガンマ補正とは

ガンマ補正(gamma correction)とは、以下の式で入力値に対する出力値を得ること。
これにより画像の輝度を所望の状態に調整すること。

まずは、入力値(I)と出力値(O)の関係をグラフ上で見てみる。
折角 Pythonを使っているので matplotlib でグラフを表示してみる。

import numpy as np
import matplotlib.pyplot as plt

ary_gamma = np.array([0.1, 0.2, 0.4, 0.67, 1, 1.5, 2.5, 5, 10, 25])

for var_gamma in ary_gamma:
    var_px = np.empty(256, np.uint8)
    for i in range(256):
        var_px[i] = np.clip(pow(i / 255.0, var_gamma) * 255.0, 0, 255)
    plt.plot(var_px, label=str(var_gamma))

plt.legend()
plt.xlabel("INPUT")
plt.ylabel("OUTPUT")
plt.show()

実行すると以下のグラフが表示される。
線ごとに色を指定せずとも自動的に色分けしてくれるので便利だ。

γ = 1 であれば入力値=出力値のリニアな関係になるので画像は何も変わらない。
γ < 1 であれば暗い部分の輝度変化が強調される。
γ > 1 であれば明るい部分の輝度変化が強調される。

3. やってみる

(1) 必要最小限の機能

まずは一切の装飾や利便性などを考慮せず、愚直にガンマ補正機能だけを実行してみる。

import cv2
import numpy as np

# ガンマ値を決める。
gamma = 0.8

# 処理対象の画像をロード
imgS = cv2.imread("img001.png")

# ガンマ値を使って Look up tableを作成
lookUpTable = np.empty((1,256), np.uint8)
for i in range(256):
    lookUpTable[0,i] = np.clip(pow(i / 255.0, gamma) * 255.0, 0, 255)

# Look up tableを使って画像の輝度値を変更
imgA = cv2.LUT(imgS, lookUpTable)

# 表示実行
cv2.namedWindow('image', cv2.WINDOW_AUTOSIZE)
cv2.imshow('image', imgA)
cv2.waitKey()

ガンマ値=0.8で実行したところ、暗い部分が少しだけ見やすくなったか?

(2) 少しだけ機能拡張

上記(1)のシンプル実装プログラムに対して、以下の二つの機能を追加実装した。
追加機能#1 : コマンドラインから、画像ファイルを指定できるようにした。
追加機能#2 : コマンドラインから、ガンマ値を指定できるようにした。

###########################################################
# ガンマ補正プログラム
import argparse
import cv2
import numpy as np

def main():
    # コマンドライン引数「γ値」を取得
    parser = argparse.ArgumentParser()
    parser.add_argument('-g','--gamma', required=True)
    parser.add_argument('-f','--filepath',  required=True)
    args = parser.parse_args()
    # γ補正実行
    exec_gamma_correction( args.filepath, float(args.gamma) )

def exec_gamma_correction( filepath, gamma ):
    # 処理対象の画像をロード
    imgS = cv2.imread(filepath)

    # γ値を使って Look up tableを作成
    lookUpTable = np.empty((1,256), np.uint8)
    for i in range(256):
        lookUpTable[0,i] = np.clip(pow(i / 255.0, gamma) * 255.0, 0, 255)

    # Look up tableを使って画像の輝度値を変更
    imgA = cv2.LUT(imgS, lookUpTable)

    # PILで表示用画像を作成
    from PIL import Image, ImageDraw, ImageFont
    imgA_RGB = cv2.cvtColor(imgA, cv2.COLOR_BGR2RGB)
    imgP = Image.fromarray(imgA_RGB)

    # 画像の左上にγ値の表示を埋め込む
    obj_draw = ImageDraw.Draw(imgP)
    obj_font = ImageFont.truetype("/usr/share/fonts/ipa/ipagp.ttf", 40)
    obj_draw.text((10, 10), "γ = %.1f" % gamma, fill=(255, 255, 255), font=obj_font)

    # 表示実行
    imgP.show()

if __name__=="__main__": main()

Shellから以下の二つのコマンドラインオプションを指定して実行する。
-f : 対象画像ファイルのパス
-g : ガンマ値

python3 gamma_correct.py -f img001.png -g 0.8

以下、いろいろなガンマ値で実行してみた。

でも…
iPhoneの自動補正機能が素晴らしいのか?
ガンマ値=1 が一番きれいに見えるなぁ







4. 参考

ありがとうございます。 m(_ _)m
https://docs.opencv.org/master/d3/dc1/tutorial_basic_linear_transform.html


(62) 直交座標 to 極座標変換

(62) 直交座標 to 極座標変換
import numpy as np
import matplotlib.pyplot as plt

# ランダムに点をプロット
x = np.random.randint(1,5,5)
y = np.random.randint(1,5,5)

# matplotlibの描画オブジェクト#1を作成
ax1 = plt.subplot(1,2,1)
# 散布図を作成
ax1.scatter(x,y)
ax1.axis([0,10,0,10])
ax1.grid(True)

# 極座標に変換
radii = np.sqrt(x**2 + y**2)
theta = np.arctan2(y,x)

# matplotlibの描画オブジェクト#2を作成
ax2 = plt.subplot(1,2,2,polar=True)
# 散布図を作成
ax2.scatter(theta,radii)
ax2.set_rmax(10)
ax2.grid(True)

# 表示を実行
plt.show()

20140905_01


(47) matplotlibでグラフ表示できない [解決]

(47) matplotlibでグラフ表示できない [解決]

別マシンへのインストール時に再度はまりそうなのでメモしておく。

(1) 現象

matplotlibを使ってグラフを表示しようとしたが表示されない。エラーも出ず…

>>> import matplotlib.pyplot as plt
>>> plt.plot([1,2,3,4])
>>> plt.show()

うんともすんとも…

(2) 原因

matplotlibの backend指定がデフォルトで画面表示できないもの backend : agg になっていた。
これを画面表示可能な backendに変える必要がある。

(3) 対策

二重三重にはまったので整理して結論だけメモしておく。

(1) Tcl/Tk関連パッケージをインストールする。

# yum install tk.x86_64
# yum install tk-devel.x86_64
# yum install tkinter.x86_64

(2) matplotlibをインストールしなおす。

$ python setup.py build
$ sudo python setup.py install

この時点でまだ表示できないようなら以下を確認する。

(3) matplotlibの設定ファイルの場所を知る。

$ python
>>> import matplotlib
>>> matplotlib.matplotlib_fname()
'/usr/local/lib/python2.7/site-packages/matplotlib-1.3.1-py2.7-linux-x86_64.egg/matplotlib/mpl-data/matplotlibrc'

(4) matplotlibの設定ファイルでbackend指定を書き換える。

# vi /mpl-data/matplotlibrc
#### CONFIGURATION BEGINS HERE
# the default backend; one of GTK GTKAgg GTKCairo GTK3Agg GTK3Cairo
# CocoaAgg MacOSX Qt4Agg TkAgg WX WXAgg Agg Cairo GDK PS PDF SVG
# Template
# You can also deploy your own backend outside of matplotlib by
# referring to the module name (which must be in the PYTHONPATH) as
# 'module://my_backend'
#backend      : agg
backend      : tkagg

(1),(2)を先にやっていれば、(3),(4)は必要なかったかもしれない。
今度別マシンにインストールするときにはこの手順でやってみよう。

(4) 確認結果

できた!

>>> import matplotlib.pyplot as plt
>>> plt.plot([1,2,3,4])
>>> plt.show()

20140829_01

(x) 面倒な場合はAnaconda

Anaconda(Python distributionの一つ)をインストールすれば、数値計算系の Pythonパッケージをごそっと入れてくれる。もちろん matplotlibも最初から表示できるように設定されている。
参考1: Python Distributions
参考2: Anaconda

Anacondaは以下の手順で非rootでもインストールできる。

wget https://repo.anaconda.com/archive/Anaconda3-5.2.0-Linux-x86_64.sh
chmod +x Anaconda3-5.2.0-Linux-x86_64.sh
./Anaconda3-5.2.0-Linux-x86_64.sh

実行時はパスを通す。

export PATH=~/anaconda3/bin/:$PATH
python3

Anacondaのアップデートは以下を実行する。
※最新の Anaconda3-5.2.0-Linux-x86_64.sh をダウンロードする必要はない。

$ conda update conda

(42) matplotlib 1.3.1をインストール

(42) matplotlib 1.3.1をインストール

(1) インストーラーをダウンロードする。
http://matplotlib.org/

(2)解凍する。

$ tar zxf matplotlib-1.3.1.tar.gz
$ cd matplotlib-1.3.1

(3) インストールを実行する。

$ python setup.py build
$ sudo python setup.py install

追記: 2014/08/29
matplotlibでグラフが描画できない問題への対処方法を下記記事に記しました。
(47) matplotlibでグラフ表示できない[解決]