使用Numba加速纯Python嵌套列表操作时遇编译错误求助
基于图像金字塔的图像融合:Numba编译错误解决
问题背景
我被指派实现基于图像金字塔的纯Python图像融合程序,不可使用NumPy但可使用Numba。编写的图像模糊函数中,嵌套列表操作按Numba官方文档应为支持项,但运行时出现编译错误。以下是代码、高斯核定义及报错信息:
模糊函数代码
@jit def blur_image(image: list[list[list[float], kernel: list[list[float]]) -> list[list[list[float]: PADDING: int = 2 height: int = len(image) width: int = len(image[0]) padded_img= create_empty_image(height + 2 * PADDING, width + 2 * PADDING) output_img = create_empty_image(height, width) for i in range(height): for j in range(width): padded_img[i + PADDING][j + PADDING] = image[i][j] for i in range(height): for j in range(width): sum_r: float = 0. sum_g: float = 0. sum_b: float = 0. for k in range(5): for l in range(5): sum_r += kernel[k][l] * padded_img[i + k][j + l][0] sum_g += kernel[k][l] * padded_img[i + k][j + l][1] sum_b += kernel[k][l] * padded_img[i + k][j + l][2] output_img[i][j][0] = min(int(sum_r), 255) output_img[i][j][1] = min(int(sum_g), 255) output_img[i][j][2] = min(int(sum_b), 255) return output_img @jit def create_empty_image(height: int, width: int) -> img_as_list: return [[[0., 0., 0.] for _ in range(width)] for _ in range(height)]
高斯核定义
gaussian_kernel: list[list[float]] = [[1, 4, 6, 4, 1], [4, 16, 24, 16, 4], [6, 24, 36, 24, 6], [4, 16, 24, 16, 4], [1, 4, 6, 4, 1]] # * (1/256.), 归一化操作在其他地方完成
报错信息
Traceback (most recent call last): File "/home/krzysztof/lab5/lab_5.py", line 258, in <module> orange_upscaled = blur_image(orange_copy, gaussian_kernel) File "/home/krzysztof/venv/lib/python3.10/site-packages/numba/core/dispatcher.py", line 487, in _compile_for_args raise e File "/home/krzysztof/venv/lib/python3.10/site-packages/numba/core/dispatcher.py", line 420, in _compile_for_args return_val = self.compile(tuple(argtypes)) File "/home/krzysztof/venv/lib/python3.10/site-packages/numba/core/dispatcher.py", line 1197, in compile cres = compiler.compile_ir(typingctx=self.typingctx, File "/home/krzysztof/venv/lib/python3.10/site-packages/numba/core/compiler.py", line 754, in compile_ir norw_cres = compile_local(func_ir.copy(), norw_flags) File "/home/krzysztof/venv/lib/python3.10/site-packages/numba/core/compiler.py", line 750, in compile_local return pipeline.compile_ir(func_ir=the_ir, lifted=lifted, File "/home/krzysztof/venv/lib/python3.10/site-packages/numba/core/compiler.py", line 462, in compile_ir return self._compile_ir() File "/home/krzysztof/venv/lib/python3.10/site-packages/numba/core/compiler.py", line 527, in _compile_ir return self._compile_core() File "/home/krzysztof/venv/lib/python3.10/site-packages/numba/core/compiler.py", line 499, in _compile_core raise e File "/home/krzysztof/venv/lib/python3.10/site-packages/numba/core/compiler.py", line 486, in _compile_core pm.run(self.state) File "/home/krzysztof/venv/lib/python3.10/site-packages/numba/core/compiler_machinery.py", line 368, in run raise patched_exception File "/home/krzysztof/venv/lib/python3.10/site-packages/numba/core/compiler_machinery.py", line 356, in run self._runPass(idx, pass_inst, state) File "/home/krzysztof/venv/lib/python3.10/site-packages/numba/core/compiler_lock.py", line 35, in _acquire_compile_lock return func(*args, **kwargs) File "/home/krzysztof/venv/lib/python3.10/site-packages/numba/core/compiler_machinery.py", line 318, in _runPass enforce_no_dels(internal_state.func_ir) File "/home/krzysztof/venv/lib/python3.10/site-packages/numba/core/ir_utils.py", line 2194, in enforce_no_dels raise CompilerError(msg, loc=dels[0].loc) numba.core.errors.CompilerError: Failed in object mode pipeline (step: remove phis nodes) Illegal IR, del found at: del $158for_iter.3 File "lab_5.py", line 204: def blur_image(image: img_as_list, kernel: list[list[float]]) -> img_as_list: <source elided> sum_b: float = 0. for k in range(5): ^ Process finished with exit code 1
解决方法
1. 修复函数签名语法错误
原代码中blur_image的类型注解存在括号不匹配问题,导致语法解析异常,间接引发Numba编译错误。正确签名如下:
@njit def blur_image(image: list[list[list[float]]], kernel: list[list[float]]) -> list[list[list[float]]]:
2. 启用Numba的nopython模式
用@njit(等价于@jit(nopython=True))替代@jit,强制进入nopython编译模式。该模式性能更高,且能规避object模式下的IR生成问题。
3. 修正返回类型注解
create_empty_image的返回类型img_as_list若为自定义类型,需确保Numba能识别;若未定义,直接使用list[list[list[float]]]即可。
修正后的完整代码
from numba import njit @njit def blur_image(image: list[list[list[float]]], kernel: list[list[float]]) -> list[list[list[float]]]: PADDING: int = 2 height: int = len(image) width: int = len(image[0]) padded_img = create_empty_image(height + 2 * PADDING, width + 2 * PADDING) output_img = create_empty_image(height, width) # 填充图像边界 for i in range(height): for j in range(width): padded_img[i + PADDING][j + PADDING] = image[i][j] # 高斯卷积计算 for i in range(height): for j in range(width): sum_r = 0.0 sum_g = 0.0 sum_b = 0.0 for k in range(5): for l in range(5): sum_r += kernel[k][l] * padded_img[i + k][j + l][0] sum_g += kernel[k][l] * padded_img[i + k][j + l][1] sum_b += kernel[k][l] * padded_img[i + k][j + l][2] # 限制像素值在0-255范围内 output_img[i][j][0] = min(int(sum_r), 255) output_img[i][j][1] = min(int(sum_g), 255) output_img[i][j][2] = min(int(sum_b), 255) return output_img @njit def create_empty_image(height: int, width: int) -> list[list[list[float]]]: return [[[0.0, 0.0, 0.0] for _ in range(width)] for _ in range(height)]
额外提示
确保高斯核已完成归一化(乘以1/256),否则卷积后的像素值可能超出合理范围,导致图像失真。
内容的提问来源于stack exchange,提问作者KrzysiekDD
相关产品推荐
相关产品推荐

