如何在Python中用多进程优化OpenCV循环以对比运行速度?
多进程版本图像对比度亮度调整实现
要将你的calculation_multi改造成真正的多进程版本,核心思路是将图像按行分割,分配给不同CPU核心并行处理,避免单进程循环的低效。以下是完整实现及关键说明:
完整代码
import cv2 as cv import numpy as np import time import multiprocessing # 配置参数 kontrast = 1.5 # 对比度系数 jasnosc = 30 # 亮度偏移值 image = cv.imread("你的图像路径.jpg") # 替换为实际图像路径 def process_rows(row_range): """单个进程负责处理指定范围的图像行""" start_y, end_y = row_range # 提取待处理的行块 img_block = image[start_y:end_y, :, :] # 计算对比度和亮度调整 processed_block = np.clip(kontrast * img_block + jasnosc, 0, 255) # 返回起始行号和处理后的块,用于主进程拼接 return start_y, processed_block def calculation_multi(): print("multi") start = time.time() cpu_count = multiprocessing.cpu_count() rows_total = image.shape[0] # 按CPU核心数分割行区间 rows_per_process = rows_total // cpu_count row_ranges = [] for i in range(cpu_count): start_row = i * rows_per_process # 最后一个进程处理剩余所有行,避免遗漏 end_row = start_row + rows_per_process if i != cpu_count - 1 else rows_total row_ranges.append((start_row, end_row)) # 初始化结果图像 new_image = np.zeros_like(image) # 创建进程池并分配任务 with multiprocessing.Pool(processes=cpu_count) as pool: results = pool.map(process_rows, row_ranges) # 将各进程返回的处理块拼接成完整图像 for start_y, block in results: new_image[start_y:start_y + block.shape[0], :, :] = block end = time.time() print(f"{end - start} z multiprocessing na {cpu_count} rdzenie") return new_image def calculation_single(): """原单进程版本(保留你的三层循环逻辑,用于速度对比)""" print("single") start = time.time() new_image = np.zeros_like(image) for y in range(image.shape[0]): for x in range(image.shape[1]): for c in range(image.shape[2]): new_image[y,x,c] = np.clip(kontrast*image[y,x,c] + jasnosc, 0, 255) end = time.time() print(f"{end - start} z singleprocessing") return new_image if __name__ == '__main__': # 运行多进程和单进程版本 img_multi = calculation_multi() img_single = calculation_single() # 显示结果 cv.imshow('Oryginal', image) cv.imshow('Nowy obraz (multi)', img_multi) cv.imshow('Nowy obraz (single)', img_single) cv.waitKey(0) cv.destroyAllWindows()
关键说明
- 进程任务分割:按CPU核心数将图像行划分为多个区间,每个进程独立处理一个区间,最大化利用多核资源。
- 避免全局变量共享问题:多进程中全局变量会被每个进程复制,无法直接共享修改。这里让每个进程返回处理后的行块,主进程再拼接结果,确保数据正确。
- 进程池管理:使用
multiprocessing.Pool自动处理进程的创建、任务分配和回收,无需手动管理进程生命周期。 - 速度对比注意:
- 若想对比单进程最优速度,可将
calculation_single替换为numpy广播实现:new_image = np.clip(kontrast * image + jasnosc, 0, 255),这比三层循环快几十倍。 - 小尺寸图像可能体现不出多进程优势,因为进程创建和数据传输的开销会抵消并行收益,适合大尺寸图像测试。
- 若想对比单进程最优速度,可将
内容的提问来源于stack exchange,提问作者gfoxi
相关产品推荐
相关产品推荐

