目錄
- 實(shí)現(xiàn)思路
- 使用BackgroundSubtractorMOG2進(jìn)行背景分割
- 使用人像識(shí)別填充面部信息
- 使用形態(tài)學(xué)填充分割出來(lái)的前景
- 將人像與目標(biāo)背景進(jìn)行合成
- 代碼實(shí)現(xiàn)
實(shí)現(xiàn)思路
通過背景建模的方法,對(duì)源圖像中的動(dòng)態(tài)人物前景進(jìn)行分割,再將目標(biāo)圖像作為背景,進(jìn)行合成操作,獲得一個(gè)可用的合成影像。
實(shí)現(xiàn)步驟如下。
使用BackgroundSubtractorMOG2進(jìn)行背景分割
BackgroundSubtractorMOG2是一個(gè)以高斯混合模型為基礎(chǔ)的背景前景分割算法,
混合高斯模型

分布概率是K個(gè)高斯分布的和,每個(gè)高斯分布有屬于自己的 μμ 和 σσ 參數(shù),以及對(duì)應(yīng)的權(quán)重參數(shù),權(quán)重值必須為正數(shù),所有權(quán)重的和必須等于1,以確保公式給出數(shù)值是合理的概率密度值。換句話說如果我們把該公式對(duì)應(yīng)的輸入空間合并起來(lái),結(jié)果將等于1。
回到原算法,它的一個(gè)特點(diǎn)是它為每一個(gè)像素選擇一個(gè)合適數(shù)目的高斯分布。基于高斯模型的期望和標(biāo)準(zhǔn)差來(lái)判斷混合高斯模型模型中的哪個(gè)高斯模型更有可能對(duì)應(yīng)這個(gè)像素點(diǎn),如果不符合就會(huì)被判定為前景。
使用人像識(shí)別填充面部信息
創(chuàng)建級(jí)聯(lián)分類器
face_cascade = cv2.CascadeClassifier()
face_cascade.load(
'/usr/local/anaconda3/envs/OpenCV/lib/python3.8/site-packages/cv2/data/haarcascade_frontalface_default.xml')
使用OpenCV自帶的級(jí)聯(lián)分類器,加載OpenCV的基礎(chǔ)人像識(shí)別數(shù)據(jù)。
識(shí)別源圖像中的人像
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
使用形態(tài)學(xué)填充分割出來(lái)的前景
# 形態(tài)學(xué)開運(yùn)算去噪點(diǎn)
fgmask = cv2.morphologyEx(fgmask, cv2.MORPH_OPEN, kernel)
for i in range(15):
fgmask = cv2.dilate(fgmask, kernel, iterations=1)
通過開操作去掉前景圖像數(shù)組中的噪點(diǎn),然后重復(fù)進(jìn)行膨脹,填充前景輪廓。
將人像與目標(biāo)背景進(jìn)行合成
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
將分割出來(lái)的部分取反再與源圖像進(jìn)行減操作,相當(dāng)于用一個(gè)Mask從原圖中摳出一部分。
再與背景進(jìn)行加操作
out = resolve(frame, fgmask, faces)
out = cv2.add(out, c_frame)
代碼實(shí)現(xiàn)
import numpy as np
import cv2
import os
# 經(jīng)典的測(cè)試視頻
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')
# 形態(tài)學(xué)操作需要使用
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3))
# 創(chuàng)建混合高斯模型用于背景建模
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)
# 形態(tài)學(xué)開運(yùn)算去噪點(diǎn)
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進(jìn)行簡(jiǎn)單的人像分割與合成的詳細(xì)內(nèi)容,更多關(guān)于python opencv人像分割與合成的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
您可能感興趣的文章:- Python OpenCV高斯金字塔與拉普拉斯金字塔的實(shí)現(xiàn)
- Python OpenCV 基于圖像邊緣提取的輪廓發(fā)現(xiàn)函數(shù)
- Python opencv操作深入詳解
- Python+Opencv實(shí)現(xiàn)數(shù)字識(shí)別的示例代碼
- python中的opencv和PIL(pillow)轉(zhuǎn)化操作
- Python OpenCV 圖像區(qū)域輪廓標(biāo)記(框選各種小紙條)
- python opencv 找出圖像中的最大輪廓并填充(生成mask)
- python利用opencv實(shí)現(xiàn)顏色檢測(cè)
- Python基于opencv的簡(jiǎn)單圖像輪廓形狀識(shí)別(全網(wǎng)最簡(jiǎn)單最少代碼)
- python基于OpenCV模板匹配識(shí)別圖片中的數(shù)字