使用多处理时cv2.Boost的Pickle异常 [英] Pickle exception for cv2.Boost when using multiprocessing
问题描述
我正在从事名为"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.
有多种方法可以纠正此问题;您需要使用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屋!