You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何计算适配skimage.view_as_windows函数的图像目标尺寸?

解决方法:计算适配view_as_windows的图像目标尺寸

我来帮你梳理通用的计算逻辑,不管步长s是不是等于窗口边长p,都能算出需要调整到的目标图像尺寸。

核心思路与公式

skimage.view_as_windows要求滑动窗口时,最后一个窗口的结束位置不能超出图像边界。换句话说,对于图像的每个维度(高度/宽度),必须满足:

目标维度D减去窗口大小w后,结果是步长s的非负整数倍,且D >= w

基于这个要求,我们可以推导出通用的目标维度计算公式:

# 对单个维度d(原高度/宽度),窗口大小w,步长s
import math

if d < w:
    # 原维度比窗口小,直接扩展到窗口大小
    D = w
else:
    # 计算(d - w)需要向上取整到s的倍数,再加窗口大小
    num_required_steps = math.ceil((d - w) / s)
    D = w + num_required_steps * s

或者用更简洁的整数除法写法(等价于向上取整):

D = w + ((d - w + s - 1) // s) * s

公式推导说明

我们的目标是找到大于等于原维度d的最小D,让(D - w)能被s整除:

  1. 如果原维度d本身就满足条件(d >=w(d-w)%s ==0),直接用d即可;
  2. 如果d <w,必须扩展到w——否则窗口都无法完整放入图像;
  3. 如果d >=w(d-w)不是s的倍数,需要补充s - ((d -w) % s)个像素,让(D -w)刚好是s的整数倍。

完整代码实现

这里推荐用np.pad代替img.resize——因为resize会拉伸/压缩像素改变原图内容,而pad只是在边缘补充像素(比如零、镜像),更符合滑动窗口的需求:

import math
import numpy as np
from skimage.util import view_as_windows

def adjust_image_for_windows(img, window_size, step):
    # 处理单通道/多通道图像的shape
    if len(img.shape) == 3:
        height, width, depth = img.shape
    else:
        height, width = img.shape
        depth = None
    
    w = window_size
    s = step
    
    # 计算目标高度和宽度
    target_h = w + ((height - w + s - 1) // s) * s
    target_w = w + ((width - w + s - 1) // s) * s
    
    # 计算需要补充的像素数,执行补边
    pad_h = target_h - height
    pad_w = target_w - width
    
    if pad_h > 0 or pad_w > 0:
        pad_config = ((0, pad_h), (0, pad_w))
        if depth is not None:
            pad_config += ((0, 0),)
        # 这里用constant补零,你可以换成reflect/symmetric等补边模式
        img_adjusted = np.pad(img, pad_config, mode='constant')
        return img_adjusted
    else:
        return img

# 测试你的两个示例
# 示例1:(5,5)图像,window(4,4),step=2
img1 = np.random.rand(5,5)
adjusted1 = adjust_image_for_windows(img1, 4, 2)
print(f"示例1调整后尺寸:{adjusted1.shape}")  # 输出(6,6),符合需求

# 示例2:(5,5)图像,window(3,3),step=2
img2 = np.random.rand(5,5)
adjusted2 = adjust_image_for_windows(img2, 3, 2)
print(f"示例2调整后尺寸:{adjusted2.shape}")  # 输出(5,5),符合需求

# 验证滑动窗口是否正常工作
windows1 = view_as_windows(adjusted1, (4,4), step=2)
windows2 = view_as_windows(adjusted2, (3,3), step=2)
print(f"示例1窗口shape:{windows1.shape}")  # 输出(1,1,4,4)
print(f"示例2窗口shape:{windows2.shape}")  # 输出(2,2,3,3)

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

火山引擎 最新活动