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

NumPy拆分图像为16×16子块后如何正确合并还原为原图

图像16x16分块拼接问题解决

问题核心

所有拼接异常、旋转翻转、转张量报错的根源是分块遍历顺序和拼接时的轴变换逻辑不匹配,后续加的旋转、翻转操作属于补丁式修复,没有解决轴顺序的根本问题,还会引入负步长导致PyTorch张量转换失败。

正确实现

numpy存储图像的维度顺序是(垂直方向y, 水平方向x, 通道c),切片im[y:y+16, x:x+16]本身逻辑正确,只需要对齐循环顺序和transpose的轴参数即可,以下是两种可直接运行的方案:

方案1:保留原有分块逻辑,仅修正拼接轴顺序

原有分块代码不需要改动:

import numpy as np
import torch

block = []
for x in range(0, 224, 16):
    for y in range(0, 224, 16):
        block.append(im[y:y+16, x:x+16])
np_block = np.array(block)

该循环是先固定列块位置x,遍历所有行块位置y,因此np_blockreshape为5维后维度含义为(列块数14, 行块数14, 块内y16, 块内x16, 通道3),拼接时调整轴顺序即可,不需要任何旋转翻转操作:

# 轴顺序调整为(行块索引, 块内y坐标, 列块索引, 块内x坐标, 通道)
reshaped_img = np_block.reshape(14,14,16,16,3).transpose(1,2,0,3,4).reshape(224,224,3)
# 直接转张量无报错,图像完全匹配原图
tensor_img = torch.from_numpy(reshaped_img)

方案2:调整分块遍历顺序为行优先(更符合常规编码直觉)

把外层循环改为遍历行块y,内层遍历列块x,切片保持原有正确顺序:

block = []
# 外层遍历垂直方向的块
for y in range(0, 224, 16):
    # 内层遍历水平方向的块
    for x in range(0, 224, 16):
        block.append(im[y:y+16, x:x+16])
np_block = np.array(block)

此时reshape后的5维维度含义为(行块数14, 列块数14, 块内y16, 块内x16, 通道3),拼接代码如下:

reshaped_img = np_block.reshape(14,14,16,16,3).transpose(0,2,1,3,4).reshape(224,224,3)
tensor_img = torch.from_numpy(reshaped_img)

踩坑说明

  • 你之前使用的transpose(0,3,1,2,4)轴参数完全错误,才会导致拼接后图像旋转翻转,后续加np.rot90、np.flip属于错误逻辑上的补丁:这类操作默认返回原数组的视图,步长为负,PyTorch不支持负步长numpy数组转张量,就算加.copy()也会因为底层轴逻辑错误导致视觉效果异常。
  • 你尝试把切片改为im[x:x+16, y:y+16]是错误修改:直接交换了块内的x、y坐标,会导致块内像素位置错乱,自然无法正确衔接。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 08:15:45