如何将8×8×3的图像块展平为长度为64的一维向量
问题原因
你得到长度为192的数组是因为每个切分后的块保留了RGB三个通道,8×8×3=192,直接调用ravel()会将三个通道的所有像素值全部展开,自然不符合你预期的64长度需求。
解决方案
根据你的实际需求,可以选择以下三种实现方式:
方案1:先转灰度图再切块展平
如果你只需要单通道的像素信息,直接在读取图像时转为灰度图,此时每个8×8块只有1个通道,展开后长度正好为64:
import cv2 as cv import numpy as np # 读取图像时直接转为灰度图,形状变为(256, 256) img_one = cv.imread("001.jpg", cv.IMREAD_GRAYSCALE) # 切块逻辑保持不变 blocks = np.array([img_one[i:i+8, j:j+8] for j in range(0,256,8) for i in range(0,256,8)]) # 展开单个块,输出长度为64 flatten_block = blocks[0].ravel()
方案2:保留三通道,单独对指定通道展平
如果你需要保留RGB三通道,仅对单个通道的8×8块做展平,按需提取对应通道的块即可:
img_one = cv.imread("001.jpg") # 默认BGR三通道,形状(256, 256, 3) blocks = np.array([img_one[i:i+8, j:j+8] for j in range(0,256,8) for i in range(0,256,8)]) # 提取第一个块的B通道展开,长度为64,G通道对应索引1,R通道对应索引2 flatten_channel = blocks[0][:, :, 0].ravel()
方案3:高效批量处理(无循环)
如果需要处理大量图像,用numpy内置的滑动窗口视图替代列表推导式,性能提升明显:
img_one = cv.imread("001.jpg", cv.IMREAD_GRAYSCALE) # 生成步长为8的8×8滑动窗口,得到所有块 blocks = np.lib.stride_tricks.sliding_window_view(img_one, (8,8))[::8, ::8].reshape(-1, 8, 8) # 一次性展平所有块,输出形状为(1024, 64),共1024个8×8块 all_flatten_blocks = blocks.reshape(-1, 64)
内容的提问来源于stack exchange,提问作者v_him
相关产品推荐
相关产品推荐

