求基于像素组最大值的图像掩码缩小方案(含OpenCV报错)
问题描述
需要对由0和1组成的二维数组掩码执行缩小操作,规则为:低分辨率掩码中的每个像素,若其对应的原始高分辨率掩码像素组中至少包含一个1,则该像素设为1。
尝试使用OpenCV的cv2.resize()并指定cv2.INTER_MAX插值方法,出现如下错误:
error: OpenCV(4.6.0) /io/opencv/modules/imgproc/src/resize.cpp:3927: error: (-5:Bad argument) Unknown interpolation method in function 'resize'
同时Pillow Image或scipy中也没有对应此规则的插值方法,因此需要自定义shrink_max()函数,示例如下:
>>> orig_mask = [[1,0,0],[0,0,0],[0,0,0]] >>> orig_mask [[1,0,0] ,[0,0,0] ,[0,0,0]] >>> mini_mask = shrink_max(orig_mask, (2,2)) >>> mini_mask [[1,0] ,[0,0]] >>> mini_mask = shrink_max(orig_mask, (1,1)) >>> mini_mask [[1]]
解决方案:自定义shrink_max函数实现
基于numpy实现高效的分块取最大值逻辑,完全匹配需求规则:
import numpy as np def shrink_max(orig_mask, target_size): # 将输入列表转为numpy数组 arr = np.array(orig_mask, dtype=np.int32) orig_h, orig_w = arr.shape target_h, target_w = target_size # 计算每个目标像素对应的原始块尺寸 block_h = orig_h // target_h block_w = orig_w // target_w # 分块并取每个块的最大值(1代表块内有1,0代表全0) shrunk_arr = arr.reshape(target_h, block_h, target_w, block_w).max(axis=(1, 3)) # 转换回列表格式返回 return shrunk_arr.tolist()
测试示例
orig_mask = [[1,0,0],[0,0,0],[0,0,0]] print(shrink_max(orig_mask, (2,2))) # 输出 [[1, 0], [0, 0]] print(shrink_max(orig_mask, (1,1))) # 输出 [[1]]
兼容非整数倍尺寸的版本
如果需要处理原始尺寸无法被目标尺寸整除的场景(比如原始4x5转2x2),可以添加填充逻辑:
import numpy as np def shrink_max(orig_mask, target_size): arr = np.array(orig_mask, dtype=np.int32) orig_h, orig_w = arr.shape target_h, target_w = target_size # 向上取整计算块尺寸 block_h = (orig_h + target_h - 1) // target_h block_w = (orig_w + target_w - 1) // target_w # 填充数组到可被块尺寸整除的大小(用0填充) pad_h = (block_h * target_h) - orig_h pad_w = (block_w * target_w) - orig_w padded_arr = np.pad(arr, ((0, pad_h), (0, pad_w)), mode='constant') # 分块取最大值 shrunk_arr = padded_arr.reshape(target_h, block_h, target_w, block_w).max(axis=(1, 3)) return shrunk_arr.tolist()
内容的提问来源于stack exchange,提问作者Frogrammer
相关产品推荐
相关产品推荐

