Pythonでいろいろやってみる

Pythonを使った画像処理や機械学習などの簡単なプログラムを載せています。

ルックアップテーブルで画像の彩度、明度を調整する(画像を明るく鮮やかにする)

画像を明るく鮮やかにします。
画像をBGR(青緑赤)の3チャンネルからなるBGR色空間から色相(Hue)、彩度(Saturation)、明度(Value)からなるHSV色空間に変換し、彩度H・明度Vを補正します。補正にはガンマカーブを用いて彩度・明度を全体的に大きくします。あらかじめガンマカーブを納めたルックアップテーブルを用意しcv2.LUT()メソッドにより各画素にルックアップテーブルを適用、彩度・明度のガンマ補正を行います。
画像処理ライブラリOpenCVでは彩度(Saturation)は[0,255],明度(Value)は[0,255]の範囲を取ります。ガンマ補正により値が小さい程高い倍率で変換することで明るく鮮やかな画像に変換します。元の値が255の場合は変換倍率は1倍で元のままなので、彩度や明度が飽和しておかしな画像になることはありません。

関連記事

ルックアップテーブルによる画像コントラストの補正
画像の彩度、明度を変える
PillowのImageEnhanceで画像の鮮やかさを変える
PillowのImageEnhanceで画像のブライトネス(明るさ)を変える

環境
  • windows10 home
  • Anaconda 3/ jupyter notebook 5.6.0
  • Python 3.7.0
  • OpenCV 4.0.0
準備

画像ファイルはフリー写真素材ぱくたそからダウンロードさせていただき、jupyter notebookファイル(***.ipynb)と同じディレクトリにファイル名'autumun.jpg'で保存しました。
f:id:T_A_T:20201216194915j:plain


①彩度Sをガンマ補正(gamma=2)し写真を鮮やかにします。

コード
import cv2
import numpy as np

img = cv2.imread('autumun.jpg')  # 画像の読み出し
img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)  # BGRからHSVに変換 
h, s, v = cv2.split(img_hsv)  # チャンネルごとに分割

# ルックアップテーブルの生成
gamma = 2
look_up_table = np.zeros((256,1),dtype=np.uint8)
for i in range(256):
    look_up_table[i][0] = (i/255)**(1.0/gamma)*255

s_lut = cv2.LUT(s, look_up_table)  # 彩度(S)に対してルックアップテーブル適用 
img_merge = cv2.merge([h, s_lut, v])  #  H,変換後S,Vをマージ
img_bgr = cv2.cvtColor(img_merge, cv2.COLOR_HSV2BGR)  # HSVからBGRに変換 

cv2.imwrite('autumun_s_gamma2.jpg',img_bgr)  # 画像を保存
実行結果

画像が鮮やかに補正されます。
f:id:T_A_T:20201216195941j:plain

用いたガンマカーブは以下の通りです。
f:id:T_A_T:20201216200103p:plain


②彩度Sをガンマ補正(gamma=3)し写真をより鮮やかにします。

コード
import cv2
import numpy as np

img = cv2.imread('autumun.jpg')  # 画像の読み出し
img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)  # BGRからHSVに変換 
h, s, v = cv2.split(img_hsv)  # チャンネルごとに分割

# ルックアップテーブルの生成
gamma = 3
look_up_table = np.zeros((256,1),dtype=np.uint8)
for i in range(256):
    look_up_table[i][0] = (i/255)**(1.0/gamma)*255

s_lut = cv2.LUT(s, look_up_table)  # 彩度(S)に対してルックアップテーブル適用 
img_merge = cv2.merge([h, s_lut, v])  #  H,変換後S,Vをマージ
img_bgr = cv2.cvtColor(img_merge, cv2.COLOR_HSV2BGR)  # HSVからBGRに変換 

cv2.imwrite('autumun_s_gamma3.jpg',img_bgr)  # 画像を保存
実行結果

画像がさらに鮮やかに補正されます。
f:id:T_A_T:20201216200336j:plain

用いたガンマカーブは以下の通りです。gamma=2のガンマカーブと比べてより彩度が高めに補正されています。
f:id:T_A_T:20201216200358p:plain


③明度Vをガンマ補正(gamma=2)し写真を明るくします。

コード
import cv2
import numpy as np

img = cv2.imread('autumun.jpg')  # 画像の読み出し
img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)  # BGRからHSVに変換 
h, s, v = cv2.split(img_hsv)  # チャンネルごとに分割

# ルックアップテーブルの生成
gamma = 2
look_up_table = np.zeros((256,1),dtype=np.uint8)
for i in range(256):
    look_up_table[i][0] = (i/255)**(1.0/gamma)*255

v_lut = cv2.LUT(v, look_up_table)  # 明度(V)に対してルックアップテーブル適用 
img_merge = cv2.merge([h, s, v_lut])  #  H,S,変換後Vをマージ
img_bgr = cv2.cvtColor(img_merge, cv2.COLOR_HSV2BGR)  # HSVからBGRに変換 

cv2.imwrite('autumun_v_gamma2.jpg',img_bgr)  # 画像を保存
実行結果

画像が明るく補正されます。
f:id:T_A_T:20201216200844j:plain


④明度Vをガンマ補正(gamma=3)し写真をさらに明るくします。

コード
import cv2
import numpy as np

img = cv2.imread('autumun.jpg')  # 画像の読み出し
img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)  # BGRからHSVに変換 
h, s, v = cv2.split(img_hsv)  # チャンネルごとに分割

# ルックアップテーブルの生成
gamma = 3
look_up_table = np.zeros((256,1),dtype=np.uint8)
for i in range(256):
    look_up_table[i][0] = (i/255)**(1.0/gamma)*255

v_lut = cv2.LUT(v, look_up_table)  # 明度(V)に対してルックアップテーブル適用 
img_merge = cv2.merge([h, s, v_lut])  #  H,S,変換後Vをマージ
img_bgr = cv2.cvtColor(img_merge, cv2.COLOR_HSV2BGR)  # HSVからBGRに変換 

cv2.imwrite('autumun_v_gamma3.jpg',img_bgr)  # 画像を保存
実行結果

画像がさらに明るく補正されます。
f:id:T_A_T:20201216200944j:plain


⑤彩度S、明度V両方ともガンマ補正(gamma=2)し写真を明るく鮮やかにします。

コード
import cv2
import numpy as np

img = cv2.imread('autumun.jpg')  # 画像の読み出し
img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)  # BGRからHSVに変換 
h, s, v = cv2.split(img_hsv)  # チャンネルごとに分割

# ルックアップテーブルの生成
gamma = 2
look_up_table = np.zeros((256,1),dtype=np.uint8)
for i in range(256):
    look_up_table[i][0] = (i/255)**(1.0/gamma)*255

s_lut = cv2.LUT(s, look_up_table)  # 明度(V)に対してルックアップテーブル適用     
v_lut = cv2.LUT(v, look_up_table)  # 明度(V)に対してルックアップテーブル適用 
img_merge = cv2.merge([h, s_lut, v_lut])  #  H,S,変換後Vをマージ
img_bgr = cv2.cvtColor(img_merge, cv2.COLOR_HSV2BGR)  # HSVからBGRに変換 

cv2.imwrite('autumun_sv_gamma2.jpg',img_bgr)  # 画像を保存
実行結果

画像が明るく鮮やかになります。
f:id:T_A_T:20201216201221j:plain

以下のサイトを参考にさせていただきました

Pythonの文法メモ >> 【OpenCV】LUTによる画像変換

ブログランキングに参加しています

にほんブログ村 IT技術ブログへ
にほんブログ村