You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python实现生物医学大图像分块切片与拼接(无信息损失)

大IHC图像通道分离的分块处理方案

针对大图像处理时的内存不足问题,我们可以通过分块处理的方式,将图像切割成小切片逐一处理,最后拼接回完整图像。以下是适配原scikit-image通道分离逻辑的完整实现:

完整代码实现

import numpy as np
import matplotlib.pyplot as plt
from skimage import data
from skimage.color import rgb2hed, hed2rgb
from skimage.exposure import rescale_intensity

def split_image_into_blocks(image, block_size=(512, 512)):
    """将图像分割成指定大小的非重叠块"""
    height, width = image.shape[:2]
    blocks = []
    # 遍历所有块的起始坐标
    for y in range(0, height, block_size[0]):
        for x in range(0, width, block_size[1]):
            # 处理边缘块(如果图像尺寸不是块大小的整数倍)
            y_end = min(y + block_size[0], height)
            x_end = min(x + block_size[1], width)
            block = image[y:y_end, x:x_end]
            blocks.append((y, x, y_end, x_end, block))
    return blocks

def process_block(block, h_percentile, d_percentile):
    """对单个图像块执行通道分离和伪荧光转换"""
    # 通道分离
    ihc_hed = rgb2hed(block)
    null = np.zeros_like(ihc_hed[:, :, 0])
    
    # 原代码的单通道RGB可视化(可选,若不需要可注释)
    ihc_h = hed2rgb(np.stack((ihc_hed[:, :, 0], null, null), axis=-1))
    ihc_e = hed2rgb(np.stack((null, ihc_hed[:, :, 1], null), axis=-1))
    ihc_d = hed2rgb(np.stack((null, null, ihc_hed[:, :, 2]), axis=-1))
    
    # 基于全局统计的强度缩放,生成伪荧光图
    h = rescale_intensity(ihc_hed[:, :, 0], out_range=(0, 1),
                          in_range=(0, h_percentile))
    d = rescale_intensity(ihc_hed[:, :, 2], out_range=(0, 1),
                          in_range=(0, d_percentile))
    zdh_block = np.dstack((null, d, h))
    
    return zdh_block, ihc_h, ihc_e, ihc_d

def main():
    # 替换为你的大图像加载代码,例如用skimage.io.imread
    # 这里用示例图像模拟大图像(可以重复拼接成更大的图)
    ihc_rgb = data.immunohistochemistry()
    # 模拟大图像:(2048, 2048, 3)
    ihc_rgb_large = np.tile(ihc_rgb, (4, 4, 1))
    height, width = ihc_rgb_large.shape[:2]
    block_size = (512, 512)
    
    # --------------------------
    # 步骤1:全局统计H和D通道的99百分位数
    # --------------------------
    h_values = []
    d_values = []
    blocks = split_image_into_blocks(ihc_rgb_large, block_size)
    for _, _, _, _, block in blocks:
        hed_block = rgb2hed(block)
        h_values.append(hed_block[:, :, 0].flatten())
        d_values.append(hed_block[:, :, 2].flatten())
    # 计算全局99百分位数
    h_percentile = np.percentile(np.concatenate(h_values), 99)
    d_percentile = np.percentile(np.concatenate(d_values), 99)
    
    # --------------------------
    # 步骤2:分块处理并初始化结果图像
    # --------------------------
    zdh_result = np.zeros_like(ihc_rgb_large, dtype=np.float64)
    # 若需要保存单通道可视化结果,可初始化对应的数组
    ihc_h_result = np.zeros_like(ihc_rgb_large, dtype=np.float64)
    ihc_e_result = np.zeros_like(ihc_rgb_large, dtype=np.float64)
    ihc_d_result = np.zeros_like(ihc_rgb_large, dtype=np.float64)
    
    for y, x, y_end, x_end, block in blocks:
        zdh_block, ihc_h_block, ihc_e_block, ihc_d_block = process_block(block, h_percentile, d_percentile)
        # 将处理后的块放回结果图像对应位置
        zdh_result[y:y_end, x:x_end] = zdh_block
        ihc_h_result[y:y_end, x:x_end] = ihc_h_block
        ihc_e_result[y:y_end, x:x_end] = ihc_e_block
        ihc_d_result[y:y_end, x:x_end] = ihc_d_block
    
    # --------------------------
    # 步骤3:可视化结果(可选)
    # --------------------------
    fig, axes = plt.subplots(2, 3, figsize=(12, 8))
    ax = axes.ravel()
    
    ax[0].imshow(ihc_rgb_large)
    ax[0].set_title("Original Large Image")
    ax[0].axis('off')
    
    ax[1].imshow(ihc_h_result)
    ax[1].set_title("Hematoxylin")
    ax[1].axis('off')
    
    ax[2].imshow(ihc_e_result)
    ax[2].set_title("Eosin")
    ax[2].axis('off')
    
    ax[3].imshow(ihc_d_result)
    ax[3].set_title("DAB")
    ax[3].axis('off')
    
    ax[4].imshow(zdh_result)
    ax[4].set_title("Pseudofluorescent (D+G)")
    ax[4].axis('off')
    
    ax[5].axis('off')
    
    fig.tight_layout()
    plt.show()

if __name__ == "__main__":
    main()

关键逻辑说明

  • 分块函数:split_image_into_blocks 将大图像切割成指定大小的非重叠块,自动处理边缘不足一个块的情况,避免遗漏像素。
  • 全局百分位数统计:先遍历所有块收集H和D通道的像素值,计算全局99百分位数,确保单块处理时的强度缩放和整图处理结果一致,避免出现块间亮度差异。
  • 单块处理:process_block 复用原代码的通道分离和伪荧光转换逻辑,仅针对单个块操作,大幅降低内存占用。
  • 结果拼接:初始化和原图像尺寸一致的结果数组,将每个处理好的块放回对应坐标位置,最终得到完整的处理后图像。

注意事项

  • 可根据你的内存情况调整 block_size,内存充足可设大一点,内存紧张则设小。
  • 若不需要单通道的RGB可视化结果,可以注释掉对应代码,进一步节省内存。
  • 加载大图像时建议用 skimage.io.imread 或 PIL.Image.open 配合逐块读取(如果图像格式支持),避免一次性加载整图。

内容的提问来源于stack exchange,提问作者Burgera

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 09:27:37