【Opencv项目实战】背景替换:动态背景移除与替换(cvzone)

news2024/9/24 6:02:58

文章目录

  • 一、项目思路
  • 二、环境布置
    • 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的背景替换

一、项目思路

  1. 设置框架参数
  2. 指定存放图像的文件夹地址
  3. 遍历图像并缩放至与框架相同尺寸
  4. 移除摄像头拍摄的背景
  5. 与指定图像进行叠加
  6. 实时更新

二、环境布置

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项目实战:你这背景太假啦!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/376810.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Hot Chocolate 构建 GraphQL .Net Core 服务

Hot Chocolate 是 .NET 平台下的一个开源组件库, 您可以使用它创建 GraphQL 服务, 它消除了构建成熟的 GraphQL 服务的复杂性, Hot Chocolate 可以连接任何服务或数据源&#xff0c;并创建一个有凝聚力的服务&#xff0c;为您的消费者提供统一的 API。 我会在 .NET 应用中使用…

mysql一两种索引方式hash和btree

1. Hash索引&#xff1a; Hash 索引结构的特殊性&#xff0c;其检索效率非常高&#xff0c;索引的检索可以一次定位&#xff0c;不像B-Tree 索引需要从根节点到枝节点&#xff0c;最后才能访问到页节点这样多次的IO访问&#xff0c;所以 Hash 索引的查询效率要远高于 B-Tree 索…

FFmpeg 编译和集成

背景FFmpeg 是一款知名的开源音视频处理软件&#xff0c;它提供了丰富而友好的接口支持开发者进行二次开发。FFmpeg 读作 “ef ef em peg” &#xff0c;其中的 “FF” 指的是 “Fast Forward”&#xff0c;“mpeg” 则是 “Moving Picture Experts Group” &#xff08;动态图…

隧道代理的工作原理是什么,为何爬虫使用起来更高效?

在网络爬虫领域&#xff0c;使用HTTP代理是非常普遍的一种技术手段。而隧道代理则是HTTP代理中的一种&#xff0c;它是指将请求通过隧道传输到代理服务器上&#xff0c;并由代理服务器向目标服务器发送请求&#xff0c;从而达到隐藏真实IP的目的。那么&#xff0c;隧道HTTP代理…

告别空指针让代码变优雅,Optional使用图文例子源码解读

一、前言 我们在开发中最常见的异常就是NullPointerException&#xff0c;防不胜防啊&#xff0c;相信大家肯定被坑过&#xff01; 这种基本出现在获取数据库信息中、三方接口&#xff0c;获取的对象为空&#xff0c;再去get出现&#xff01; 解决方案当然简单&#xff0c;只…

华为OD机试模拟题 用 C++ 实现 - 最优资源分配(2023.Q1)

最近更新的博客 【华为OD机试模拟题】用 C++ 实现 - 最多获得的短信条数(2023.Q1)) 文章目录 最近更新的博客使用说明最优资源分配题目输入输出描述备注示例一输入输出说明示例二输入输出说明Code使用说明 参加华为od机试,一定要注

2023 Java 分布式 面试 大纲

前段时间 &#xff0c;公司部门的HR找到我&#xff0c;说来了几份简历 &#xff0c;都是三年所有的开发 让我面一下&#xff0c; HR那边 一面核对了基本的信息 二面技术&#xff0c;是由我来接手&#xff0c;然后问了 一些分布式的问题 &#xff0c;大部分都是在围绕着SpringCl…

这回稳了!电力巡检低功耗摄像头全新来袭

最近的狂飙成为大家的话题&#xff0c;互联网的发展让很多信息都很透明&#xff0c;这个也是我比较喜欢和各位技术大咖一起分享一些当下比较前沿的解决方案 春回大地&#xff0c;疫情远去&#xff0c;我们也没有理由逃避不去努力&#xff0c;在互相网的各种平台去获取各种自己需…

安全配置检查的必要性?以及检查流程

随着行业信息化建设的不断深入&#xff0c;生产、业务支撑系统的网络结构越来越复杂&#xff0c;由此带来的各种应用和服务器的数量及种类也日益增多&#xff0c;一旦发生维护人员错误操作&#xff0c;或者采用一成不变的初始系统设置&#xff0c;就可能会带来安全隐患&#xf…

〖大前端 - 基础入门三大核心篇②〗- 前端开发工具和环境准备

