本帖最后由 云天 于 2022-5-11 09:26 编辑  
 
 
由于许多原因,视频的背景需要修改,如背景中有很多其他中断或背景颜色不适合该人。因此,我们使用实时背景替换技术来替换背景并添加替换为所需内容。 
流行的背景去除技术 
图像剪切路径 - 如果图像的主题具有锐利的边缘,则使用此技术。所有落在路径之外的元素都将被消除。 
 
图像剪切 – 在这里,我们剪切帧中所需的区域或主题并删除背景。 
 
图像遮罩 – 如果图像有褶边或细边缘,我们可以使用图像遮罩技术。 
 
擦除背景 – 使用任何不同的工具擦除图像的背景 
 
许多著名的应用程序使用背景去除技术并用自定义技术替换它。在这里,我们将实现类似的东西,使用 OpenCV 和 MediaPipe 。 
 
 
 MediaPipe 库可以让我们轻松运行像人脸检测、手部跟踪、姿势估计等,以及图像处理和其他 AI 功能。 
【安装MediaPipe 库】 
安装Mediapipe库与OpenCV库,参考AI人工智能应用:https://wiki.unihiker.com/ai_project 
 
【单背景测试】 
			
			
			- 
 - import cv2
 - import mediapipe as mp
 - import numpy as np
 - mp_drawing = mp.solutions.drawing_utils
 - mp_selfie_segmentation = mp.solutions.selfie_segmentation
 - 
 - # For webcam input:
 - BG_COLOR = (192, 192, 192) # gray
 - cap = cv2.VideoCapture(0)
 - 
 - cap.set(cv2.CAP_PROP_FRAME_WIDTH, 320)
 - cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 240)
 - cap.set(cv2.CAP_PROP_BUFFERSIZE, 1)
 - 
 - cv2.namedWindow('MediaPipe Selfie Segmentation',cv2.WND_PROP_FULLSCREEN)    #Set the windows to be full screen.
 - cv2.setWindowProperty('MediaPipe Selfie Segmentation', cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN)    #Set the windows to be full screen.
 - 
 - with mp_selfie_segmentation.SelfieSegmentation(
 -     model_selection=1) as selfie_segmentation:
 -   bg_image = cv2.imread("back.png")
 -   while cap.isOpened():
 -     success, image = cap.read()
 -     if not success:
 -       print("Ignoring empty camera frame.")
 -       # If loading a video, use 'break' instead of 'continue'.
 -       continue
 - 
 -     # Flip the image horizontally for a later selfie-view display, and convert
 -     # the BGR image to RGB.
 -     image = cv2.cvtColor(cv2.flip(image, 1), cv2.COLOR_BGR2RGB)
 -     # To improve performance, optionally mark the image as not writeable to
 -     # pass by reference.
 -     image.flags.writeable = False
 -     results = selfie_segmentation.process(image)
 - 
 -     image.flags.writeable = True
 -     image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
 - 
 -     # Draw selfie segmentation on the background image.
 -     # To improve segmentation around boundaries, consider applying a joint
 -     # bilateral filter to "results.segmentation_mask" with "image".
 -     condition = np.stack(
 -       (results.segmentation_mask,) * 3, axis=-1) > 0.1
 -     # The background can be customized.
 -     #   a) Load an image (with the same width and height of the input image) to
 -     #      be the background, e.g., bg_image = cv2.imread('/path/to/image/file')
 -     #   b) Blur the input image by applying image filtering, e.g.,
 -     #      bg_image = cv2.GaussianBlur(image,(55,55),0)
 -     if bg_image is None:
 -       bg_image = np.zeros(image.shape, dtype=np.uint8)
 -       bg_image[:] = BG_COLOR
 -     
 -     output_image = np.where(condition, image, bg_image)
 -     output_image = cv2.rotate(output_image, cv2.ROTATE_90_COUNTERCLOCKWISE)
 -     cv2.imshow('MediaPipe Selfie Segmentation', output_image)
 -     if cv2.waitKey(5) & 0xFF == 27:
 -       break
 - cap.release()
 
  复制代码
  
