ルックアップテーブルで画像の彩度、明度を調整する(画像を明るく鮮やかにする)
画像を明るく鮮やかにします。
画像をBGR(青緑赤)の3チャンネルからなるBGR色空間から色相(Hue)、彩度(Saturation)、明度(Value)からなるHSV色空間に変換し、彩度H・明度Vを補正します。補正にはガンマカーブを用いて彩度・明度を全体的に大きくします。あらかじめガンマカーブを納めたルックアップテーブルを用意しcv2.LUT()メソッドにより各画素にルックアップテーブルを適用、彩度・明度のガンマ補正を行います。
画像処理ライブラリOpenCVでは彩度(Saturation)は[0,255],明度(Value)は[0,255]の範囲を取ります。ガンマ補正により値が小さい程高い倍率で変換することで明るく鮮やかな画像に変換します。元の値が255の場合は変換倍率は1倍で元のままなので、彩度や明度が飽和しておかしな画像になることはありません。
関連記事
ルックアップテーブルによる画像コントラストの補正
画像の彩度、明度を変える
PillowのImageEnhanceで画像の鮮やかさを変える
PillowのImageEnhanceで画像のブライトネス(明るさ)を変える
環境
準備
画像ファイルはフリー写真素材ぱくたそからダウンロードさせていただき、jupyter notebookファイル(***.ipynb)と同じディレクトリにファイル名'autumun.jpg'で保存しました。
①彩度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) # 画像を保存
実行結果
画像が鮮やかに補正されます。
用いたガンマカーブは以下の通りです。
②彩度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) # 画像を保存
実行結果
画像がさらに鮮やかに補正されます。
用いたガンマカーブは以下の通りです。gamma=2のガンマカーブと比べてより彩度が高めに補正されています。
③明度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) # 画像を保存
実行結果
画像が明るく補正されます。
④明度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) # 画像を保存
実行結果
画像がさらに明るく補正されます。
⑤彩度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) # 画像を保存
実行結果
画像が明るく鮮やかになります。
以下のサイトを参考にさせていただきました
Pythonの文法メモ >> 【OpenCV】LUTによる画像変換