Python实现2D单通道图像双线性插值遇索引越界问题求解决方向
双线性插值函数索引越界问题排查
功能需求
实现bilinear_interpolation(image,y,x)函数,接收2D矩阵格式的单通道图像,y为图像高度方向像素坐标,x为图像宽度方向像素坐标,返回0~255范围内的插值后像素值。
注意:计算公式中的x、y与函数入参的x、y定义不同,可假设函数接收到的都是合法单通道图像。
输入输出示例
bilinear_interpolation([[0, 64], [128, 255]], 0, 0) → 0 bilinear_interpolation([[0, 64], [128, 255]], 1, 1) → 255 bilinear_interpolation([[0, 64], [128, 255]], 0.5, 0.5) → 112 bilinear_interpolation([[0, 64], [128, 255]], 0.5, 1.5) → 160 assert bilinear_interpolation([[0, 64], [128, 255]], 0.5, 1) == 160 assert bilinear_interpolation([[0, 64], [128, 255]], 0.5, 1.5) == 160 assert bilinear_interpolation([[0, 64], [128, 255]], 0, 1) == 64 assert bilinear_interpolation([[0, 64], [128, 255]], 0, 0) == 0 assert bilinear_interpolation([[0, 64], [128, 255]], 1, 1) == 255 assert bilinear_interpolation([[0, 64], [128, 255]], 0.5, 0.5) == 112 assert bilinear_interpolation([[255, 255], [255, 255]], 0.5, 1.5) == 255 assert bilinear_interpolation([[255, 255], [255, 255]], 0, 1) == 255 assert bilinear_interpolation([[255, 255], [255, 255]], 1.5, 1.5) == 255
现有实现代码
def bilinear_interpolation(image, y, x): xa = math.floor(x) ya = math.floor(y) if(xa >= len(image[0]) and ya >= len(image)): xa = len(image[0]) - 1 ya = len(image) - 1 a = image[ya][xa] elif (xa >= len(image[0]) ): xa = len(image[0]) - 1 a = image[ya][xa] elif (ya >= len(image)): ya = len(image) - 1 a = image[ya][xa] else: a = image[ya][xa] if(ya + 1 >= len(image)): b = image[ya][xa] else: b = image[ya + 1][xa] if (xa + 1 >= len(image[0])): c = image[ya][xa] else: c = image[ya][xa + 1] if(xa + 1 >= len(image[0]) and ya + 1 >= len(image)): d = image[ya][xa] elif (xa + 1 >= len(image[0]) ): d = image[ya + 1][xa] elif (ya+1 >= len(image)): d = image[ya][xa + 1] else: d = image[ya + 1][xa + 1] dx = x - math.floor(x) dy = y - math.floor(y) interpolation_factor = a *( 1 - dx)*(1 - dy) + b * dy * (1 - dx) + c * dx * (1 - dy) + d * dx * dy return round(interpolation_factor)
问题现象
处理460x460这类大尺寸图像矩阵时,总是抛出列表索引越界报错。
排查方向
- 首先检查是否存在输入的x/y为负数的场景:现有代码仅处理了坐标超过图像宽高上限的情况,完全没有处理坐标小于0的场景,floor后的负索引要么读取到错误的像素值,要么直接触发越界报错。
- 其次检查边界判断的覆盖度:现有代码的边界判断分支分散,无法覆盖所有异常组合,比如同时出现x超过上限、y小于0的情况,判断逻辑会进入x超限的分支,直接使用未校验的负y值索引数组,导致越界。
- 建议优化边界裁剪逻辑,将分散的边界判断替换为统一的坐标裁剪,避免遗漏异常情况,参考实现如下:
import math def bilinear_interpolation(image, y, x): h = len(image) w = len(image[0]) # 统一对floor后的坐标做上下限裁剪,保证落在合法索引范围内 xa = max(0, min(math.floor(x), w - 1)) ya = max(0, min(math.floor(y), h - 1)) # 邻域点坐标也做边界裁剪 xb = min(xa + 1, w - 1) yb = min(ya + 1, h - 1) # 直接取四个邻域点 a = image[ya][xa] b = image[yb][xa] c = image[ya][xb] d = image[yb][xb] # 计算插值 dx = x - math.floor(x) dy = y - math.floor(y) res = a * (1 - dx) * (1 - dy) + b * dy * (1 - dx) + c * dx * (1 - dy) + d * dx * dy return round(res)
- 最后排查调用侧传入的坐标范围是否正确,尤其是大图像做坐标缩放计算时,是否存在坐标下溢到负数的情况。
内容的提问来源于stack exchange,提问作者Schevenz Rs
相关产品推荐
相关产品推荐

