OpenCVで画像・映像加工処理 画像や映像を好き勝手加工してみる パート1 〜色変換編〜
画像や映像を好き勝手加工してみる パート1 〜色変換編〜
OpenCVで画像・映像加工処理
こんにちは。目指せ!脱コボラー!のsakaです。
今回はPython×OpenCVで、画像や映像を加工してみた話をします。
パート1では、色を変える処理を紹介していきます。
具体的には、以下の3つを紹介します。
・色指定(RGB)
・白黒,ネガポジ反転
・色変換
OpenCV
OpenCVとは、「CPで画像や映像を処理するのに必要な機能が実装されているOSSライブラリ」です。
画像や映像を加工するにはもってこいのライブラリです!
前準備
・必要なモジュールを用意
cv2
OpenCVの機能を使うときに必要
numpy
数値計算を効率的に行なう
os
osに依存している機能を利用できる
・以下のコマンドを実行
pip install opencv-python
pip install numpy
・フォルダ構造
/rgb/
/gray.py
/replace.py
/rgb.py
/img/
/fruit.jpg
この画像を加工していきます。
(fruit.jpg)
プログラム
・色指定(RGB)
画像を読み取り(old_img)、[青,緑,赤]に分けたのち、指定した色だけ出力する。
python:rgb.py
import cv2 import numpy as np import os # 画像があるフォルダ取得 PATH = './img' FOLDER = os.listdir(PATH) # ウィンドウ名の設定 OLD_WINDOW_NAME = 'old' NEW_WINDOW_NAME = 'new' COLORS = ['blue', 'green', 'red'] # 画像名取得 def get_file_name(): # フォルダ内ファイル名全取得 print('*** All Pictures ***') print(*FOLDER, sep='\n') print('*** End ***') while True: file_name = input('Which use file name ?: ') if file_name in FOLDER: return file_name else: print('not exist: ' + file_name) # 使用色 yes OR no ? def yes_no_color(color): while True: choice = input('Do you use "' + color + '" ? [y/N]: ').lower() if choice in 'yes': return True elif choice in 'no': return False # メイン if __name__ == '__main__': old_file_name = get_file_name() file_prefixes = old_file_name.rsplit('.', 1) new_file_name = file_prefixes[0] # 元の画像を読み込む old_img = cv2.imread(PATH + '/'+ old_file_name, cv2.IMREAD_COLOR) # ゼロ埋めの画像配列 if len(old_img.shape) == 3: height, width, channels = old_img.shape[:3] else: height, width = old_img.shape[:2] channels = 1 # 0に初期化 zeros = np.zeros((height, width), old_img.dtype) # RGB分離 img_colors = cv2.split(old_img) for color in COLORS: if yes_no_color(color): new_file_name += '_' + color[:1] else: img_colors[COLORS.index(color)] = zeros new_file_name += '.' + file_prefixes[1] new_img = cv2.merge((img_colors[0], img_colors[1], img_colors[2])) # ウィンドウを作成 cv2.namedWindow(OLD_WINDOW_NAME) cv2.namedWindow(NEW_WINDOW_NAME) # ウィンドウに表示 cv2.imshow(OLD_WINDOW_NAME, old_img) cv2.imshow(NEW_WINDOW_NAME, new_img) # ファイルに保存 cv2.imwrite(r'img/{}'.format(new_file_name), new_img) # 終了処理 cv2.waitKey(0) cv2.destroyAllWindows()
img_colors[COLORS.index(color)] = zeros
指定されなかった色は、ここで値を0に初期化される。
cv2.waitKey(0)
何かしらキーボード入力があるまで、プログラムを停止する。
入力文字を指定したい場合は以下のように変更する。
〇終了処理
python:rgb.py
while True: k = cv2.waitKey(0) print(k) if k == 27: # Escキー break
cv2.destroyAllWindows()
作成されたウィンドウを閉じる関数
特定のウィンドウのみ削除したい場合、()内にウィンドウ名を入力する。
・白黒,ネガポジ反転
白黒 => cv2.cvtColor(old_img, cv2.COLOR_BGR2GRAY)
反転 => cv2.bitwise_not(old_img)
python:gray.py
### 省略 ############################################################### ### rgb.pyの配列"COLORS"を削除 ### 関数yes_no_color()を削除 ########################################################################## if __name__ == '__main__': old_file_name = get_file_name() file_prefixes = old_file_name.rsplit('.', 1) new_file_name = file_prefixes[0] + '_gray.' + file_prefixes[1] # 元の画像を読み込む old_img = cv2.imread(PATH + '/'+ old_file_name, cv2.IMREAD_COLOR) new_img = cv2.cvtColor(old_img, cv2.COLOR_BGR2GRAY) # 白黒 # new_img = cv2.bitwise_not(old_img) # ネガポジ反転 # new_img = cv2.cvtColor(old_img, cv2.COLOR_BGR2RGB) # BGR => RGB # ウィンドウを作成 cv2.namedWindow(OLD_WINDOW_NAME) cv2.namedWindow(NEW_WINDOW_NAME) # ウィンドウに表示 cv2.imshow(OLD_WINDOW_NAME, old_img) cv2.imshow(NEW_WINDOW_NAME, new_img) # ファイルに保存 cv2.imwrite(r'img/{}'.format(new_file_name), new_img) # 終了処理 cv2.waitKey(0) cv2.destroyAllWindows()
cv2.cvtColor(old_img, cv2.COLOR_BGR2GRAY)
RGBをグレースケールに変換する。
cv2.bitwise_not(old_img)
ネガポジ反転する。
※ネガポジ反転 … 写真(ポジティブフィルム)をネガフィルム(ネガティブフィルム)に変換すること
cv2.cvtColor(old_img, cv2.COLOR_BGR2RGB)
BGRをRGBに変換するため、赤と青が入れ替わる。
・色変換
赤系を緑に変換
HSVに変換すると赤系は20未満又は300以上になることを考慮
python:replace.py
### 省略 ############################################################### ### rgb.pyの配列"COLORS"を削除 ### 関数yes_no_color()を削除 ########################################################################## if __name__ == '__main__': old_file_name = get_file_name() file_prefixes = old_file_name.rsplit('.', 1) new_file_name = file_prefixes[0] + '_after.' + file_prefixes[1] # 元の画像を読み込む old_img = cv2.imread(PATH + '/'+ old_file_name) # old_imgをHSVに変換し、複製する。 old_img_1 = cv2.cvtColor(old_img, cv2.COLOR_BGR2HSV) old_img_2 = np.copy(old_img_1) old_img_3 = np.copy(old_img_1) # 色変換 old_img_2[:, :, 0] = np.where(old_img_1[:, :, 0]>300, old_img_1[:, :, 0] - 180, old_img_1[:, :, 0]) old_img_3[:, :, 0] = np.where(old_img_2[:, :, 0]<20, old_img_2[:, :, 0] + 40, old_img_2[:, :, 0]) new_img = cv2.cvtColor(old_img_3, cv2.COLOR_HSV2BGR) # ウィンドウを作成 cv2.namedWindow(OLD_WINDOW_NAME) cv2.namedWindow(NEW_WINDOW_NAME) # ウィンドウに表示 cv2.imshow(OLD_WINDOW_NAME, old_img) cv2.imshow(NEW_WINDOW_NAME, new_img) # ファイルに保存 cv2.imwrite(r'img/{}'.format(new_file_name), new_img) # 終了処理 cv2.waitKey(0) cv2.destroyAllWindows()
cv2.cvtColor(old_img, cv2.COLOR_BGR2HSV)
色を変換する場合、HSVに変換しH(色相)を変えていく
出力結果
(rbg.png)
(gray.png)
(replace.png)
まとめ
パート1では、OpenCVを使って基本的な加工方法を試してみました。
顔認証や物体検知などでは、グレイスケールにしてデータを取得するらしいです。
次回パート2では、ヒストグラムの表示と顔認証を紹介したいと思います!