掩膜合并代码

def ensure_dir(path):"""若目录不存在则创建"""if not os.path.exists(path): #判断路径是否存在os.makedirs(path) #创建路径def read_and_resize(img_path, size):"""读取并缩放图像到指定尺寸,返回 numpy 数组"""img = Image.open(img_path).convert("RGB") #Image.open 读取图片文件 .convert将数据改为所需的格式img = img.resize(size, Image.BILINEAR) #.resize(size, Image.BILINEAR) 缩放图片的大小 保证格式相同return np.array(img) #np.array 将数据的格式改为数组
#插值(interpolation):缩放图像时需要“估算”新像素值的方法。常见方式有:最近邻 (NEAREST),双线性插值 (BILINEAR),双三次插值 (BICUBIC)def merge_instance_masks(mask_folder, size):"""将一个病例下的所有 instance-mask 合并成一张二值 mask"""final = np.zeros(size[::-1], dtype=np.uint8)  # (H, W) 创建空的掩膜for fname in os.listdir(mask_folder): #os.listdir(...) 遍历文件 读取所有的mask图片if not fname.lower().endswith((".png", ".jpg", ".tif")): #跳过非图片文件 .endswith判断文件格式continuem = Image.open(os.path.join(mask_folder, fname)).convert("L") #.convert 将数据改为单通道数据 黑白图片m = m.resize(size, Image.NEAREST)          # 保持 label 不插值m = np.array(m)m = (m > 0).astype(np.uint8)               # 转成 0/1 二值化 (m > 0)布尔判断 生成一个和m形同形状的数组 并比较比0大的就是1 其他的就是0final = np.maximum(final, m)   #将符合条件的masks合并             # 像素级取最大值return final * 255      #最后输出的值为255\0 方便保存                       # 保存成 0/255def process_one_case(case_dir, out_img_dir, out_mask_dir, size):"""处理单个病例,输出 image.png & mask.png"""# 1. 读取原图(每个 images 文件夹只含一张)img_folder = os.path.join(case_dir, "images")#拼接路径,得到某病例的“images”文件夹路径img_name   = os.listdir(img_folder)[0]img        = read_and_resize(os.path.join(img_folder, img_name), size)# 2. 合并 maskmask_folder = os.path.join(case_dir, "masks")mask        = merge_instance_masks(mask_folder, size)# 3. 生成保存路径case_id = os.path.basename(case_dir)img_out_path  = os.path.join(out_img_dir,  f"{case_id}.png")mask_out_path = os.path.join(out_mask_dir, f"{case_id}.png")# 4. 保存Image.fromarray(img).save(img_out_path)Image.fromarray(mask).save(mask_out_path)def main():ensure_dir(OUT_IMG_DIR)ensure_dir(OUT_MASK_DIR)case_dirs = [os.path.join(SRC_ROOT, d) for d in os.listdir(SRC_ROOT)if os.path.isdir(os.path.join(SRC_ROOT, d))]for c in tqdm(case_dirs, desc="Processing cases"):process_one_case(c, OUT_IMG_DIR, OUT_MASK_DIR, TARGET_SIZE)print(f"✅ 处理完成!{len(case_dirs)} 张图像已保存到 {OUT_IMG_DIR} / {OUT_MASK_DIR}")if __name__ == "__main__":main()

这是比较完整的掩膜合并代码

掩膜(mask), 通俗易懂来说就是对图片中重要内容做的标签,一般的掩膜都是二值型的,背景的像素是0,而掩膜的像素是255。

为什么要进行掩膜合并:模型在处理文件时,一般是一张图片只能对应一个mask,但是有些图片中的特征比较多,需要多个mask标记,这些mask又是单独的文件,所以要将他们合并,方便后面模型处理

掩膜合并的过程简单来说就是:先确认文件的路径存在,再将图片提取出来,将图片的格式通过插值的方法统一格式像素大小方便后面进行处理。提取出mask,进行与图片相同的处理步骤后,通过二值化的方法提取出mask,最后在进行合并。

简洁的二值化掩膜合并代码

def merge_instance_masks(mask_folder, size):final_mask = np.zeros(size[::-1], dtype=np.uint8)for fname in os.listdir(mask_folder):if not fname.endswith('.png'):continuemask = Image.open(os.path.join(mask_folder, fname)).convert('L')mask = mask.resize(size, Image.NEAREST)mask = np.array(mask)mask = (mask > 0).astype(np.uint8)final_mask = np.maximum(final_mask, mask)return final_mask * 255

 

