pythonはOpenCVを使って簡単な人物分割と合成を行います。
構想を実現する
背景モデリングの方法により、ソース画像の動的人物の前景を分割し、対象画像を背景として合成動作を行い、利用可能な合成画像を得る。
実装手順は以下の通りです。
バックグラウンド分割は、Background SubtractomoG 2を用いて行います。
Background SubtractomoG 2はガウス混合モデルをベースとした背景展望分割アルゴリズムである。
ハイブリッドガウスモデル
分布確率はKガウス分布の和であり、各ガウス分布は自己のものである。μμ 和σσ パラメータ、および対応する重みパラメータ、重み値は正の数でなければなりません。すべての重みの和は1に等しくなければなりません。数式が数値を与えるのが合理的な確率密度値であることを保証します。つまり、数式に対応する入力空間を統合すると、結果は1になります。
元のアルゴリズムに戻ると、各ピクセルに適した数のガウス分布を選択するのが特徴です。ガウスモデルの期待と標準偏差に基づいて,ハイブリッドガウスモデルにおけるどのガウスモデルがこのピクセルポイントにより対応する可能性が高いかを判断し,もし一致しないならば前景として判定する。
顔情報を塗りつぶした人物認識
カスケード分類器を作成
ソース画像のポートレートを識別する
人物と目標背景を合成する
背景との追加操作
背景モデリングの方法により、ソース画像の動的人物の前景を分割し、対象画像を背景として合成動作を行い、利用可能な合成画像を得る。
実装手順は以下の通りです。
バックグラウンド分割は、Background SubtractomoG 2を用いて行います。
Background SubtractomoG 2はガウス混合モデルをベースとした背景展望分割アルゴリズムである。
ハイブリッドガウスモデル
分布確率はKガウス分布の和であり、各ガウス分布は自己のものである。μμ 和σσ パラメータ、および対応する重みパラメータ、重み値は正の数でなければなりません。すべての重みの和は1に等しくなければなりません。数式が数値を与えるのが合理的な確率密度値であることを保証します。つまり、数式に対応する入力空間を統合すると、結果は1になります。
元のアルゴリズムに戻ると、各ピクセルに適した数のガウス分布を選択するのが特徴です。ガウスモデルの期待と標準偏差に基づいて,ハイブリッドガウスモデルにおけるどのガウスモデルがこのピクセルポイントにより対応する可能性が高いかを判断し,もし一致しないならば前景として判定する。
顔情報を塗りつぶした人物認識
カスケード分類器を作成
face_cascade = cv2.CascadeClassifier()
face_cascade.load(
'/usr/local/anaconda3/envs/OpenCV/lib/python3.8/site-packages/cv2/data/haarcascade_frontalface_default.xml')
OpenCVが持参するカスケード分類器を使って、OpenCVの基礎人物識別データをロードします。ソース画像のポートレートを識別する
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
形態学を用いて分割された見通しを塗りつぶす。
#
fgmask = cv2.morphologyEx(fgmask, cv2.MORPH_OPEN, kernel)
for i in range(15):
fgmask = cv2.dilate(fgmask, kernel, iterations=1)
オープン操作により、前景画像配列のノイズを除去し、拡大を繰り返し、前景の輪郭を塗りつぶします。人物と目標背景を合成する
def resolve(o_img, mask, faces):
if len(faces) == 0:
return
(x, y, w, h) = faces[0]
rgb_mask_front = cv2.cvtColor(mask, cv2.COLOR_GRAY2BGR)
rgb_mask_front = cv2.bitwise_not(rgb_mask_front)
cv2.circle(rgb_mask_front, (int(x + w / 2), int(y + h / 2)), int((w + h) / 4), (0, 0, 0), thickness=-1)
o_img = cv2.subtract(o_img, rgb_mask_front)
return o_img
分割された部分を逆に取ってソース画像と減殺するのは、一つのMaskで原図から一部を切り取るのと同じです。背景との追加操作
out = resolve(frame, fgmask, faces)
out = cv2.add(out, c_frame)
コードの実装
import numpy as np
import cv2
import os
#
camera = cv2.VideoCapture('./source/background_test2.avi')
cap = cv2.VideoCapture('./source/camera_test2.avi')
face_cascade = cv2.CascadeClassifier()
face_cascade.load(
os.getcwd()+'/source/haarcascade_frontalface_default.xml')
#
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3))
#
fgbg = cv2.createBackgroundSubtractorMOG2(detectShadows=False)
def resolve(o_img, mask, faces):
if len(faces) == 0:
return
(x, y, w, h) = faces[0]
rgb_mask_front = cv2.cvtColor(mask, cv2.COLOR_GRAY2BGR)
rgb_mask_front = cv2.bitwise_not(rgb_mask_front)
cv2.circle(rgb_mask_front, (int(x + w / 2), int(y + h / 2)), int((w + h) / 4), (0, 0, 0), thickness=-1)
o_img = cv2.subtract(o_img, rgb_mask_front)
return o_img
while True:
ret, frame = cap.read()
c_ret, c_frame = camera.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
fgmask = fgbg.apply(frame)
#
fgmask = cv2.morphologyEx(fgmask, cv2.MORPH_OPEN, kernel)
gray_camera = cv2.cvtColor(c_frame, cv2.COLOR_BGR2GRAY)
for i in range(15):
fgmask = cv2.dilate(fgmask, kernel, iterations=1)
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
out = resolve(frame, fgmask, faces)
out = cv2.add(out, c_frame)
cv2.imshow('Result', out)
cv2.imshow('Mask', fgmask)
k = cv2.waitKey(150) & 0xff
if k == 27:
break
out.release()
camera.release()
cap.release()
cv2.destroyAllWindows()
以上はpythonがOpenCVを使って簡単な人物分割と合成の詳しい内容です。python opencv人物分割と合成の資料について、他の関連記事に注目してください。