You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python中利用multiprocessing加速图片处理循环?

解决Python多进程处理图片返回None及效率问题

问题根源分析

你的多进程代码存在几个关键错误,导致返回None且无法正常工作:

  • 代码结构错误:if __name__ == "__main__": 放在了图片遍历循环内部,且处理函数定义在循环里,子进程无法正确加载这些函数。
  • 无返回值:mask 函数没有返回任何结果,pool.map 会收集每个任务的返回值,自然得到全是None的列表。
  • 共享变量失效:多进程中每个子进程有独立的内存空间,x1、y1、total 这些列表的修改不会同步到主进程,必须通过函数返回值传递结果。
  • 逻辑错误:equation 函数传入的是单个坐标y,x,却调用np.average(y),这是无效操作(单个整数的平均值就是自身),和单进程逻辑不符。
  • 任务拆分错误:[blackMask] *3 是重复处理同一张图的mask,没有批量处理不同图片。

修正后的多进程代码

import numpy as np
import cv2
import os
from multiprocessing import Pool

def process_single_image(img_path):
    # 单张图片处理逻辑
    img = cv2.imread(img_path)
    gry = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    _, blackMask = cv2.threshold(gry, 0, 255, cv2.THRESH_BINARY_INV)
    
    x1 = []
    y1 = []

    def verticle(mask, y, x):
        vertiPixel = 0
        while y < mask.shape[0]:
            if (y + 1) == mask.shape[0]:
                break
            if mask[y + 1][x] == 255:
                vertiPixel += 1
                y += 1
            else:
                break
        return vertiPixel
    
    def horizontal(mask, y, x):
        horiPixel = 0
        while x < mask.shape[1]:
            if (x + 1) == mask.shape[1]:
                break
            if mask[y][x + 1] == 255:
                horiPixel += 1
                x += 1
            else:
                break
        return horiPixel

    for y in range(blackMask.shape[0]):
        for x in range(blackMask.shape[1]):
            if blackMask[y][x] == 255:
                y1.append(verticle(blackMask, y, x))
                x1.append(horizontal(blackMask, y, x))
    
    # 计算最终结果,和单进程逻辑对齐
    avg_x = np.average(x1) if x1 else 0
    avg_y = np.average(y1) if y1 else 0
    a = avg_y * (9.9 / 305)
    c = avg_x * (9.9 / 305)
    final = (a + c) / 2
    return final

if __name__ == "__main__":
    folderDir = "C://Users/ruler/Desktop/testseg/"
    # 收集所有目标图片路径
    image_paths = []
    for allImages in os.listdir(folderDir):
        if allImages.startswith('TRAIN_SET') and allImages.endswith(".bmp"):
            image_paths.append(os.path.join(folderDir, allImages))
    
    # 启动多进程池,进程数默认匹配CPU核心数
    with Pool() as pool:
        # 批量处理所有图片
        results = pool.map(process_single_image, image_paths)
    
    # 将结果写入文件
    with open('readme.txt', 'w') as f:
        for idx, res in enumerate(results, 1):
            f.write(f"图片{idx}处理结果: {res}\n")
    
    print(f"所有图片处理完成,共{len(results)}张")

额外效率优化建议

原单进程的逐像素遍历效率很低,这也是80张图耗时久的核心原因之一,可以用OpenCV的轮廓提取替代手动循环,大幅提升单张图处理速度:

def process_single_image_optimized(img_path):
    img = cv2.imread(img_path)
    gry = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    _, blackMask = cv2.threshold(gry, 0, 255, cv2.THRESH_BINARY_INV)
    
    # 提取黑色区域轮廓,直接获取区域的宽高
    contours, _ = cv2.findContours(blackMask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    
    x1 = []
    y1 = []
    for cnt in contours:
        x, y, w, h = cv2.boundingRect(cnt)
        x1.append(w)  # 水平方向连续像素数等价于轮廓宽度
        y1.append(h)  # 垂直方向连续像素数等价于轮廓高度
    
    avg_x = np.average(x1) if x1 else 0
    avg_y = np.average(y1) if y1 else 0
    a = avg_y * (9.9 / 305)
    c = avg_x * (9.9 / 305)
    final = (a + c) / 2
    return final

这个优化后的函数能比原循环快数倍,结合多进程会让整体处理速度得到质的提升。

内容的提问来源于stack exchange,提问作者user20680514

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 18:45:30