如何使用多处理并行处理OpenCV图像?

问题描述 投票:1回答:2

我在一个文件夹中有一组图像,我想使用一些OpenCV函数进行预处理。功能

detectAndaligncrop

采用使用OpenCV预处理它的图像路径并返回输出图像。我可以使用:

for image_path in files_list:
   cropped_image, _=detectAndaligncrop(im)
   cv2.imwrite("ouput_folder/{}".format(os.path.basename(image_path)),cropped_im*255.)

但是这不起作用:

jobs=[]
for im_no, im in enumerate(files_list):
    p=multiprocessing.Process(target=saveIm,args=[im])
    jobs.append(p)
    p.start()
for j in jobs:
    j.join()

saveIm在哪里:

im,lm=detectAndaligncrop(im_path)
        fname="output_path/cropped2/{}".format(os.path.basename(im_path))
        cv2.imwrite(fname,im)

我已经验证它调用了detectAndaligncrop函数,但是不会从其中的行开始处理图像

gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

在detectAndaligncrop中调用,因为为每个图像调用“before cvtColor”,而“cvtColor之后”不是:

def detectAndaligncrop(impath):
    image=cv2.imread(impath)
    image_float=np.float32(image)/255.0
    print ("before cvtcolor")
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    print ("after cvtcolor")
    return gray, 1

另外,我试过:

with ThreadPoolExecutor(max_workers=32) as execr:
    res=execr.map(saveIm,files_list)

这可以工作但不比简单地运行for循环快。是因为GIL吗?

python multithreading opencv python-multiprocessing
2个回答
0
投票

经过几次实验后发现错误:基本上,错误在于将读取的图像转换为灰度图像的方法。如果我使用:

gray = cv2.imread(impath,0)

代替

image = cv2.imread(impath)
image_float = np.float32(image)/255.0
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

代码工作正常,

也许在MultiProcessing中使用cv2.cvtColor存在一些问题。有人可以说清楚原因。它是关于可挑选性的吗?


-1
投票

在将图像馈送到神经网络之前,我需要一种多处理方法来预处理图像。我遇到了这个名为Embarrassingly parallel for loops的页面,其中数组任务正在并行运行数组/列表中的元素。我想知道这是否可以扩展到图像(毕竟图像只是阵列,大型3D阵列!)

我决定从OpenCV执行add weighted操作到一组图像。使用此操作,您可以对两个图像应用不同的权重并添加它们。它用于混合图像,你可以see here

我使用和不使用joblib为我的桌面上的一组图像执行此功能并比较它们的性能。最后,我提到了图像的数量和这些图像的总体大小。

码:

import os
import time

#--- Importing the required library ---
from joblib import delayed

#--- Choosing all available image formats of images from my desktop ---
path = r'C:\Users\Jackson\Desktop'
img_formats = ['.png', '.jpg', '.jpeg']

#--- Defining the addWeighted function from OpenCV ---
def weight(im):
    addweighted = cv2.addWeighted(im, 0.7, cv2.GaussianBlur(im, (15, 15), 0), 0.3, 0)
    return addweighted


#--- Using joblib library-----
start_time = time.time()

new_dir = os.path.join(path, 'add_Weighted_4_joblib')
if not os.path.exists(new_dir):
    os.makedirs(new_dir)

def joblib_loop():
    for f in os.listdir(path):
        if any(c in f for c in img_formats):
            img = cv2.imread(os.path.join(path, f))
            r = delayed(weight)(img)
            cv2.imwrite(os.path.join(new_dir, f + '_add_weighted_.jpg'), r)

elapsed_time = time.time() - start_time
print('Using Joblib : ', elapsed_time)

#--- Without joblib ---
start_time = time.time()

#--- Check whether directory exists if not make one
new_dir = os.path.join(path, 'add_Weighted_4')
if not os.path.exists(new_dir):
    os.makedirs(new_dir)

for f in os.listdir(path):
    if any(c in f for c in img_formats):
        img = cv2.imread(os.path.join(path, f))
        r = weight(img)
        cv2.imwrite(os.path.join(new_dir, f + '_add_weighted_.jpg'), r)

elapsed_time = time.time() - start_time
print('Without Joblib : ', elapsed_time)

这是我得到的结果:

('Using Joblib : ', 0.09400010108947754)
('Without Joblib : ', 15.386000156402588)

正如你所看到的那样使用joblib加速疯狂的操作!

现在让我向您展示我的桌面上有多少图像以及它们的总大小:

overall_size = 0
count = 0
#for f in os.listdir(path):
for  f in os.listdir(path):
    if any(c in f for c in img_formats):
        img = cv2.imread(os.path.join(path, f))
        overall_size+= img.size
        count+= 1

print('Collective Size of all {} images in the predefined path is {} MB'.format(count, overall_size/10**6))

结果:

Collective size of all 14 images in the predefined path is 58 MB
© www.soinside.com 2019 - 2024. All rights reserved.