OpenCVで画像・映像加工処理 画像や映像を好き勝手加工してみる パート1 〜色変換編〜

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

最新ブログ一覧