无法挑选<type'cv2.brisk'=“”>:属性查询cv2.BRISK失败

时间:2016-07-01 16:47:40

标签: python multithreading opencv

我试图同时运行多个CMT trackers。出于这个原因,我设置了一个线程池:

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

每当我评论串行方法并尝试使用线程(并行aproach )时,我都会遇到以下错误:

  

追踪(最近一次呼叫最后一次):

     
    

文件&#34; /home/rafael/GIT/CMT-Tracker/VaretoCMT/VARmain.py",第128行,模块res1 = res1.get()

         

File&#34; /usr/lib/python2.7/multiprocessing/pool.py" ;,第558行,在get raise self._value

  
     

cPickle.PicklingError:不能发现:属性查找cv2.BRISK失败

VARmain.py, VARtracker.py and util.py上可能遇到其他文件。

我已经尝试了很多方法,但我仍然没有找到克服Python限制的方法。我发现我不能序列化类方法,只能序列化函数。如果可能的话,我想用Python标准库来解决它。

2 个答案:

答案 0 :(得分:4)

我设法解决了这个问题。感谢@Matt和@Yamaneko。 基本上,我将读取图像的块移动到worker函数中。因此,如果池大小= 6 并且有六个边界框,则每个帧将被读取六次(在每个工作者内)。这是我找到的唯一方法。

可以找到当前版本here

user_friends

答案 1 :(得分:3)

在你的课程周围试试这个代码段(这不是我的代码,可归功于Steven Bethard) - 这是一个解决类的解决方法;多处理模块使用pickle将作业发送给worker:

def _pickle_method(method):
    func_name = method.im_func.__name__
    obj = method.im_self
    cls = method.im_class
    return _unpickle_method, (func_name, obj, cls)

def _unpickle_method(func_name, obj, cls):
    for cls in cls.mro():
        try:
            func = cls.__dict__[func_name]
        except KeyError:
            pass
        else:
            break
    return func.__get__(obj, cls)

import copy_reg
import types
copy_reg.pickle(types.MethodType, _pickle_method, _unpickle_method)

multiprocessingCan't pickle <type 'instancemethod'> when using python's multiprocessing Pool.map()

一起使用的示例

不是说这很容易转换。如果你真的想要多线程,我建议使用OpenMP进行Cython。您只需重写需要与nogil语句并行的程序部分和from cython.parallel cimport prange并行循环......