大家好&#xff0c;我是 哈士奇 &#xff0c;一位工作了十年的"技术混子"&#xff0c; 致力于为开发者赋能的UP主, 目前正在运营着 TFS_CLUB社区。 &#x1f4ac; 人生格言&#xff1a;优于别人,并不高贵,真正的高贵应该是优于过去的自己。&#x1f4ac; &#x1f4e…

2020蓝桥杯真题跑步锻炼(填空题) C语言/C++

题目描述 本题为填空题&#xff0c;只需要算出结果后&#xff0c;在代码中使用输出语句将所填结果输出即可。 小蓝每天都锻炼身体。 正常情况下&#xff0c;小蓝每天跑 1 千米。如果某天是周一或者月初&#xff08;1 日&#xff09;&#xff0c;为了激励自己&#xff0c;小蓝…

TCP协议原理三

文章目录七、延时应答八、捎带应答九、面向字节流粘包问题十、TCP异常情况总结七、延时应答 如果说滑动窗口的关键是让窗口大一些&#xff0c;传输速度就快一些。那么延时应答就是在接收方能够处理的前提下&#xff0c;尽可能把ack返回的窗口大小尽可能大一些。 如果在接受数据…

关于事务的理解

事务的概念 事务处理几乎是每一个信息系统中都会涉及到的问题&#xff0c;它存在的意义就是保证系统中的数据是正确的&#xff0c;不同数据间不会产生矛盾&#xff0c;也就是保证数据状态的一致性&#xff08;Consistency&#xff09;。 关于一致性&#xff0c;我们重点关注的…

MySQL —— 基本查询

文章目录1. 向表中插入数据2. 查询操作2.1 全列查询2.2 指定列查询2.3 查询字段带表达式2.4 为查询结果指定别名2.5 去重操作3. where 条件3.1 比较运算符和逻辑预算符的运用3.2 like的细节3. 3 null查询4. 对查询的结果进行排序4.1 对单一字段进行排序4.2 对多个字段排序4.3 对…

密码学基础概念

把一段原始数据通过某种算法处理成另外一种数据&#xff08;原始数据为明文&#xff0c;处理后的数据为密文&#xff09;。明文->密文&#xff1a;称之为加密。密文->明文&#xff1a;称之为解密。 在加密过程中我们需要知道下面的这些概念&#xff1a; 1&#xff09;明文…

操作系统——10.进程通信

这篇文章我们来讲一下进程通信的相关内容 目录 1.概述 2.什么是进程通信 2.1进程通信——共享存储 2.2进程通信——管道通信 2.3进程通信——消息传递 3.小结 1.概述 首先&#xff0c;我们来看一下这节内容的大体框架 2.什么是进程通信 顾名思义&#xff0c;进程通信就是…

QML 鼠标事件

作者: 一去、二三里 个人微信号: iwaleon 微信公众号: 高效程序员 QML 中有一些元素本身是不具备交互能力的(例如:Rectangle、Text、Image 等),那么如何通过鼠标来控制它们的行为呢?这里就需要用到 MouseArea 元素了,它继承于 Item 且不可见,通常需要与可见元素结合使…

【vue2小知识】路由守卫的使用与解决RangeError: Maximum call stack size exceeded问题的报错。

&#x1f973;博 主&#xff1a;初映CY的前说(前端领域) &#x1f31e;个人信条&#xff1a;想要变成得到&#xff0c;中间还有做到&#xff01; &#x1f918;本文核心&#xff1a;当我们在路由跳转前与后我们可实现触发的操作 【前言】当我们在做类似于登录页面的时候&…

jmeter-如何在多线程一起执行时,控制请求的执行顺序【临界部分控制器】

前言&#xff1a;一个线程多个脚本的时候&#xff0c;发现只要100个用户同时执行&#xff0c;请求就会乱。期望2个线程执行结果&#xff1a;获取验证码-注册-登录这个流程获取验证码-注册-登录这个流程实际2个线程执行结果&#xff1a;a. 登录-获取验证码-注册b. 注册-获取验证…

运动无线蓝牙耳机哪款好、运动无线蓝牙耳机推荐

作为 运动爱好者&#xff0c;每天早晨醒来后的第一件事就去家门口的湿地公园跑上一圈。各种运动装备都齐了&#xff0c;不过在耳机选择上还真的犯难&#xff0c;打着“运动耳机”旗号的产品也是种类繁多&#xff0c;那么到底什么样的无线耳机更适合运动呢&#xff1f;于是我花时…