【转换数据集格式】dcm转nii,mhd转nii,nii转nii.gz,nrrd转nii,jpg转png,将图像打patches块,

🍉 博主微信 cvxiayixiao
🍓 【Segment Anything Model】计算机视觉检测分割任务专栏。 链接
🍑 【公开数据集预处理】特别是医疗公开数据集的接受和预处理,提供代码讲解。链接
🍈 【opencv+图像处理】opencv代码库讲解,结合图像处理知识,不仅仅是调库。链接

【opencv+图像处理】专栏代码地址https://github.com/xiawei20161308104/xv_opencv_tutorials


本节叙述一些常见的医疗数据格式转换方式和代码。如果有新的转换需求评论区
在这里插入图片描述

😳装包

import os
join = os.path.join
import random
import numpy as np
from skimage import io
import SimpleITK as sitk

😄 dcm转nii

def dcm2nii(dcm_path, nii_path):
    reader = sitk.ImageSeriesReader()
    dicom_names = reader.GetGDCMSeriesFileNames(dcm_path)
    reader.SetFileNames(dicom_names)
    image = reader.Execute()
    sitk.WriteImage(image, nii_path)

😆mhd转nii

def mhd2nii(mhd_path, nii_path):
    image = sitk.ReadImage(mhd_path)
    sitk.WriteImage(image, nii_path)

😊nii转nii.gz

def nii2nii(nii_path, nii_gz_path):
    image = sitk.ReadImage(nii_path)
    sitk.WriteImage(image, nii_gz_path)

😃 nrrd转nii

def nrrd2nii(nrrd_path, nii_path):
    image = sitk.ReadImage(nrrd_path)
    sitk.WriteImage(image, nii_path)

😏jpg转png

def jpg2png(jpg_path, png_path):
    image = io.imread(jpg_path)
    io.imsave(png_path, image)

😍将图像打patches块

用于将大图像及其相应的掩膜(mask)分割为多个1024x1024的小图块(也称为“patches”)。

过程

函数定义:四个参数分别为:要分割的图像、相应的掩膜、输出路径以及基础文件名。
创建输出目录:在输出路径下创建两个目录:一个存放图像的小图块,另一个存放掩膜的小图块。
大小检查:检查图像和掩膜的大小是否匹配。
图像和掩膜的填充:如果图像或掩膜的高度或宽度不是1024的倍数,将它们填充到最近的1024的倍数。
分割图像和掩膜:计算在垂直和水平方向上需要分割的步数。对于每个步骤,从图像和掩膜中提取1024x1024的小图块。保存每个小图块到指定的输出目录。

