求助优化Python中三层嵌套循环实现的代价体积计算代码
优化基于汉明距离的代价体积计算代码
你的代码核心是计算左右图像对应位置的汉明距离(异或结果的二进制1的个数)并构建代价体积,但三层Python嵌套循环的执行效率极低——Python解释器处理循环的开销远高于C级别的向量化操作。以下是几种高效优化方案,从易到难,适配不同技术基础:
方案1:Numba JIT编译(改动最小,适合Python基础有限的场景)
只需给原代码添加Numba即时编译装饰器,就能把Python循环转化为机器码执行,同时支持多线程并行,速度能提升几十到上百倍。
先安装依赖:pip install numba
优化后代码:
import numpy as np from numba import njit, prange @njit(parallel=True) def calculate_cost_numba(left_image_ct, right_image_ct, max_disparity, left=True): h, w = left_image_ct.shape # 直接初始化全inf的数组,省去边界判断后重复赋值inf的操作 cost_volume = np.full((max_disparity, h, w), np.inf, dtype=np.float64) for i in prange(h): # prange启用多线程并行处理行 for j in range(w): for d in range(max_disparity): x_right = j - d if left else j + d if 0 <= x_right < w: xor_val = left_image_ct[i, j] ^ right_image_ct[i, x_right] cost_volume[d, i, j] = bin(xor_val).count('1') return cost_volume
关键优化点:
@njit(parallel=True):将函数编译为机器码,prange自动把行循环分配到多个CPU核心并行执行- 用
np.full初始化全inf数组,减少冗余操作
方案2:NumPy向量化操作(纯numpy实现,无额外依赖)
把循环逻辑转化为numpy的广播和切片操作,利用numpy的C级内核加速,避免显式循环。
优化后代码:
import numpy as np def calculate_cost_vectorized(left_image_ct, right_image_ct, max_disparity, left=True): h, w = left_image_ct.shape # 初始化全inf的代价体积 cost_volume = np.full((max_disparity, h, w), float('inf'), dtype=np.float32) for d in range(max_disparity): if left: # 右图像向右偏移d像素,左边补0,仅保留与左图像对齐的有效列 right_shifted = np.pad(right_image_ct, ((0,0), (d,0)), mode='constant')[:, :w] valid_cols = slice(d, None) # 有效列范围:从d到末尾 else: # 右图像向左偏移d像素,右边补0,仅保留与左图像对齐的有效列 right_shifted = np.pad(right_image_ct, ((0,0), (0,d)), mode='constant')[:, d:] valid_cols = slice(None, -d) # 有效列范围:从开头到倒数第d列 # 计算异或并统计二进制1的个数(汉明距离) xor_result = left_image_ct ^ right_shifted # numpy 1.20+支持bit_count,效率最高;旧版本用unpackbits兼容 if hasattr(np, 'bit_count'): hamming_dist = np.bit_count(xor_result.astype(np.uint64)) else: hamming_dist = np.unpackbits(xor_result.view(np.uint8), axis=-1).sum(axis=-1) # 仅对有效区域赋值,其余保持inf cost_volume[d, :, valid_cols] = hamming_dist[:, valid_cols] return cost_volume
关键优化点:
- 仅保留视差d的循环,整幅图像的偏移、异或、汉明距离计算都用numpy向量化操作完成
- 通过切片和padding处理边界,避免逐像素判断
- 用
np.bit_count或np.unpackbits高效计算二进制1的个数,替代原代码中bin().count('1')的低效字符串操作
方案3:验证与性能测试
可以用以下代码测试优化后代码的正确性和速度:
if __name__ == "__main__": # 生成测试用随机图像 h, w = 480, 640 max_disp = 64 left_img = np.random.randint(0, 256, (h, w), dtype=np.uint8) right_img = np.random.randint(0, 256, (h, w), dtype=np.uint8) import time # 测试Numba版本 start = time.time() cost_numba = calculate_cost_numba(left_img, right_img, max_disp) print(f"Numba版本耗时: {time.time() - start:.2f}s") # 测试向量化版本 start = time.time() cost_vectorized = calculate_cost_vectorized(left_img, right_img, max_disp) print(f"向量化版本耗时: {time.time() - start:.2f}s") # 验证结果一致性 print("结果是否一致:", np.allclose(cost_numba, cost_vectorized, rtol=1e-6))
内容的提问来源于stack exchange,提问作者Straw User
相关产品推荐
相关产品推荐

