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

Python中分割任意尺寸(H,W,C)图像为(224,224,3)子图及原图重建方法咨询

刚好做过类似的需求,给你一套从图像分割到重建的完整实现方案,都是实战能用的代码和思路👇

一、图像分割:生成224x224子图

首先得明确Z的计算方式,这取决于你选择的分割策略(无重叠/有重叠):

1. 分割策略与Z的计算

  • 无重叠分割:子图紧密排列,仅在边界处可能取最后224像素(如果原图尺寸不是224的整数倍)
    行数 = ceil(H / 224),列数 = ceil(W / 224),Z = 行数 × 列数
  • 有重叠分割:子图之间有重叠区域,步长stride设为小于224的数值(比如112=224/2,重叠率50%)
    行数 = ceil((H - 224) / stride) + 1,列数 = ceil((W - 224) / stride) + 1,Z = 行数 × 列数

2. 分割代码实现(Python+OpenCV)

这个函数会自动处理边界情况,同时记录每个子图的左上角坐标(用于后续重建):

import cv2
import numpy as np

def split_image(img, patch_size=224, stride=224):
    H, W, C = img.shape
    patches = []
    patch_info = []  # 存储每个子图的左上角(x,y)坐标,重建必备!
    
    # 遍历完整的行和列
    for y in range(0, H - patch_size + 1, stride):
        for x in range(0, W - patch_size + 1, stride):
            patch = img[y:y+patch_size, x:x+patch_size, :]
            patches.append(patch)
            patch_info.append((x, y))
    
    # 处理最后一行的剩余区域(如果高度不能被步长整除)
    if H % stride != 0:
        y = H - patch_size
        for x in range(0, W - patch_size + 1, stride):
            patch = img[y:y+patch_size, x:x+patch_size, :]
            patches.append(patch)
            patch_info.append((x, y))
    
    # 处理最后一列的剩余区域(如果宽度不能被步长整除)
    if W % stride != 0:
        # 先处理前面完整的行
        for y in range(0, H - patch_size + 1, stride):
            x = W - patch_size
            patch = img[y:y+patch_size, x:x+patch_size, :]
            patches.append(patch)
            patch_info.append((x, y))
        # 处理右下角的最后一个子图(如果行列都有剩余)
        if H % stride != 0:
            x = W - patch_size
            y = H - patch_size
            patch = img[y:y+patch_size, x:x+patch_size, :]
            patches.append(patch)
            patch_info.append((x, y))
    
    Z = len(patches)
    return patches, patch_info, Z
二、子图处理后的图像重建

重建的核心是根据子图的位置信息,把处理后的子图放回原位置,如果有重叠区域,需要做融合处理避免拼接痕迹。

1. 通用重建代码(支持无重叠/有重叠)

这个方法用加权平均处理重叠区域,能自然消除拼接缝隙:

def reconstruct_image(processed_patches, patch_info, original_shape, patch_size=224):
    H, W, C = original_shape
    # 创建画布和权重映射(用于重叠区域加权)
    recon_img = np.zeros((H, W, C), dtype=np.float32)
    weight_map = np.zeros((H, W), dtype=np.float32)
    
    # 把每个处理后的子图放回对应位置,累加像素值和权重
    for patch, (x, y) in zip(processed_patches, patch_info):
        recon_img[y:y+patch_size, x:x+patch_size] += patch
        weight_map[y:y+patch_size, x:x+patch_size] += 1
    
    # 避免除以0的情况(比如补边区域,不过我们的分割函数已经处理了边界)
    weight_map[weight_map == 0] = 1
    # 加权平均得到最终图像
    recon_img = recon_img / weight_map[..., np.newaxis]
    # 转换回图像的uint8格式
    recon_img = np.clip(recon_img, 0, 255).astype(np.uint8)
    
    return recon_img

2. 使用示例

# 读取原图
img = cv2.imread("your_image.jpg")
original_shape = img.shape

# 分割(这里用50%重叠率,步长112)
patches, patch_info, Z = split_image(img, stride=112)

# 这里模拟子图处理过程:比如对每个子图做分类/增强等操作
processed_patches = [cv2.cvtColor(p, cv2.COLOR_BGR2GRAY)[..., np.newaxis] for p in patches]
# 注意:处理后的子图必须保持224x224x3(或和原图通道数一致),如果改变了尺寸要先resize回去

# 重建图像
reconstructed_img = reconstruct_image(processed_patches, patch_info, original_shape)

# 保存结果
cv2.imwrite("reconstructed_image.jpg", reconstructed_img)
三、关键注意事项
  • 必须保存位置信息:patch_info是重建的核心,没有它你根本不知道每个子图该放回哪里
  • 保持子图尺寸一致:如果你的处理流程改变了子图大小(比如模型输出不是224x224),一定要先用cv2.resize把处理后的子图变回224x224再重建
  • 通道数匹配:如果原图是灰度图(C=1),要调整代码里的通道处理逻辑,避免维度不匹配
  • 重叠步长选择:步长越小,重叠率越高,子图数量Z越多,但重建后的细节保留越好(适合处理过程中丢失信息的场景,比如深度学习推理)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 09:37:47