写在开头:你完全可以按照我的模板实现 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('亲,觉得对您有帮助的话,请给我点个小赞,谢谢你!')
如果有什么疑惑,欢迎留言。
如果有哪些地方可以进行改进使得程序更加高效,欢迎留言。