使用OpenCV - Python项目实现隐形斗篷

2025年4月11日 | 阅读 9 分钟

如果你是哈利·波特迷,你可能会熟悉著名的隐形斗篷,它是一种魔法服装,可以让哈利·波特随心所欲地消失。在本文中,我们将使用 OpenCV 和几行 Python 代码来创建类似的效果。我们将像哈利·波特用他的斗篷一样,展示一个人如何变得隐形。这个项目包括使用颜色检测、蒙版和简单的图像处理方法,使指定颜色的任何物体从视野中消失。让我们用 Python 和 OpenCV 来看看这种魔法的实现。

隐形斗篷的工作原理

这种方法基本上是传统绿幕抠像的逆过程。在绿幕抠像中,背景被移除,以便可以替换成不同的背景。而在这里,我们做的是相反的事情;前景帧被移除,这让我们能够使选定的物体消失。

魔术效果将这样实现:

  1. 捕获并存储背景帧:首先,在将斗篷添加到场景之前,会捕获并保存背景帧。这将存储背景,并将在斗篷移除图像部分时用作背景。
  2. 检测斗篷的颜色:OpenCV 的颜色检测和分割方法可以帮助识别斗篷的特定颜色。这些定义的颜色将在最终结果中消失。
  3. 为斗篷创建蒙版:接下来,将根据检测到的颜色生成蒙版。蒙版是斗篷出现区域的重要部分,只在这些位置留下背景。
  4. 生成具有隐形效果的最终输出:通过将原始背景与蒙版区域集成,斗篷的颜色将被背景替换,这使得斗篷以及穿着它的人看起来是隐形的。

最后,将输出生成为视频格式,例如 output.avi,以展示这种神奇的隐形效果。

让我们用 Python 制作这个神奇的隐形斗篷

使用 Python 和 OpenCV 构建隐形斗篷

现在我们将使用 OpenCV 模块在 Python 中构建隐形斗篷。

导入所需的模块

首先,我们将导入本项目的所有必需模块。这些模块包括 cv2 模块以及 time 和 numpy 模块。

代码

为了实现这种效果,需要将 HSV(色调、饱和度、明度)值设置在代码中,以匹配您使用的斗篷或布料的特定颜色。例如,如果你有一块红色或蓝色的布,并且想让它隐形,你将需要调整代码中的 HSV 值来准确检测颜色。在 OpenCV 中,颜色检测通常在 HSV 颜色空间中进行,因为它提供了对颜色范围更精确的控制,尤其是在光照条件变化的物体上。通过设置正确的 HSV 值,可以创建一个仅隔离斗篷颜色的蒙版。这些值将根据所用布料的颜色而有所不同。

  1. 对于红色斗篷: HSV 范围可以设置为检测红色色调,同时考虑饱和度和亮度。由于红色在 HSV 色轮中的位置,通常需要两个范围来提取低红色和高红色值。
  2. 对于蓝色斗篷:可以通过调整饱和度和阈值来设置 HSV 范围以检测蓝色阴影,从而确保在不同光照下都能准确检测。

通过微调代码中的这些 HSV 范围,布料的颜色就可以消失。

H:色调

色调是 HSV 模型中的颜色分量,其值范围为 0 到 36 度。

  • 红色: 0 至 60 度
  • 黄色: 61 至 120 度
  • 绿色: 121 至 180 度
  • 青色: 181 至 240 度
  • 蓝色: 241 至 300 度
  • 品红色: 301 至 360 度

S:饱和度

饱和度是 HSV 颜色模型提供的另一个度量,表示颜色的强度或纯度。它显示了灰色所占的百分比。饱和度以百分比表示,通常范围为 0% 至 100%。100% 的饱和度意味着颜色完全鲜艳,没有灰色。随着饱和度水平降低到 0%,会添加更多灰色,导致颜色褪色或暗淡。在某些情况下,饱和度可以显示为 0 到 1 的小数范围。在这里,0 的饱和度表示完全的灰色;另一方面,1 的饱和度表示颜色的最鲜艳版本。

V:明度

在颜色理论中,明度与饱和度一起定义颜色的亮度或强度。其测量范围为 0% 至 100%,其中 0 表示完全黑色,意味着没有亮度;另一方面,100% 表示最高亮度水平,表示颜色具有最强的强度。这个尺度有助于区分颜色的浅或深,较低的值给出较暗的颜色和更柔和的色调,而较高的值则显示鲜艳、完全照亮的颜色。明度是调整颜色在不同情况下外观的重要组成部分,它会影响许多设计和艺术应用中的感知深度、对比度和情绪。

