使用 OpenCV+CVzone 進行實時背景替換

介紹

OpenCV是一個開源計算機視覺庫,可提供播放不同影象和影片流的許可權,還有助於端到端專案,如物件檢測、人臉檢測、物件跟蹤等。

CVzone是一個計算機視覺包,可以讓我們輕鬆執行像人臉檢測、手部跟蹤、姿勢估計等,以及影象處理和其他 AI 功能。它的核心是使用 OpenCV 和 MediaPipe 庫。請點選此處獲取更多資訊。

https://github。com/cvzone/cvzone

為什麼需要實時背景去除?

由於許多原因,影片的背景需要修改,如背景中有很多其他中斷或背景顏色不適合該人。因此,我們使用實時背景替換技術來替換背景並新增替換為所需內容。

使用 OpenCV+CVzone 進行實時背景替換

流行的背景去除技術

影象剪下路徑

- 如果影象的主題具有銳利的邊緣,則使用此技術。所有落在路徑之外的元素都將被消除。

影象剪下

– 在這裡,我們剪下幀中所需的區域或主題並刪除背景。

影象遮罩

– 如果影象有褶邊或細邊緣,我們可以使用影象遮罩技術。

擦除背景

– 使用任何不同的工具擦除影象的背景

許多著名的應用程式使用背景去除技術並用自定義技術替換它。在這裡,我們將實現類似的東西,使用 OpenCV 和 CVzone。

讓我們開始實施

安裝所需的模組。

—— pip install OpenCV-python

—— pip install cvzone

—— pip install mediapipe

首先,讓我們檢查一下我們的網路攝像頭是否工作正常。

import cv2

cap = cv2。VideoCapture()

cap。set(3, 640)

cap。set(4, 480)

while True:

success, img = cap。read()

cv2。imshow(“Image”, img)

if cv2。waitKey(1) & 0xFF == ord(‘q’):

break

如果你有網路攝像頭,上面的程式碼會彈出一個視窗,這裡的幀大小是 640 X 480。所以我們需要注意,因為背景替換影象的大小應該與幀大小相同,即 640 X 480 。

使用 OpenCV+CVzone 進行實時背景替換

現在在這裡建立專案目錄中的資料夾,我正在建立一個名為*‘BackgroundImages’*的資料夾。你可以下載任何影象或任意數量的影象並將它們放在此目錄中。

專案結構將如下圖所示:

使用 OpenCV+CVzone 進行實時背景替換

讓我們在單獨的 python 檔案中編寫一小段程式碼,將*“BackgroundImages”*資料夾中的所有影象大小調整 為 640 X 480。

import cv2

import os

for root, subdirs, files in os。walk(‘D:/pycharmprojects/BackgroundRemover/BackgroundImages’):

for f in files:

if f。endswith(‘jpg’):

# print(f)

img = cv2。imread(‘D:/pycharmprojects/BackgroundRemover/BackgroundImages/’ + f)

img = cv2。resize(img, (640, 480))

cv2。imwrite(‘D:/pycharmprojects/BackgroundRemover/BackgroundImages/’+f, img)

print(*[“Image”, f, “is resized to 640 X 480”])

上面的程式碼將讀取指定資料夾中的影象(jpg)檔案,並一次將所有影象調整為 640 X480。

調整所有影象大小後的輸出

使用 OpenCV+CVzone 進行實時背景替換

現在我們都準備好實現背景替換技術了。

匯入需要的模組

import cv2

import cvzone

from cvzone。SelfiSegmentationModule import SelfiSegmentation

import os

在上面的模組中,*“SelfSegmentation”*用於刪除框架的背景並將其替換為我們目錄中的影象。

cap = cv2。VideoCapture()

cap。set(3, 640)

cap。set(4, 480)

# cap。set(cv2。CAP_PROP_FPS, 60)

segmentor = SelfiSegmentation()

fpsReader = cvzone。FPS()

# imgBG = cv2。imread(“BackgroundImages/3。jpg”)

listImg = os。listdir(“BackgroundImages”)