【按键A、B测试】 
- 
 - from pinpong.extension.unihiker import *
 - from pinpong.board import Board,Pin
 - 
 - 
 - Board().begin()
 - 
 - while True:
 -   if (button_a.is_pressed()==True):
 -     buzzer.play(buzzer.DADADADUM,buzzer.Once)
 -   if (button_b.is_pressed()==True):
 -     buzzer.play(buzzer.ENTERTAINER,buzzer.Once)
 
  复制代码 【准备多背景】现在在这里创建项目目录中的文件夹,我正在创建一个名为*'BackgroundImages'*的文件夹。你可以下载任何图像或任意数量的图像并将它们放在此目录中。 
 
【完整程序】 
这里我们将获得背景替换图像或帧的输出。然后使用一个简单的 if 语句,分配键来更改背景。 例如,如果我们有 5 张背景图像,根据上面的代码,我们可以使用键“A”或键“B”来更改帧的背景。  
- 
 - import cv2
 - import mediapipe as mp
 - import numpy as np
 - import os
 - from pinpong.extension.unihiker import *
 - from pinpong.board import Board,Pin
 - 
 - Board().begin()
 - mp_drawing = mp.solutions.drawing_utils
 - mp_selfie_segmentation = mp.solutions.selfie_segmentation
 - 
 - # For webcam input:
 - BG_COLOR = (192, 192, 192) # gray
 - cap = cv2.VideoCapture(0)
 - 
 - cap.set(cv2.CAP_PROP_FRAME_WIDTH, 320)
 - cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 240)
 - cap.set(cv2.CAP_PROP_BUFFERSIZE, 1)
 - 
 - cv2.namedWindow('MediaPipe Selfie Segmentation',cv2.WND_PROP_FULLSCREEN)    #Set the windows to be full screen.
 - cv2.setWindowProperty('MediaPipe Selfie Segmentation', cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN)    #Set the windows to be full screen.
 - listImg = os.listdir("./BackgroundImages")
 - imgList = []
 - for imgPath in listImg:
 -     img = cv2.imread(f'BackgroundImages/{imgPath}')
 -     imgList.append(img)
 -  
 - indexImg = 0
 - 
 - with mp_selfie_segmentation.SelfieSegmentation(
 -     model_selection=1) as selfie_segmentation:
 -   
 -   while cap.isOpened():
 -     success, image = cap.read()
 -     if not success:
 -       print("Ignoring empty camera frame.")
 -       # If loading a video, use 'break' instead of 'continue'.
 -       continue
 - 
 -     # Flip the image horizontally for a later selfie-view display, and convert
 -     # the BGR image to RGB.
 -     image = cv2.cvtColor(cv2.flip(image, 1), cv2.COLOR_BGR2RGB)
 -     # To improve performance, optionally mark the image as not writeable to
 -     # pass by reference.
 -     image.flags.writeable = False
 -     results = selfie_segmentation.process(image)
 - 
 -     image.flags.writeable = True
 -     image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
 - 
 -     # Draw selfie segmentation on the background image.
 -     # To improve segmentation around boundaries, consider applying a joint
 -     # bilateral filter to "results.segmentation_mask" with "image".
 -     condition = np.stack(
 -       (results.segmentation_mask,) * 3, axis=-1) > 0.1
 -     # The background can be customized.
 -     #   a) Load an image (with the same width and height of the input image) to
 -     #      be the background, e.g., bg_image = cv2.imread('/path/to/image/file')
 -     #   b) Blur the input image by applying image filtering, e.g.,
 -     #      bg_image = cv2.GaussianBlur(image,(55,55),0)
 -     if (button_a.is_pressed()==True):
 -       if indexImg>0:
 -             indexImg -=1
 - 
 -     if (button_b.is_pressed()==True):
 -       if indexImg<len(imgList)-1:
 -             indexImg +=1
 - 
 -     
 -     output_image = np.where(condition, image, imgList[indexImg])
 -     output_image = cv2.rotate(output_image, cv2.ROTATE_90_COUNTERCLOCKWISE)
 -     cv2.imshow('MediaPipe Selfie Segmentation', output_image)
 -     if cv2.waitKey(5) & 0xFF == 27:
 -       break
 - cap.release()
 
  复制代码
   
 
【演示视频】 
 
 
 |