如何利用numpy reshape消除循环实现图像块均值降采样?
用Numpy向量化操作替代循环实现图像块均值降采样
优化后的代码
import numpy as np from matplotlib import pyplot as plt from PIL import Image as im B = 9 pic = np.array(im.open('portrait.png')) # 裁剪图像,确保宽高都是B的倍数,保留RGB通道 pic = pic[pic.shape[0] % B:, pic.shape[1] % B:, :3] # 向量化实现块均值降采样 h, w, c = pic.shape # 重新调整形状:(块行数, 块内高度, 块列数, 块内宽度, 通道数) blocked = pic.reshape(h // B, B, w // B, B, c) # 在块内的高度和宽度轴上取均值 reduced = blocked.mean(axis=(1, 3)).astype(np.uint8) plt.title(str(reduced.shape)) plt.imshow(reduced) plt.show()
代码解释
- 裁剪图像:和原代码逻辑一致,确保图像的高度和宽度都是
B的整数倍,避免后续分块时出现剩余像素。 - 分块reshape:将原图像的形状
(h, w, c)重新组织为(h//B, B, w//B, B, c),其中:h//B是垂直方向的块数量,B是每个块的高度;w//B是水平方向的块数量,B是每个块的宽度;c是图像的通道数(这里是3,对应RGB)。
- 块内取均值:调用
mean(axis=(1,3)),对每个块的高度轴(轴1)和宽度轴(轴3)计算均值,直接得到每个块对应的单个像素值。 - 类型转换:将均值结果转换为
uint8类型,符合图像像素0-255的取值范围。
优势说明
Numpy的向量化操作基于底层C实现,避免了Python循环的性能开销,处理大图像时效率提升明显,同时代码更简洁易读。
内容的提问来源于stack exchange,提问作者scribe
相关产品推荐
相关产品推荐

