首页 > 解决方案 > 带有while循环和共享资源的Python多处理

问题描述

我是编程新手,我似乎无法弄清楚如何正确优化我的项目,我有一个函数需要 2 张图像并使用 opencv 将图像拼接在一起。此过程通常需要 0.5 秒才能将每个图像拼接在一起,我想对此进行优化,以便图像以更快的速度拼接在一起。

因此,目前我有 2 个数组,每个数组包含 800 张图像,我还有一个名为stitch_images 的函数,它处理要拼接在一起的每个图像集。但是,对于这个函数,我使用 while 循环遍历每个图像并将其缝合到相应的图像上——这似乎导致了我的问题,因为 while 循环阻塞了进程。我还使用了 2 个包含图像的共享全局变量。

理论上我想要实现的是 4 个进程,每个进程进程获取一组图像并对其进行处理 --> 有效地将计算时间减少了 1/4。

我的问题是,我将如何实现这一目标?我知道在 python 中有多种不同的多处理方式,例如线程、多进程、队列。哪个对我来说是最好的选择?如果有一种简单的方法可以实现这一点,有人会有任何示例代码吗?

这是我目前的设置:

import multiprocessing
import time
import cv2

# Global variables:
frames_1 = []
frames_2 = []
panorama = []


# converting the video into frames for individual image processing
def convert_video_to_frames():
    cap = cv2.VideoCapture("Sample_video_1.mp4")
    ret = True
    while ret:
        ret, img = cap.read()  # read one frame from the 'capture' object; img is (H, W, C)
        if ret:
            frames_1.append(img)

    cap = cv2.VideoCapture("Sample_video_2.mp4")
    ret = True
    while ret:
        ret, img = cap.read()  # read one frame from the 'capture' object; img is (H, W, C)
        if ret:
            frames_2.append(img)

    return frames_1, frames_2


#converting final output images back to video
def convert_frames_to_video():
    print("now creating stitched image video")
    height, width, layers = panorama[0].shape
    size = (width, height)
    out = cv2.VideoWriter('project.avi', cv2.VideoWriter_fourcc(*'DIVX'), 15, size)
    for i in range(len(panorama)):
        out.write(panorama[i])
    out.release()


def stitch_images():
    print("image processing starting...")
    stitcher = cv2.Stitcher_create(cv2.STITCHER_PANORAMA)
    while len(frames_1) != 0:
        status, result = stitcher.stitch((frames_1.pop(0), frames_2.pop(0)))
        if status == 0:  # pass
            panorama.append(result)
        else:
            print("image stitching failed")


if __name__ == '__main__':
    
    convert_video_to_frames()  # dummy function

    start = time.perf_counter()
    stitch_images()
    finish = time.perf_counter()
    print(f'finished in {round(finish - start, 2)} seconds(s)')

    print("now converting images to video...")
    convert_frames_to_video()

另外,我尝试使用多处理并添加锁来实现这一点,但添加:

p1 = multiprocessing.Process(target=stitch_images)
p2 = multiprocessing.Process(target=stitch_images)
    
p1.start()
p2.start()
    
p1.join()
p2.join()

但是当我运行它时,它似乎一起跳过了while循环?

标签: pythonmultithreading

解决方案


推荐阅读