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では、ヒストグラムの表示と顔認証を紹介したいと思います!
