视频python中帧的并行处理,你好我已经尝试使用python中的多处理库进行图像处理,我想做的是我有一个视频,我们知道视频是一个帧流我有核心i5我想要做的每个核心将处理这些帧的一帧示例(将在一秒内发生什么)核心1处理帧1核心2处理帧2核心3处理帧3核心4处理帧4核心。
我的问题是如何实现这一点? 这是我计划进行多处理或多线程的代码
int($(ls|wc -l)) > 20
答案 0 :(得分:0)
虽然这不是你要求的,但我很好奇我将自己的图像分解成子图像以便进一步处理,所以我把这个例子放在一起。它显示了如何进行线程或多进程。你应该能够弄清楚如何及时分解而不是空间。
基本上,使用框架填充FRAME_QUEUE
,而不是块。
import cv2
import numpy as np
import multiprocessing
import threading
import time
import argparse
FRAME_QUEUE = multiprocessing.JoinableQueue()
RESULT_QUEUE = multiprocessing.Queue()
# defaults
NWORKERS = 2
PARALLEL_TYPE = 'thread'
FONT = cv2.FONT_HERSHEY_SIMPLEX
def process_frame(frame):
# Convert BGR to HSV
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
lower_red = np.array([150, 150, 50], np.uint8)
upper_red = np.array([180, 255, 150], np.uint8)
# Threshold the HSV image to get only blue colors
# finding the range of red
mask = cv2.inRange(hsv, lower_red, upper_red)
res = cv2.bitwise_and(frame, frame, mask=mask)
kernel = np.ones((5, 5), np.uint8)
mask = cv2.dilate(mask, kernel)
res = cv2.bitwise_and(frame, frame, mask=mask)
_, contours, hierarchy = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
for pic, contour in enumerate(contours):
area = cv2.contourArea(contour)
if(area > 1000):
x, y, w, h = cv2.boundingRect(contour)
frame = cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 0, 255), 2)
return frame, mask, res
def parallel_process_frame(cls):
"""the main function that perfroms the image processing"""
while True:
next_frame = FRAME_QUEUE.get()
if next_frame is None:
# Poison pill means shutdown
break
# process the frame
i, frame = next_frame
frame, mask, res = process_frame(frame)
# draw worker on frame
frame = cv2.putText(frame, '{}'.format(i),
(0, 20), FONT,
0.5, (255, 0, 0), 1, cv2.LINE_AA)
# tell the queue that we are done
FRAME_QUEUE.task_done()
# place the results in the result queue
RESULT_QUEUE.put((i, (frame, mask, res)))
class ParallelProcessWorker(multiprocessing.Process):
"""multiprocess worker"""
def __init__(self):
multiprocessing.Process.__init__(self)
def run(self):
parallel_process_frame(self)
class ParallelThreadWorker(threading.Thread):
"""multithread worker"""
def __init__(self):
threading.Thread.__init__(self)
def run(self):
parallel_process_frame(self)
def serial(frame):
"""serial process the frame"""
return process_frame(frame)
def multi(frame):
"""multithread/multiprocess process the frame"""
# split the frame and place in the queue
for i, chunk in enumerate(np.split(frame, NWORKERS)):
FRAME_QUEUE.put((i, chunk))
# wait for the chunks to finish
FRAME_QUEUE.join()
# collect the results
results = []
for i in range(NWORKERS):
results.append(RESULT_QUEUE.get())
# sort, because they can come back in any order
results.sort(key=lambda x: x[0])
# combine chunks
frame = np.vstack((r[1][0] for r in results))
mask = np.vstack((r[1][1] for r in results))
res = np.vstack((r[1][2] for r in results))
return frame, mask, res
if __name__ == "__main__":
parser = argparse.ArgumentParser(
prog='Parallel',
description='Program parallel video processing')
ARG = parser.add_argument
ARG('-m', '--method', metavar='PAR', action='store', default=None,
choices=['serial', 'thread', 'process'])
ARG('-w', '--workers', metavar='N', action='store', default=2,
help='specify the number of workers')
args = parser.parse_args()
# set flags
PARALLEL_TYPE = args.method
NWORKERS = int(args.workers)
# setup parallel scheme
if PARALLEL_TYPE != 'serial':
method = multi
if PARALLEL_TYPE == 'thread':
worker = ParallelThreadWorker
else:
worker = ParallelProcessWorker
# start the workers
for i in range(NWORKERS):
w = worker()
w.start()
else:
method = serial
# variables
frame_count = 0
start = time.time()
# start capture
cap = cv2.VideoCapture(0)
# start the loop
while(True):
frame_count += 1
# Take each frame
_, frame = cap.read()
frame, mask, res = method(frame)
FPS = frame_count/(time.time()-start)
frame = cv2.putText(frame, 'FPS: {0:.1f}'.format(FPS),
(0, 20), FONT,
0.5, (0, 255, 0), 1, cv2.LINE_AA)
cv2.imshow('frame', frame)
# cv2.imshow('mask', mask)
# cv2.imshow('res', res)
k = cv2.waitKey(5) & 0xFF
if k == 27:
break
cap.release()
cv2.destroyAllWindows()
# place a bunch of Nones to shutdown the threads/process
[FRAME_QUEUE.put(None) for i in range(NWORKERS*2)]
# report
print('Using a {0} approach with {1} workers resulted in an average FPS of {2:.1f}'.format(PARALLEL_TYPE, NWORKERS, FPS))
您可以指定并行方案和这样的工作人员:
python camera_parallel.py -m serial
python camera_parallel.py -m thread -w 4
python camera_parallel.py -m process -w 2
在我的机器上(MacBook Pro,2009,Core2Duo),串口为我提供了最高的帧速率。