记录和缓存每一帧的背景

为了实现视频中的这种隐形效果,像素会被替换以匹配红色,用背景中的像素替换,从而有效地使红色区域与背景无缝融合,仿佛它们是隐形的。这种方法需要精确检测红色像素和一致的背景采样,以在视频中保持平滑逼真的效果。

代码

说明

上面的代码片段用于通过 OpenCV 初始化来自系统默认摄像头的视频捕获。在延迟 3 秒以确保摄像头馈送稳定后,设置 变量 以保存帧计数和背景帧。该 循环 捕获 60 帧,旨在通过读取多帧来生成稳定的背景帧。最终捕获的背景帧会水平翻转,以匹配未来帧的方向。这个翻转的背景将稍后用于蒙版化特定颜色以使对象或人物隐形的效果。

检测每一帧中的颜色部分

在此步骤中,主要目标是通过将颜色空间从 RGB(红绿蓝) 转换为 HSV(色调、饱和度、明度)来分离图像中的红色区域。这种转换至关重要,因为 RGB 值容易受到光照变化的影响,使其在不同条件下进行颜色检测的可靠性降低。同时,HSV 将颜色信息(色调)与强度(明度)分开,使其在基于颜色的分割方面更具鲁棒性。一旦图像处于 HSV 空间,就会定义特定的颜色阈值来查找视频每一帧中的红色区域。通过为色调、饱和度和明度参数设置这些下限和上限,将创建指示仅红色区域的蒙版。此蒙版允许精确检测红色,这在诸如实现隐形斗篷效果等应用中非常有用。以下 HSV 值用于模拟检测视频中的红色阴影。

代码

说明

使用 OpenCV 从摄像头读取视频帧,直到流关闭,并在每一帧上设置一个简单的计数器。对每一帧都应用了几个图像处理步骤。通过水平翻转帧来进行镜像操作。然后,将颜色空间从 BGR 更改为 HSV,因为可以使用这种颜色空间更好地进行检测。定义了两个 HSV 颜色范围来检测红色阴影之间的差异。然后,代码创建两个二值蒙版,一个用于红色,另一个覆盖 HSV 空间中较低和较高的红色色调。然后将所有这些蒙版合并,形成一个捕获指定范围内所有红色阴影的单个蒙版。

在每一帧中用蒙版图像替换红色部分

既然视频中的红色区域已在 `red_mask` 二值图像中分离出来,我们就可以继续提取和增强原始帧中的这些红色区域。我们将首先利用蒙版从每一帧中仅分离出那些红色的部分,最终得到一个仅突出这些区域的图像。然后将分割的区域通过执行形态学运算进行进一步增强。具体来说,我们在这里使用形态学开运算,即先腐蚀后膨胀。这样,就可以去除噪声,而构成小孤立区域的红色像素会消失。最后,我们使用膨胀来扩展红色区域,使其轮廓清晰可见,并填充这些区域内的任何小内孔,以生成清晰的输出。

代码

说明

这段代码在一个二值蒙版上操作,以分离和增强视频帧中的红色区域。最初,对 `red_mask` 应用形态学开运算,以进一步去除由蒙版区域中可能出现的小物体引起的噪声,从而生成 `cleaned_mask`。然后,对 `cleaned_mask` 执行膨胀操作,使具有红色的区域得以扩展;因此,会产生 `dilated_mask`。然后从 `dilated_mask` 创建一个反转蒙版,以便非红色区域在蒙版帧中显示为红色。然后使用这个反转蒙版生成一个 `segmented_frame`,该帧仅包含输入帧的非红色区域。然后,生成 `background_segment` 以显示红色区域被报告的静态背景。

代码

输出

Invisible Cloak using OpenCV - Python Project

图片 1:没有斗篷的背景

Invisible Cloak using OpenCV - Python Project

图片 2:有斗篷的背景

说明

此代码从摄像头捕获视频,处理每一帧以检测红色区域,并对红色对象应用背景减除。它首先通过平均 60 帧来获取初始的静态背景。背景会水平翻转以保持一致。然后为了镜像效果,帧会被水平翻转。它会逐帧处理,然后转换为 HSV 颜色空间。然后创建蒙版以确定红色区域,并使用两个独立的 HSV 范围来确保同时捕获浅红色和深红色阴影。对这些蒙版应用开运算和膨胀等形态学运算,以清除噪声并照亮红色区域。下一步是构建那些非红色部分图像的倒置蒙版,并从当前帧中提取它们。最后,代码生成一个背景图像,其中仅包含那些被检测为红色区域的部分。


下一个话题Pydub-module-in-python