掩膜合并写代码的思路框架

  1. 明确掩膜格式和组织结构

    • 是多张单通道小掩膜文件,还是一张带类别标签的整图?

    • 是灰度图、RGB图还是三维数组(如 .npy, .nii)?

    • 是实例掩膜(每个对象单独一个文件)还是语义掩膜(每个像素分类标签)?

  2. 确定目标掩膜格式

    • 是要把多个实例掩膜合成一张二值掩膜?

    • 还是转换成语义分割标签图?

    • 还是保留多通道结构?(例如多类别多通道)

  3. 选择对应处理方法

    • 对文件夹内的多个二值掩膜做像素级“或”运算(np.maximum)

    • 对语义标签图做像素级直接使用

    • 对多通道数组用数组操作叠加/转换

  4. 写对应的代码模块,保证流程:读掩膜→处理→保存

其他mask类型的掩膜合并代码 

语义分割标签图(单文件,类别标签编码) 

def process_semantic_mask(mask_path, size):mask = Image.open(mask_path)mask = mask.resize(size, Image.NEAREST)mask = np.array(mask)# 假设原始mask是类别编码,如0-background,1-肿瘤,2-器官# 这里直接返回,不合并return mask

多类别掩膜存为多通道 npy 文件,转换为单通道标签图 

def multi_channel_npy_to_label(mask_npy_path, size):mask_3d = np.load(mask_npy_path)  # shape: (C, H, W)mask_3d_resized = np.zeros((mask_3d.shape[0], size[1], size[0]), dtype=np.uint8)for i in range(mask_3d.shape[0]):channel = cv2.resize(mask_3d[i], size, interpolation=cv2.INTER_NEAREST)mask_3d_resized[i] = channel# 逐像素最大类别索引作为标签label_mask = np.argmax(mask_3d_resized, axis=0).astype(np.uint8)return label_mask

掩膜合并中常用的函数方法 

  • Image.open() 读取图片

  • img.resize() 缩放图片

  • np.array() 转成数组

  • np.maximum() 进行掩膜合并

  • Image.fromarray() + .save() 保存图片

  • os.listdir() 遍历目录

  • os.path.join() 拼接路径

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

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

相关文章

蓝桥杯5130 健身

问题描述 小蓝要去健身,他可以在接下来的 1∼n 天中选择一些日子去健身。 他有 m 个健身计划,对于第 i 个健身计划,需要连续的 天,如果成功完成,可以获得健身增益 si​ ,如果中断,得不到任何…

auto关键字解析

前言 在11标准之前,auto在c中是声明存储器类型的关键字。而在11标准中它的功能变为了类型推导。 对此, 在这里引入Cprimer中的原句: 编程时常常需要把表达式的值赋给变量,这就要求在声明变量的时候清楚的知道表达式的类型。然而…

嵌入式STM32学习——串口USART 2.0(printf重定义及串口发送)

printf重定义: C语言里面的printf函数默认输出设备是显示器,如果要实现printf函数输出正在串口或者LCD显示屏上,必须要重定义标准库函数里调用的与输出设备相关的函数,比如printf输出到串口,需要将fputc里面的输出指向…

信号量机制:操作系统中的同步与互斥利器

在计算机操作系统中,信号量机制是一种重要的进程同步与互斥工具。它广泛应用于多进程或多线程环境中,用于解决并发访问共享资源时可能出现的竞态条件问题。本文将从信号量的基本概念出发,逐步深入探讨其工作原理、实现方式以及实际应用&#…

LeetCode 1004. 最大连续1的个数 III

LeetCode 1004题 “最大连续1的个数 III” 是一道关于数组和滑动窗口的问题。题目描述如下: 题目描述 给定一个由若干 0 和 1 组成的数组 nums,以及一个整数 k。你可以将最多 k 个 0 翻转为 1。返回经过翻转操作后,数组中连续 1 的最大个数…

digitalworld.local: FALL靶场

digitalworld.local: FALL 来自 <digitalworld.local: FALL ~ VulnHub> 1&#xff0c;将两台虚拟机网络连接都改为NAT模式 2&#xff0c;攻击机上做namp局域网扫描发现靶机 nmap -sn 192.168.23.0/24 那么攻击机IP为192.168.23.182&#xff0c;靶场IP192.168.23.4 3&…

经典Java面试题的答案——Java 基础

大家好&#xff0c;我是九神。这是互联网技术岗的分享专题&#xff0c;废话少说&#xff0c;进入正题&#xff1a; 1.JDK 和 JRE 有什么区别&#xff1f; JDK&#xff1a;Java Development Kit 的简称&#xff0c;java 开发工具包&#xff0c;提供了 java 的开发环境和运行环境…

LabVIEW风机状态实时监测

在当今电子设备高度集成化的时代&#xff0c;设备散热成为关键问题。许多大型设备机箱常采用多个风机协同散热&#xff0c;确保系统稳定运行。一旦风机出现故障&#xff0c;若不能及时察觉&#xff0c;可能导致设备损坏&#xff0c;造成巨大损失。为满足对机箱内风机状态实时监…

