scikit-learn的extract_patches_2d支持步长吗?如何实现步长32的图像分块?
解决scikit-learn extract_patches_2d步长设置问题:提取64×64步长32的图像块
嘿,我刚好碰到过一模一样的需求!extract_patches_2d确实默认只能用步长1做密集采样,没法直接设置步长参数,但有两个亲测好用的办法能实现你要的效果,咱们一步步来:
方法一:用skimage.util.view_as_windows(推荐)
scikit-image里的view_as_windows专门支持自定义步长的滑动窗口提取,用法非常直观,而且效率很高。
代码示例(结合你的load_train_data函数):
from skimage.util import view_as_windows def load_train_data(self): imgs_row, imgs_col = 512, 512 patch_size = (64, 64) stride = 32 train_list = [] train_img = [] label_list = [] label_img = [] # 假设你已经加载了单通道灰度图,形状为(512,512) # 如果是RGB图,形状是(512,512,3),只需把patch_size改成(64,64,3)即可 for img in your_train_images: # 替换成你的图像加载逻辑 # 生成带步长的窗口 patches = view_as_windows(img, window_shape=patch_size, step=stride) # 把形状从(行数, 列数, 64, 64)转换成(N, 64, 64),方便后续处理 patches = patches.reshape(-1, *patch_size) train_img.extend(patches) # 标签部分同理处理 # ... 你的其他逻辑
这个方法会自动计算所有符合条件的块:512×512的图,步长32提取64×64的块,横向和纵向各有(512-64)/32 +1 = 15个,总共15×15=225个块,完全符合需求。
方法二:手动循环切片(无额外依赖)
如果不想引入scikit-image的依赖,也可以手动计算每个块的起始坐标,循环提取,逻辑更透明:
代码示例:
def load_train_data(self): imgs_row, imgs_col = 512, 512 patch_size = 64 stride = 32 train_list = [] train_img = [] label_list = [] label_img = [] for img in your_train_images: # 计算所有x方向的起始坐标 x_starts = range(0, imgs_col - patch_size + 1, stride) # 计算所有y方向的起始坐标 y_starts = range(0, imgs_row - patch_size + 1, stride) for y in y_starts: for x in x_starts: # 提取当前块 patch = img[y:y+patch_size, x:x+patch_size] train_img.append(patch) # 标签部分同理处理 # ... 你的其他逻辑
这个方法和方法一的结果完全一致,只是手动实现了窗口滑动的逻辑,适合需要精细控制的场景。
为什么extract_patches_2d不行?
补充说明一下:sklearn.feature_extraction.image.extract_patches_2d的设计目标是密集采样,它会以步长1遍历整个图像提取所有可能的块,没有提供步长参数的接口,所以如果要自定义步长,就得用上面两种方法啦。
内容的提问来源于stack exchange,提问作者doyle
相关产品推荐
相关产品推荐

