お役立ち

OpenCV(Python)でクロマキー

  • このエントリーをはてなブックマークに追加

OpenCVでクロマキー(Chroma Key)

クロマキーとはある特定の色を選択して背景とみなす手法です。今回はクロマキーを使って特定の色が透明色になる画像を生成する方法について紹介します。

クロマキーというよりは前景抽出を行いたい場合

静止画の前景抽出をしたい場合は「PythonでOpenCV~GrabCut(前景抽出)~」や「前景領域抽出ツール作成OpenCV」を参考にしてください。

サンプルコード

# -*- coding: utf-8 -*-
import cv2
#背景の色(緑)が2値化で0となるように前景色を指定
#背景色は青の値が120より未満(cv2.THRESH_BINARY)
B_thres_type = cv2.THRESH_BINARY
B_thres = 30
#背景色は緑の値が230以上(cv2.THRESH_BINARY_INV)
G_thres_type = cv2.THRESH_BINARY_INV
G_thres = 230
#背景色は赤の値が120未満
R_thres_type = cv2.THRESH_BINARY
R_thres = 30
#画像の読み込み
img = cv2.imread("img.jpg")
BGR = cv2.split(img)
#2値化を使ってそれぞれのチャンネルの背景を選択
_, B_mask = cv2.threshold(BGR[0], B_thres, 1, B_thres_type)
_, G_mask = cv2.threshold(BGR[1], G_thres, 1, G_thres_type)
_, R_mask = cv2.threshold(BGR[2], R_thres, 1, R_thres_type)
#BGRから生成した0-1行列をかけ合わせることで特定の値を背景とみなす
background_mask = B_mask * G_mask * R_mask
#0-1行列を0-255行列に変換してアルファチャンネルとして追加
result = cv2.merge(BGR + [255 * background_mask])
cv2.imwrite("result.png", result)

解説

#背景の色(緑)が2値化で0となるように前景色を指定
#背景色は青の値が120より未満(cv2.THRESH_BINARY)
B_thres_type = cv2.THRESH_BINARY
B_thres = 30
#背景色は緑の値が230以上(cv2.THRESH_BINARY_INV)
G_thres_type = cv2.THRESH_BINARY_INV
G_thres = 230
#背景色は赤の値が120未満
R_thres_type = cv2.THRESH_BINARY
R_thres = 30

ここでは、背景が0、前景が1となるマスク画像を生成するために閾値を設定しています。また、2値化のフラグで閾値より大きいか小さいかを選択します。緑色の画素は青と赤の値が小さく緑の値が大きい画素と考えることができます。つまり、赤と青の値は未満のほうを背景としたいのでcv2.THRESH_BINARYを選び、緑の値は以上のほうを選択すれば背景マスクが作成できます。

#2値化を使ってそれぞれのチャンネルの背景を選択
_, B_mask = cv2.threshold(BGR[0], B_thres, 1, B_thres_type)
_, G_mask = cv2.threshold(BGR[1], G_thres, 1, G_thres_type)
_, R_mask = cv2.threshold(BGR[2], R_thres, 1, R_thres_type)
#BGRから生成した0-1行列をかけ合わせることで特定の値を背景とみなす
background_mask = B_mask * G_mask * R_mask

それぞれBGRにチャンネル分解した画像に設定した2値化を適用することでそれぞれのチャンネルのマスク画像ができます。単体ではマスクとして機能しないので3つを掛け合わせることで合成します。3つの条件すべてを満たす画素のみ1となりそれ以外は0となります。

  • このエントリーをはてなブックマークに追加