opencv - 如何平均两个口罩?
问题描述
我有两个布尔掩码,我从两个视频帧的对象检测i
和i+1
. 现在我想“平均”它们以消除噪音。蒙版是封闭的凸曲线。所以基本上我想找到它们之间的中间线。我怎样才能做到这一点?
假设我们有两个连续的帧有两个红色和蓝色,过滤后我们需要得到两个轮廓之间的绿线。
解决方案
您可以使用距离变换来完成此操作。
核心思想是计算到每个掩模边缘的有符号距离,并找到平均值的零水平集。该算法不需要凸面掩码。我确实假设输入是实心蒙版(即填充轮廓)。
距离变换计算每个对象像素到最近背景像素的(欧几里得)距离。到边缘的有符号距离由两个距离变换的组合形成:对象的距离变换和背景的距离变换(即反转蒙版的距离变换)。后者,从前者中减去,得到一个图像,其中蒙版外的像素与蒙版边缘的距离为负,而内部的像素与蒙版边缘的距离为正。掩码的边缘由零交叉给出。
如果您计算到两个掩码图像边缘的有符号距离,并将它们平均在一起,您将在两个掩码边缘正好一半的位置获得零交叉。简单地对该结果进行阈值化即可为您提供平均掩码。
请注意,由于我们将阈值设置为 0,因此两个有符号距离之和或其平均值之间没有差异。总和计算起来更便宜。
这是一个示例,使用您的颜色编码(红色和蓝色是两个输入的边缘,绿色是输出的边缘):
下面的代码是带有 DIPimage 的 MATLAB,我编写它只是为了显示结果。只需将其视为您使用 OpenCV 实现的伪代码。:)
% inputs: mask1, mask2: binary images
d1 = dt(mask1) - dt(~mask1); % dt is the distance transform
d2 = dt(mask2) - dt(~mask2); % ~ is the logical negation
mask = (d1+d2) > 0; % output
推荐阅读
- python - 在shebang中使用“#!/usr/bin/env python”而不是仅仅调用“#!python”解释器有什么优势?
- javascript - window.getComputedStyle(elem) 用于元素未悬停的情况,即使它当前已悬停
- python - 我得到退出代码 0 但程序没有做我想要的。看起来它卡在第一行代码中
- wso2esb - 基于 REST API 的 TCP 请求/响应
- postgresql - CloudSQL Postgres 对表授权和所有者感到困惑
- arrays - 如何根据其他列值从其他列复制数据
- python - 无法使用 CUDA 9.2 安装 pytorch 1.2
- python-3.x - 如何制作一个需要 3 秒然后在控制台中打印的程序
- addition - 如何使用 CNF 描述加法
- laravel - 更新 laravel 6.2 [App\Http\Controllers\Auth\ConfirmPasswordController] 后不存在