Python启动多进程并行处理数据集--模板--(必须干货,含代码模板)

写在开头:你完全可以按照我的模板实现 python并行处理数据,只有7个步骤

背景:已知数据集中包含5500张图片,每一张图片都需要进行图像处理,使用单线程耗费时间大约45min。因此,单线程是不可能的,这辈子都不可能单线程的。。。

解决办法:使用python中的多进程(真香!

注意:该博客不会说明太多原理性的东西,只会告诉你如何去做,怎么去实现。原理性、底层性的知识出门右拐。

实现步骤:

1、导入相应的库,重点:multiprocessing库

import os
from tqdm import trange                  # 显示进度条
from multiprocessing import cpu_count    # 查看cpu核心数
from multiprocessing import Pool         # 并行处理必备,进程池 

import cv2                                
from PIL import Image, ImageOps
import numpy as np                        
from contrast import ImageContraster     # 自定义图像处理库,忽略

2、定义单线程的工作流函数,换句话说就是单线程需要完成的任务

# 单线程所进行的自定义任务,每个任务可能不同,所以以下代码没有太大的参考价值
def single_worker(List_imgs, src_path, dest_path):
    icter = ImageContraster()
        
    # 注意:
    # 这里使用的是 trange 而不是 range 原因是为了美观
    # trange 会输出一个进度条
    # 当然,你也可以换成 range 函数
    for i in trange(len(List_imgs)):
        if not List_imgs[i].endswith('.jpg'):
            continue
        file = List_imgs[i]
        filepath = os.path.join(src_path, file)
        img = cv2.imread(filepath)
        he_eq_img = icter.enhance_contrast(img, method="HE")
        he_eq_img = np.array(he_eq_img)
        save_he = os.path.join(dest_path, file)
        cv2.imwrite(save_he, he_eq_img)

3、将总数据集进行分割,分割成子数据集

# 忽略
SourceImgs = './data/source/'
HE_path = './data/he_trainval_jpg/'
if not os.path.exists(HE_path):
    os.mkdir(HE_path)

# 以下重点
# 将数据集下的图片名加载到List_imgs中
List_imgs = os.listdir(SourceImgs)
Len_imgs = len(List_imgs)            # 数据集长度
num_cores = cpu_count()              # cpu核心数

if num_cores == 2:    # 双核,将所有数据集分成两个子数据集
    subset1 = List_imgs[:Len_imgs // 2]
    subset2 = List_imgs[Len_imgs // 2:]

    List_subsets = [subset1, subset2]

elif num_cores == 4:  # 四核,将所有数据集分成四个子数据集
    subset1 = List_imgs[:Len_imgs // 4]
    subset2 = List_imgs[Len_imgs // 4: Len_imgs // 2]
    subset3 = List_imgs[Len_imgs // 2: (Len_imgs * 3) // 4]
    subset4 = List_imgs[(Len_imgs * 3) // 4:]

    List_subsets = [subset1, subset2, subset3, subset4]

elif num_cores >= 8:     # 八核以上,将所有数据集分成八个子数据集
    num_cores = 8
    subset1 = List_imgs[:Len_imgs // 8]
    subset2 = List_imgs[Len_imgs // 8: Len_imgs // 4]
    subset3 = List_imgs[Len_imgs // 4: (Len_imgs * 3) // 8]
    subset4 = List_imgs[(Len_imgs * 3) // 8: Len_imgs // 2]
    subset5 = List_imgs[Len_imgs // 2: (Len_imgs * 5) // 8]
    subset6 = List_imgs[(Len_imgs * 5) // 8: (Len_imgs * 6) // 8]
    subset7 = List_imgs[(Len_imgs * 6) // 8: (Len_imgs * 7) // 8]
    subset8 = List_imgs[(Len_imgs * 7) // 8: ]

    List_subsets = [subset1,subset2,subset3,subset4,
                    subset5,subset6,subset7,subset8]

4、开启多线程处理数据

# 开辟进程池,不需要改动
# num_cores为cpu核心数,也就是开启的进程数
p = Pool(num_cores)   

#
# 对每个进程分配工作
for i in range(num_cores):
    #
    # 格式:p.apply_async(task, args=(...))
    # task:当前进程需要进行的任务/函数,只需要填写函数名
    # args:task函数中所需要传入的参数
    # 注意看 List_subsets[i] 就是传入不同的数据子集
    p.apply_async(single_worker, args=(List_subsets[i], SourceImgs, HE_path))

# 当进程完成时,关闭进程池
# 以下两行代码不需要改动
p.close()
p.join()

5、给这篇博客点个赞

6、输出样例

7、

while(1):
    print('亲,觉得对您有帮助的话,请给我点个小赞,谢谢你!')

如果有什么疑惑,欢迎留言。

如果有哪些地方可以进行改进使得程序更加高效,欢迎留言。

  • 22
    点赞
  • 48
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值