问题描述
我正在尝试同时运行多个 CMT跟踪器.因此,我设置了一个线程池:
I'm trying to run multiple CMT trackers simultaneously. For that reason, I'm setting a Pool of threads:
import argparse
import cv2
from multiprocessing import Pool
import numpy as np
import os
import sys
import time
import VARtracker
import util
CMT1 = VARtracker.CMT()
... # code lines removed
# Clean up
cv2.destroyAllWindows()
if args.inputpath is not None:
# If a path to a file was given, assume it is a single video file
if os.path.isfile(args.inputpath):
cap = cv2.VideoCapture(args.inputpath)
# Skip first frames if required
if args.skip is not None:
cap.set(cv2.cv.CV_CAP_PROP_POS_FRAMES, args.skip)
# Otherwise assume it is a format string for reading images
else:
cap = util.FileVideoCapture(args.inputpath)
# Skip first frames if required
if args.skip is not None:
cap.frame = 1 + args.skip
# Check if videocapture is working
if not cap.isOpened():
print 'Unable to open video input.'
sys.exit(1)
# Read first frame
status, im0 = cap.read()
im_gray0 = cv2.cvtColor(im0, cv2.COLOR_BGR2GRAY)
im_draw = np.copy(im0)
# Getting initial bounding boxes
tl1 = [405, 160]
br1 = [450, 275]
VARtracker.initialise(CMT1, im_gray0, tl1, br1)
frame = 1
while True:
pool = Pool(processes=4)
print frame
# Read image
status, im = cap.read()
if not status:
break
im_gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
im_draw = np.copy(im)
tic = time.time()
# Serial approach
#res1 = VARtracker.process_frame(CMT1, im_gray)
# Parallel approach
res1 = pool.apply_async(VARtracker.process_frame, (CMT2, im_gray))
pool.close()
pool.join()
res1 = res1.get()
toc = time.time()
# Display results
if res1.has_result:
cv2.line(im_draw, res1.tl, res1.tr, (255, 0, 0), 4)
cv2.line(im_draw, res1.tr, res1.br, (255, 0, 0), 4)
cv2.line(im_draw, res1.br, res1.bl, (255, 0, 0), 4)
cv2.line(im_draw, res1.bl, res1.tl, (255, 0, 0), 4)
if not args.quiet:
cv2.imshow('main', im_draw)
cv2.waitKey(pause_time)
# Remember image
im_prev = im_gray
frame += 1
每当我评论串行方法并尝试使用线程(并行方式)时,都会遇到以下错误:
Whenever I comment the Serial approach and attempt using threads (Parallel aproach), I come across the following error:
在文件"/usr/lib/python2.7/multiprocessing/pool.py"的第558行中,获取提高self._value值
File "/usr/lib/python2.7/multiprocessing/pool.py", line 558, in get raise self._value
cPickle.PicklingError:无法腌制:属性查找cv2.BRISK失败
cPickle.PicklingError: Can't pickle : attribute lookup cv2.BRISK failed
可以在 VARmain.py,VARtracker中遇到其他文件.py和util.py .
我已经尝试了很多方法,但仍然没有找到克服Python局限性的方法.我发现我不能序列化类方法,只能序列化函数.如果可能的话,我想使用Python标准库解决它.
I've tried so many ways and I still haven't found a way to overcome this Python limitation. I found out that I cannot serialize class methods, only functions. If possible, I would like to solve it using Python standard libraries.
推荐答案
我设法解决了这个问题.感谢@Matt和@Yamaneko.基本上,我将读取图像的块移到了worker函数中.因此,如果 pool size = 6 并且有六个边界框,则每个帧将被读取六次(在每个工作程序中).这是我发现使其工作的唯一方法.
I managed to solve it. Thanks to @Matt and @Yamaneko.Basically, I moved the block that reads the image into the worker function. Therefore, if the pool size = 6 and there are six bounding boxes, each frame is going to be read six times (within each worker). That's the only way I have found to make it work.
当前版本可以在此处找到.
import cv2 as cv
import multiprocessing as mp
import time
def worker(folder_path, list_name, top_left, bot_right, index):
frame_path = folder_path + '/' + list_name[0]
image_0 = cv.imread(frame_path)
gray_0 = cv.cvtColor(image_0, cv.COLOR_BGR2GRAY)
cmt = VARtracker.CMT()
cmt.initialise(gray_0, top_left, bot_right)
box_queue = mp.Queue()
for name in list_name:
frame_path = folder_path + '/' + name
image_now = cv.imread(frame_path)
gray_now = cv.cvtColor(image_now, cv.COLOR_BGR2GRAY)
cmt.process_frame(gray_now)
if cmt.has_result:
print index, name, zip(cmt.tl, cmt.br)
output.put((index, name, zip(cmt.tl, cmt.br)))
print 'Process {} finished'.format(index)
def VARmethod(folder_path, final_frame, top_left, bot_right):
tic = time.time()
if len(top_left) == len(bot_right):
list_frame = [index for index in range(1, final_frame + 1)]
list_name = [str(index) + '.jpg' for index in list_frame]
pool = mp.Pool(5)
for index in range(0, len(top_left)):
pool.apply_async(worker, args=(folder_path, list_name, top_left[index], bot_right[index], index))
pool.close()
pool.join()
print 'Finished with the script'
toc = time.time()
print output.qsize()
print (toc - tic)
这篇关于无法腌制<类型'cv2.BRISK'> ;:属性查找cv2.BRISK失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!