文章目录
- 一、项目思路
- 二、环境布置
- 2.1、cvzone安装
- 2.2、MediaPipe安装
- 2.3、常见问题
- 2.4、注意事项
- 三、算法详解
- 3.1、segmentor.removeBG():去除背景(抠出图像中的人)
- 3.2、cvzone.stackImages():堆叠图像
- 3.3、fpsReader.update():更新帧图像
- 3.4、os.listdir():返回指定的文件夹包含的文件或文件夹的名字的列表。
- 四、实战:基于cvzone的背景替换
一、项目思路
- 设置框架参数
- 指定存放图像的文件夹地址
- 遍历图像并缩放至与框架相同尺寸
- 移除摄像头拍摄的背景
- 与指定图像进行叠加
- 实时更新
二、环境布置
2.1、cvzone安装
- Opencv是一个开源计算机视觉库。
- cvzone是一个计算机视觉包。提供如:人脸检测、手部跟踪、姿势估计等项目,以及图像处理和其他 AI 功能。它的核心是使用 OpenCV 和 MediaPipe 库。
DOS命令行窗口中输入:pip install cvzone
2.2、MediaPipe安装
MediaPipe 是一个基于图形的跨平台框架,用于构建多模式(视频,音频和传感器)应用的机器学习管道。可在移动设备、工作站和服务器上跨平台运行,并支持移动 GPU 加速。
(1)在线下载
DOS命令行窗口中输入:pip install cvzone
(2)离线下载(.whl)
官网下载地址:MediaPipe:为移动、边缘、云和web构建世界级ML解决方案和应用程序的最简单方法。
注意:MediaPipe版本必须与Python的版本对应。
更多项目可参考官网:
MediaPipe官网(github)
MediaPipe官网(gitee-镜像)
2.3、常见问题
关于python的mediapipe库踩过的坑
2.4、注意事项
如何减小锯齿和虚影:
(1)视频中布置的背景尽量简约(如:白墙等),过多的东西容易变成干扰项。
(2)手指间的虚影比较大,尽量减少相关动作。
三、算法详解
3.1、segmentor.removeBG():去除背景(抠出图像中的人)
函数说明:img_out = segmentor.removeBG(img, img_list[img_index], threshold=0.8)
输入函数: img 摄像头的帧图像
img_list[img_index] 目录中存在的图像列表以及图像索引
threshold 削减帧图像的背景(0~1)。1表示不进行图像叠加;0表示反向叠加。
3.2、cvzone.stackImages():堆叠图像
3.3、fpsReader.update():更新帧图像
3.4、os.listdir():返回指定的文件夹包含的文件或文件夹的名字的列表。
os.listdir()
:返回指定的文件夹包含的文件或文件夹的名字的列表。列表以字母排序。不包括 . 和 … ,即使它在文件夹中。只支持在 Unix, Windows 下使用。
函数说明:list = os.listdir(path)
输入参数 path -- 需要列出的目录路径
输入参数: 返回指定路径下的文件和文件夹列表。
################################################
folder_path = r"C:\Users\my\Desktop\Images" # 存放图像的文件夹路径(不能有中文)
list_img = os.listdir(folder_path) # os.listdir(): 返回指定文件夹下的文件名(列表结构)
print(list_img) # 打印文件夹中的图像名
img_list = [] # 存放自定义图像的列表
for img_path in list_img: # 遍历文件夹
image_path = folder_path + '/' + img_path # 读取图像路径
img = cv2.imread(image_path) # 读取图像
img_list.append(img) # 添加列表元素
print(len(img_list)) # 打印列表长度
四、实战:基于cvzone的背景替换
import cv2
import cvzone
import os
from cvzone.SelfiSegmentationModule import SelfiSegmentation
# 摄像头的帧大小是640x480,所以替换的背景图像大小应该与帧大小相同。
# 设置参数
cap = cv2.VideoCapture(0) # 获取图像设备(0/1)
cap.set(3, 640) # 调整输出框架的长
cap.set(4, 480) # 调整输出框架的宽
cap.set(cv2.CAP_PROP_FPS, 60) # 调整输出框架的帧速率
segmentor = SelfiSegmentation() # 实例化分割模型
fpsReader = cvzone.FPS() # 显示帧每秒(fps)的输出帧
folder_path = r"C:\Users\my\Desktop\Images" # 存放背景图像的文件夹路径(不能有中文)(可存放任意张图像)
list_img = os.listdir(folder_path) # os.listdir(): 返回指定文件夹下的文件名(列表结构)
print(list_img) # 打印文件夹中的图像名
img_list = [] # 存放自定义图像的列表
for img_path in list_img: # 遍历文件夹
image_path = folder_path + '/' + img_path # 读取图像路径
img = cv2.imread(image_path) # 读取图像
print(img.size) # 打印图像尺寸
img = cv2.resize(img, (640, 480)) # 图像缩放到指定尺寸
img_list.append(img) # 添加列表元素
print(len(img_list)) # 打印列表长度
img_index = 0 # 初始化背景图片(列表中索引=0)
while 1:
reg, img = cap.read() # 读取帧图像
img_out = segmentor.removeBG(img, img_list[img_index], threshold=0.5) # 移除背景
img_stacked = cvzone.stackImages([img, img_out], 2, 1) # 图像叠加
fps, img_stacked = fpsReader.update(img_stacked, color=(0, 0, 255)) # 实时更新(人物是动态的)
cv2.imshow("Image_stacked", img_stacked) # 图形化显示(标题名 + 图像)
key = cv2.waitKey(1) # 使用 waitKey 可以控制视频的播放速度。数值越小,播放速度越快。
if key & 0xFF == 27: # 按Esc退出
break
elif key == ord('q'): # 背景切换
if img_index > 0:
img_index -= 1 # Q键:在自定义的图片中,正向选择图片
elif key == ord('w'):
if img_index < len(img_list)-1:
img_index += 1 # W键:在自定义的图片中,逆向选择图片
Opencv项目实战:你这背景太假啦!