OpenCV 将多个掩膜合并为一个

目录

一、概述

二、代码实现

2.1代码

2.2代码解析

三、实现的结果

四、注意事项

4.1代码

4.2代码解析


一、概述

近期在做yolov8的实例分割,在一张图中可以分割出多个目标,那对应的掩膜就会有多个,不想通过遍历每个掩膜再合并成一个的方式。所以通过numpy进行多个掩膜的合并。

二、代码实现

2.1代码

如果你有一个形状为 (640, 480, num) 的掩膜数据,其中 num 大于1,想要将这些掩膜合并成一个单一的掩膜,可以考虑使用逻辑运算来实现。通常,合并多个掩膜的方法取决于你希望如何组合这些掩膜,比如取并集、交集等。

以下是一种将多个掩膜合并成一个的基本方法:

python 复制代码
import numpy as np

# 假设有多个掩膜数据,每个掩膜的形状为 (640, 480)
num = 3  # 假设有3个掩膜
mask_data = np.random.randint(0, 2, size=(640, 480, num))  # 示例随机生成的掩膜数据

# 方法1:取所有掩膜的最大值
merged_mask_max = np.max(mask_data, axis=2)

# 方法2:取所有掩膜的和(当掩膜值为1或0时适用)
merged_mask_sum = np.sum(mask_data, axis=2)

# 方法3:取所有掩膜的乘积(当掩膜值为1或0时适用)
merged_mask_prod = np.prod(mask_data, axis=2)

# 方法4:取所有掩膜的逻辑或
merged_mask_or = np.any(mask_data, axis=2)

# 方法5:取所有掩膜的逻辑与
merged_mask_and = np.all(mask_data, axis=2)

# 选择其中一种合并方法,比如逻辑或
final_mask = merged_mask_or

# 显示合并后的掩膜
print(final_mask.shape)  # 输出应为 (640, 480)

2.2代码解析

在上述示例中,我展示了几种合并掩膜的方法:

  1. 使用 np.max 函数取所有掩膜的最大值,适用于掩膜值为0或1的情况。
  2. 使用 np.sum 函数取所有掩膜的和,适用于掩膜值为0或1的情况。
  3. 使用 np.prod 函数取所有掩膜的乘积,适用于掩膜值为0或1的情况。
  4. 使用 np.any 函数取所有掩膜的逻辑或,结果为真(1)如果任何一个掩膜为真。
  5. 使用 np.all 函数取所有掩膜的逻辑与,结果为真(1)如果所有掩膜都为真。

你可以根据你的具体需求选择其中一种方法来合并掩膜。这些方法基于逻辑运算来组合多个掩膜,生成一个单一的掩膜图像。

三、实现的结果

图中的mask_data是我分割出来掩膜的合集,掩膜区域为1,背景为0。

通过np.count_nonzero去计算这五个方法计算掩膜后,像素值为1的个数。

四、注意事项

在获取掩膜后,需要对图片进行裁剪,在裁剪过程中需要注意将掩膜转换为二值图像,转换代码如下面所示。

4.1代码

python 复制代码
# 将mask的值转换为二值图像(0或255),并确保类型为uint8
binary_mask = (mask  * 255).astype(np.uint8)  # 0或255

# 确保binary_mask是二值图像(0和255)
_, binary_mask = cv2.threshold(binary_mask, 1, 255, cv2.THRESH_BINARY)

#获取到最后检测出来的目标图
result_image = cv2.bitwise_and(image, image, mask=binary_mask)

4.2代码解析

下面逐行解释这段代码的作用和每个步骤的目的:

python 复制代码
# 将mask的值转换为二值图像(0或255),并确保类型为uint8
binary_mask = (mask  * 255).astype(np.uint8)  # 0或255

**转换为二值图像:**这一行代码将原始的 mask 数据进行转换,目的是将其值缩放到一个适合的范围内,以便后续的处理。mask 可能包含的值在 0 到 1 之间,因此乘以 255 来将值映射到 0 到 255 的范围内。这将 mask 转换为二值图像,其中 0 表示像素被排除,255 表示像素被选中。.astype(np.uint8) 确保 binary_mask 的数据类型为 uint8,以便与 OpenCV 函数兼容。

python 复制代码
# 确保binary_mask是二值图像(0和255)
_, binary_mask = cv2.threshold(binary_mask, 1, 255, cv2.THRESH_BINARY)

二值化处理:cv2.threshold 函数用于对图像进行阈值化处理,将其转换为二值图像。在这里,cv2.threshold 函数将 binary_mask 中大于 1 的像素设置为 255(白色),小于等于 1 的像素设置为 0(黑色)。这确保 binary_mask 只包含值为 0 和 255 的像素,符合二值图像的要求。

python 复制代码
# 获取到最后检测出来的目标图
result_image = cv2.bitwise_and(image, image, mask=binary_mask)

**应用掩膜:**cv2.bitwise_and 函数用于将 binary_mask 应用于 image 上,只保留binary_mask 中像素值为 255 的区域对应的 image 像素。这样可以得到 result_image,其中只有 binary_mask 中被选中的区域保留了 image 的像素值,其他区域被遮挡或去除。

**总结:**这段代码的目的是根据 mask 数据提取出 image 中被选中的区域,并且保证输出的 result_image 只包含 mask 中被选中的部分的图像信息。

相关推荐
PhotonixBay5 小时前
3D共聚焦显微镜与探针式粗糙度仪:谁更适合亚表面损伤检测?
图像处理·人工智能·测试工具·3d
信奥卷王5 小时前
2025年09月GESPC++五级真题解析(含视频)
算法
白狐_7985 小时前
408 数据结构|外部排序:流程与 k 路归并
数据结构·算法
闻缺陷则喜何志丹5 小时前
【动态规划】P3609 [USACO17JAN] Hoof, Paper, Scissor G
c++·算法·动态规划·洛谷
2601_962297255 小时前
Python、Pytest、Allure、Selenium和Jenkins实现自动化测试集成实例
python·selenium·jenkins·pytest·allure
今天AI了吗6 小时前
Codex 配置自定义 AI API 完整指南:从零到一接入你的专属模型
java·人工智能·python·数据分析·embedding
阿童木写作6 小时前
跨境电商批量图片翻译与视频字幕翻译工具推荐
python·音视频
leihefeng6 小时前
手写数字识别:KNN vs 逻辑回归实战
python·算法·机器学习·逻辑回归·scikit-learn
SunnyDays10116 小时前
如何使用 Python 从 Word 文档中提取图片
python·word
2601_962097366 小时前
Pathway 实时RAG新方案:抛弃Spark、Flink,生产级数据管道
python·流处理·大数据集群·实时rag·pathway