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

基于PyTorch向量化实现图像方形区域的选取与拼接

基于PyTorch向量化实现图像方形区域的选取与拼接

你好呀!针对你目前用for循环从PyTorch张量中提取多个方形区域的场景,我来给你分享两种高效的向量化实现方案,既能替代低效的for循环,还能在处理大量区域时大幅提升性能。

先回顾你的原实现

你现在的for循环代码完全能实现需求,但在区域数量多的时候效率会很低:

import torch

image = torch.arange(5*5).reshape(5, 5)

region_size = 2
xmin = torch.tensor([0,1,2])
xmax = xmin + region_size
ymin = torch.tensor([0,0,0])
ymax = ymin + region_size
num_regions = xmin.shape[0]

output = torch.zeros(xmin.shape[0], 2, 2)

for i in range(xmin.shape[0]):
    region = image[xmin[i] : xmax[i], ymin[i] : ymax[i]]
    output[i,...] = region

对应的输入输出:

>>> image
tensor([[ 0,  1,  2,  3,  4],
        [ 5,  6,  7,  8,  9],
        [10, 11, 12, 13, 14],
        [15, 16, 17, 18, 19],
        [20, 21, 22, 23, 24]])

>>> output
tensor([[[ 0.,  1.],
         [ 5.,  6.]],

        [[ 5.,  6.],
         [10., 11.]],

        [[10., 11.],
         [15., 16.]]])

向量化解决方案

下面两种方法都是纯PyTorch向量化操作,没有任何显式for循环,效率拉满:

方法1:用torch.unfold(最简洁高效,推荐)

unfold是PyTorch专门为提取固定尺寸窗口块设计的函数,内部是C++优化实现,速度极快,尤其适合这种等尺寸区域提取的场景:

import torch

image = torch.arange(5*5).reshape(5, 5)
region_size = 2
xmin = torch.tensor([0,1,2])
ymin = torch.tensor([0,0,0])

# 先把2D图像转成unfold需要的4D格式:(batch, channel, height, width)
image_4d = image.unsqueeze(0).unsqueeze(0)
# 分别在高度、宽度维度提取窗口块
# 高度维度unfold:窗口大小region_size,步长1(可根据你的需求调整)
patches_h = image_4d.unfold(2, region_size, 1)
# 宽度维度unfold:窗口大小region_size,步长1
patches = patches_h.unfold(3, region_size, 1)
# 现在patches形状是:(1, 1, 高度方向窗口数, 宽度方向窗口数, region_size, region_size)

# 根据xmin和ymin选取我们需要的区域
selected_patches = patches[0, 0, xmin, ymin]
# 转成float类型和原输出对齐
output = selected_patches.float()

方法2:构造坐标网格(更灵活,支持任意位置区域)

如果你的区域位置不是连续滑动的,而是随机分布的,这种方法更灵活,通过构造每个区域的所有像素坐标,用高级索引一次性提取:

import torch

image = torch.arange(5*5).reshape(5, 5)
region_size = 2
xmin = torch.tensor([0,1,2])
ymin = torch.tensor([0,0,0])
num_regions = xmin.shape[0]

# 构造每个区域的x坐标网格:形状(num_regions, region_size, region_size)
x_coords = xmin.unsqueeze(1).unsqueeze(2) + torch.arange(region_size).unsqueeze(0).unsqueeze(0)
# 构造每个区域的y坐标网格:形状(num_regions, region_size, region_size)
y_coords = ymin.unsqueeze(1).unsqueeze(2) + torch.arange(region_size).unsqueeze(0).unsqueeze(0)

# 用高级索引一次性提取所有区域
output = image[x_coords, y_coords].float()

结果验证

运行上述任意一种方法,得到的output和你用for循环得到的结果完全一致:

print(output)
# 输出:
tensor([[[ 0.,  1.],
         [ 5.,  6.]],

        [[ 5.,  6.],
         [10., 11.]],

        [[10., 11.],
         [15., 16.]]])

为什么向量化更快?

PyTorch的向量化操作会把计算任务批量丢给CPU/GPU的并行计算单元处理,而for循环是串行执行每个区域的提取,当区域数量达到几千、几万时,向量化方法的速度会是for循环的几十甚至上百倍,尤其在GPU上差距更明显。


备注:内容来源于stack exchange,提问作者codebanjo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.16 11:54:34