18 C 语言算术、关系、逻辑运算符及 VS Code 警告配置详解

1 运算符与表达式核心概念 1.1 什么是运算符 运算符是编程和数学中具有特定功能的符号&#xff0c;用于对数据进行运算、赋值、比较及逻辑处理等操作。它们能够改变、组合或比较操作数的值&#xff0c;进而生成新值或触发特定动作。 1.2 什么是表达式 表达式是编程和数学中用…

shell脚本之函数详细解释及运用

什么是函数 通俗地讲&#xff0c;所谓函数就是将一组功能相对独立的代码集中起来&#xff0c;形成一个代码块&#xff0c;这个代码可 以完成某个具体的功能。从上面的定义可以看出&#xff0c;Shell中的函数的概念与其他语言的函数的 概念并没有太大的区别。从本质上讲&#…

86.评论日记

再谈小米SU7高速爆燃事件_哔哩哔哩_bilibili 2025年5月21日14:00:45

Babylon.js学习之路《七、用户交互:鼠标点击、拖拽与射线检测》

文章目录 1. 引言&#xff1a;用户交互的核心作用1.1 材质与纹理的核心作用 2. 基础交互&#xff1a;鼠标与触摸事件2.1 绑定鼠标点击事件2.2 触摸事件适配 3. 射线检测&#xff08;Ray Casting&#xff09;3.1 射线检测的原理3.2 高级射线检测技巧 4. 拖拽物体的实现4.1 拖拽基…

adb抓包

目录 抓包步骤 步骤 1: 获取应用的包名 步骤 2: 查看单个应用的日志 步骤 3: 使用日志级别过滤器 步骤 4: 高级日志过滤 可能的原因&#xff1a; 解决方案&#xff1a; 额外提示&#xff1a; 日志保存 抓包步骤 连接设备 adb devices 步骤 1: 获取应用的包名 首先…

什么是实时流数据?核心概念与应用场景解析

在当今数字经济时代&#xff0c;实时流数据正成为企业核心竞争力。金融机构需要实时风控系统在欺诈交易发生的瞬间进行拦截&#xff1b;电商平台需要根据用户实时行为提供个性化推荐&#xff1b;工业物联网需要监控设备状态预防故障。这些场景都要求系统能够“即时感知、即时分…

百度飞桨OCR(PP-OCRv4_server_det|PP-OCRv4_server_rec_doc)文本识别-Java项目实践

什么是OCR? OCR&#xff08;Optical Character Recognition&#xff0c;光学字符识别&#xff09;是一种通过技术手段将图像或扫描件中的文字内容转换为可编辑、可搜索的文本格式&#xff08;如TXT、Word、PDF等&#xff09;的技术。它广泛应用于文档数字化、信息提取、自动化…

Pytorch实现常用代码笔记

Pytorch实现常用代码笔记 基础实现代码其他代码示例Networks or ProjectsNetwork ModulesLossUtils 基础实现代码 参考 深度学习手写代码 其他代码示例 Networks or Projects SENet学习笔记 SKNet——SENet孪生兄弟篇 GCNet&#xff1a;当Non-local遇见SENet YOLOv1到YOLO…

word通配符表

目录 一、word查找栏代码&通配符一览表二、word替换栏代码&通配符一览表三、参考文献 一、word查找栏代码&通配符一览表 序号清除使用通配符复选框勾选使用通配符复选框特殊字符代码特殊字符代码or通配符1任意单个字符^?一个任意字符?2任意数字^#任意数字&#…

TYUT-企业级开发教程-第6章

这一章 考点不多 什么是缓存&#xff1f;为什么要设计出缓存&#xff1f; 企业级应用为了避免读取数据时受限于数据库的访问效率而导致整体系统性能偏低&#xff0c;通 常会在应用程序与数据库之间建立一种临时的数据存储机制&#xff0c;该临时存储数据的区域称 为缓存。缓存…

双检锁(Double-Checked Locking)单例模式

在项目中使用双检锁&#xff08;Double-Checked Locking&#xff09;单例模式来管理 JSON 格式化处理对象&#xff08;如 ObjectMapper 在 Jackson 库中&#xff0c;或 JsonParser 在 Gson 库中&#xff09;是一种常见的做法。这种模式确保了对象只被创建一次&#xff0c;同时在…

华为网路设备学习-22(路由器OSPF-LSA及特殊详解)

一、基本概念 OSPF协议的基本概念 OSPF是一种内部网关协议&#xff08;IGP&#xff09;&#xff0c;主要用于在自治系统&#xff08;AS&#xff09;内部使路由器获得远端网络的路由信息。OSPF是一种链路状态路由协议&#xff0c;不直接传递路由表&#xff0c;而是通过交换链路…