imgList = []

for imgPath in listImg:

img = cv2。imread(f‘BackgroundImages/’)

imgList。append(img)

indexImg =

在上面的程式碼中,我們採取從網路攝像頭輸入,並且還設定幀寬度為640 X 480

然後呼叫SelfiSegmentation(),並將其分配給一個變數segmentor,並且為了在顯示幀每秒(fps)的輸出幀,我們使用*cvzone。FPS()*函式。

然後我們建立一個存在於BackgroundImages資料夾中的影象列表,我們遍歷該列表並讀取每個影象並將其附加到一個空列表中。初始索引設定為零。

while True:

success, img = cap。read()

# imgOut = segmentor。removeBG(img, (255,0,255), threshold=0。83)

imgOut = segmentor。removeBG(img, imgList[indexImg], threshold=0。8)

imgStack = cvzone。stackImages([img, imgOut], 2,1)

_, imgStack = fpsReader。update(imgStack)

print(indexImg)

cv2。imshow(“image”, imgStack)

key = cv2。waitKey(1)

if key == ord(‘a’):

if indexImg>:

indexImg -=1

elif key == ord(‘d’):

if indexImg

indexImg +=1

elif key == ord(‘q’):

break

現在主要部分在 while 迴圈中從網路攝像頭讀取幀,我們使用*segmentor。removeBG()*函式從幀中刪除背景並將其替換為目錄中的影象。

在上面的程式碼中,你可以看到我們已經向segmentor。removeBG()函式傳遞了三個引數 ,即來自網路攝像頭的影象幀(img),然後是目錄中存在的影象列表以及影象索引

(imgList[indexImg) ])

,最後是閾值。如果閾值設定為 1,則閾值會削減所有內容,這裡我們將其設定為 0。8,為了獲得更好的邊緣,請使用不同的閾值。

然後我們使用cvzone。stackImages堆疊影象*,* 這裡我們將獲得背景替換影象或幀的輸出。然後使用一個簡單的 if 語句,分配鍵來更改背景。

例如,如果我們有 10 張背景影象,根據上面的程式碼,我們可以使用鍵“a”或鍵“d”來更改幀的背景。

整個程式碼如下。

import cv2

import cvzone

from cvzone。SelfiSegmentationModule import SelfiSegmentation

import os

cap = cv2。VideoCapture()

cap。set(3, 640)

cap。set(4, 480)

# cap。set(cv2。CAP_PROP_FPS, 60)

segmentor = SelfiSegmentation()

fpsReader = cvzone。FPS()

# imgBG = cv2。imread(“BackgroundImages/3。jpg”)

listImg = os。listdir(“BackgroundImages”)

imgList = []

for imgPath in listImg:

img = cv2。imread(f‘BackgroundImages/’)

imgList。append(img)

indexImg =

while True:

success, img = cap。read()

# imgOut = segmentor。removeBG(img, (255,0,255), threshold=0。83)

imgOut = segmentor。removeBG(img, imgList[indexImg], threshold=0。8)

imgStack = cvzone。stackImages([img, imgOut], 2,1)

_, imgStack = fpsReader。update(imgStack)

print(indexImg)

cv2。imshow(“image”, imgStack)

key = cv2。waitKey(1)

if key == ord(‘a’):

if indexImg>:

indexImg -=1

elif key == ord(‘d’):

if indexImg

indexImg +=1

elif key == ord(‘q’):

break

輸出截圖如下

輸出 1:

使用 OpenCV+CVzone 進行實時背景替換

輸出 2:

使用 OpenCV+CVzone 進行實時背景替換

整個程式碼也可以在這裡找到:

https://github。com/BakingBrains/Real-Time_Background_remover

參考:

https://www。youtube。com/watch?v=k7cVPGpnels

☆ END ☆

如果看到這裡,說明你喜歡這篇文章,請轉發、點贊。微信搜尋「uncle_pn」,歡迎新增小編微信「 woshicver」,每日朋友圈更新一篇高質量博文。