使用多处理时cv2.Boost的Pickle异常 [英] Pickle exception for cv2.Boost when using multiprocessing

查看:133
本文介绍了使用多处理时cv2.Boost的Pickle异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在从事名为"Faciel Actions Units Detection"的项目 我正在使用python2.7和opencv 2.4

I'm working on project named "Faciel Actions Units Detection" I'm using python2.7 and opencv 2.4

错误:

pickle.PicklingError: Can't pickle <type 'cv2.Boost'>: it's not the same object as cv2.Boost

屏幕快照抄录的部分回溯:

Loading classifier for action unit 27
Traceback (most recent call last):
  File "C:\Python27\audetect-master\audetect-interactive.py", line 59, in <module>
    main()
  File "C:\Python27\audetect-master\audetect-interactive.py", line 18, in main
    active_aus = detector.detect()
  File "C:\Python27\audetect-master\detect.py", line 67, in detect
    initial_points = self.ffdetector.locate_features(first)
  File "C:\Python27\audetect-master\detect.py", line 183, in locate_features
    thread.start()
  File "C:\Python27\lib\multiprocessing\process.py", line 130, in start
    self._popen = Popen(self)
  File "C:\Python27\lib\multiprocessing\forking.py", line 227, in __init__
    dump(process_obj, to_child, HIGHEST_PROTOCOL)
  File "C:\Python27\lib\multiprocessing\forking.py", line 199, in dump
    ForkingPickler(file, protocol).dump(obj)
  File "C:\Python27\lib\pickle.py", line 224, in dump
    self.save(obj)
  File "C:\Python27\lib\pickle.py", line 331, in save
    self.save_reduce(obj=obj, *rv)
  File "C:\Python27\lib\pickle.py", line 425, in save_reduce
    save(state)
  File "C:\Python27\lib\pickle.py", line 286, in save
    f(self, obj) # Call unbound method with explicit self
  File "C:\Python27\lib\pickle.py", line 655, in save_dict
    self._batch_setitems(obj.iteritems())
  File "C:\Python27\lib\pickle.py", line 687, in _batch_setitems
    save(v)
  File "C:\Python27\lib\pickle.py", line 286, in save
    f(self, obj) # Call unbound method with explicit self
  File "C:\Python27\lib\multiprocessing\forking.py", line 67, in dispatcher
    self.save_reduce(obj=obj, *rv)
  File "C:\Python27\lib\pickle.py", line 401, in save_reduce
    save(args)
  File "C:\Python27\lib\pickle.py", line 286, in save
    f(self, obj) # Call unbound method with explicit self
  File "C:\Python27\lib\pickle.py", line 554, in save_tuple
    save(element)

推荐答案

Pickle由multiprocessing模块用于在不同部分之间以及

Pickle is used by the multiprocessing module to communicate between the different parts, and in the programming guidelines it explains that you must ensure that all your data that you pass between processes must be compatible with pickling:

可拾取性:确保代理方法的参数可拾取.

Picklability: Ensure that the arguments to the methods of proxies are picklable.

您所使用的数据不可腌制.

You are using data that is not picklable.

特别是,出问题的是cv2.Boost类并没有完全说明如何创建该类的更多副本. pickle存储对类和函数的引用,而不是对它们的定义的存储,因为这样做效率更高.这意味着实例仅需要存储该实例的数据,而不需要存储所有的类层次结构和方法定义.

Specifically, what is going wrong is that the cv2.Boost class doesn't quite tell the truth on how you can create more copies of the class. pickle stores references to classes and functions, not their definition, because that's way more efficient. This means that instances only need to store the data for that instance, not also all of the class hierarchy and method definitions.

为此,pickle将在模块中定义一个类或函数,对象名称以及对类或函数的引用一起使用.然后仔细检查可以使用该名称再次加载相同的类或函数.

In order to do this, pickle takes the module a class or function is defined in, and the name of the object, and together that's the reference to the class or function. It then double-checks that it can use that name to load the same class or function back again.

cv2.Boost类的健全性检查失败.您有一个名为Boost的类的实例,该实例声称来自cv2模块,但是当pickle然后进入cv2模块并查找该模块的Boost属性时,一个不同的对象.这意味着您的数据无法被剔除.

That sanity check failed for the cv2.Boost class. You have instances of a class is named Boost and that claims to have come from the cv2 module, but when pickle then goes to the cv2 module and looks up the Boost attribute of that module it found a different object. This means your data could not be unpickled.

有多种方法可以纠正此问题;您需要使用pickle模块使用其他函数来再次加载相同的数据. rel ="nofollow noreferrer"> copyreg.pickle()函数;如果cv2.Boost类存在这样的注册,则pickle不会进行上述检查:

There are ways to correct this; you need to teach the pickle module to use a different function to load the same data again, using the copyreg.pickle() function; if such a registration exists for the cv2.Boost class then pickle will not make the above check:

import copyreg
import cv2

def _pickle_boost(boost):
    return cv2.Boost, (
        boost.trainData,
        boost.tflag,
        boost.responses, 
        boost.varIdx,
        boost.sampleIdx,
        boost.varType,
        boost.missingDataMask,
        boost.paramsd,
    )

copyreg.pickle(cv2.Boost().__class__, _pickle_boost)

警告 :我实际上并未测试上述方法是否可行,因为我没有在本地安装2.4c版本的cv2.我只是参考了 cv2.Boost()文档猜测此类会具有哪些属性.您可能需要调整它.这个想法是,对于cv2.Boost().__class__类型,将调用_pickle_boost()函数,返回一个可调用对象(cv2.Boost)以创建一个新实例,以及要传递给该可调用对象的参数.

WARNING: I didn't actually test if the above will work, because I don't have a 2.4.x version of cv2 installed locally; I merely referred to the cv2.Boost() documentation to guess at what attributes such a class would have. You'll probably need to adjust it. The idea is that for the cv2.Boost().__class__ type, the _pickle_boost() function is called, returning a callable (cv2.Boost) to create a new instance, and the arguments that you want to pass to that callable.

如果以上任何一个值本身都是表现相同问题的更多cv2类型,则您需要注册更多功能.

If any of the above values are themselves more cv2 types that exhibit the same problem, then you need to register more functions.

这篇关于使用多处理时cv2.Boost的Pickle异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