def patchfy(img, mask, outpath, basename):
    # 定义存放图像和掩膜小图块的目录
    image_patch_dir = join(outpath, "images")
    mask_patch_dir = join(outpath, "labels")
    
    # 如果目录不存在,则创建它们
    os.makedirs(image_patch_dir, exist_ok=True)
    os.makedirs(mask_patch_dir, exist_ok=True)
    
    # 确保图像和掩膜的前两个维度(即高度和宽度)是相同的
    assert img.shape[:2] == mask.shape
    
    # 定义小图块的高度和宽度为1024x1024
    patch_height = 1024
    patch_width = 1024
    
    # 获取图像和掩膜的高度和宽度
    img_height, img_width = img.shape[:2]
    mask_height, mask_width = mask.shape
    
    # 如果图像的高度不是1024的倍数,则进行填充
    if img_height % patch_height != 0:
        img = np.pad(img, ((0, patch_height - img_height % patch_height), (0, 0), (0, 0)), mode="constant")
    # 如果图像的宽度不是1024的倍数,则进行填充
    if img_width % patch_width != 0:
        img = np.pad(img, ((0, 0), (0, patch_width - img_width % patch_width), (0, 0)), mode="constant")
    # 如果掩膜的高度不是1024的倍数,则进行填充
    if mask_height % patch_height != 0:
        mask = np.pad(mask, ((0, patch_height - mask_height % patch_height), (0, 0)), mode="constant")
    # 如果掩膜的宽度不是1024的倍数,则进行填充
    if mask_width % patch_width != 0:
        mask = np.pad(mask, ((0, 0), (0, patch_width - mask_width % patch_width)), mode="constant")
    
    # 再次确保填充后的图像和掩膜大小相同
    assert img.shape[:2] == mask.shape
    # 确保填充后的图像和掩膜可以被1024整除
    assert img.shape[0] % patch_height == 0
    assert img.shape[1] % patch_width == 0
    assert mask.shape[0] % patch_height == 0
    assert mask.shape[1] % patch_width == 0
    
    # 计算垂直和水平方向上需要的分割步骤
    height_steps = (img_height // patch_height) if img_height % patch_height == 0 else (img_height // patch_height + 1)
    width_steps = (img_width // patch_width) if img_width % patch_width == 0 else (img_width // patch_width + 1)
    
    # 对图像和掩膜进行分割,并保存小图块
    for i in range(height_steps):
        for j in range(width_steps):
            # 提取图像小图块
            img_patch = img[i * patch_height:(i + 1) * patch_height, j * patch_width:(j + 1) * patch_width, :]
            # 提取掩膜小图块
            mask_patch = mask[i * patch_height:(i + 1) * patch_height, j * patch_width:(j + 1) * patch_width]
            
            # 确保图像和掩膜小图块的大小相同,并且都是1024x1024
            assert img_patch.shape[:2] == mask_patch.shape
            assert img_patch.shape[0] == patch_height
            assert img_patch.shape[1] == patch_width
            
            # 显示小图块的大小(可选)
            print(f"img_patch.shape: {img_patch.shape}, mask_patch.shape: {mask_patch.shape}")
            
            # 定义图像和掩膜小图块的保存路径
            img_patch_path = join(image_patch_dir, f"{basename}_{i}_{j}.png")
            mask_patch_path = join(mask_patch_dir, f"{basename}_{i}_{j}.png")
            
            # 保存图像和掩膜小图块
            io.imsave(img_patch_path, img_patch)    
            io.imsave(mask_patch_path, mask_patch)


😘将Run-Length Encoding(RLE)转换numpy

用于将Run-Length Encoding(RLE,行程长度编码)格式的掩膜编码转换为一个二维的numpy数组。这种编码方式常用于表示二进制图像,特别是在医学影像分割任务中。

过程

函数定义:rle_decode(mask_rle, img_shape):该函数接受两个参数,mask_rle 是一个用字符串表示的RLE编码,img_shape 是目标图像的形状(高度,宽度)。
初始化:将 mask_rle 字符串通过空格分割,得到一个数字字符串的列表。列表中的偶数索引(从0开始)表示RLE编码的起始点,奇数索引表示该连续区域的长度。
转换:使用numpy数组将起始点和长度转换为整数格式。通过加法计算每个连续区域的结束点。确保起始点和长度的数量是相同的。初始化一个全零的一维numpy数组,其长度等于目标图像的像素总数。遍历每个连续区域,将对应的像素值设置为255(表示掩膜区域)。
重塑:将一维的numpy数组重塑为二维数组,其形状与目标图像相同。使用转置操作(.T)确保数组的形状与预期的图像形状匹配。

def rle_decode(mask_rle, img_shape):
    """
    将RLE编码的掩膜解码为二维numpy数组。
    
    参数:
        mask_rle: RLE编码的掩膜,格式为字符串(起始点和长度交替出现)。
        img_shape: 目标图像的形状(高度,宽度)。
    
    返回:
        一个二维numpy数组,表示解码后的掩膜图像。
    """
    # 将RLE编码字符串通过空格分割
    seq = mask_rle.split()
    
    # 获取所有的起始点(偶数索引)
    starts = np.array(list(map(int, seq[0::2])))
    
    # 获取所有的长度(奇数索引)
    lengths = np.array(list(map(int, seq[1::2])))
    
    # 确保起始点和长度的数量是相同的
    assert len(starts) == len(lengths)
    
    # 计算每个连续区域的结束点
    ends = starts + lengths
    
    # 初始化一个全零的一维数组,长度等于图像的像素总数
    img = np.zeros((np.product(img_shape),), dtype=np.uint8)
    
    # 遍历每个连续区域,设置对应的像素值为255
    for begin, end in zip(starts, ends):
        img[begin:end] = 255
        
    # 将一维数组重塑为二维数组,形状与目标图像相同
    img.shape = img_shape
    
    # 返回转置后的图像,确保其形状与预期的图像形状匹配
    return img.T

在这里插入图片描述

  • 17
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 11
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cv夏一笑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值