我正在开发名为“Faciel Actions Units Detection”的项目我正在使用python2.7和opencv 2.4
错误:
pickle.PicklingError: Can't pickle <type 'cv2.Boost'>: it's not the same object as cv2.Boost
从a screenshot转录的部分追溯:
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)
multiprocessing
模块使用Pickle在不同部分之间进行通信,在programming guidelines中,它解释了您必须确保在进程之间传递的所有数据必须与pickle兼容:
可选择性:确保代理方法的参数是可选择的。
您正在使用不可选择的数据。
具体来说,出现问题的是,cv2.Boost
类并不能说明如何创建更多类的副本。 pickle
存储对类和函数的引用,而不是它们的定义,因为这样更有效。这意味着实例只需要存储该实例的数据,而不是所有类层次结构和方法定义。
为了做到这一点,pickle
将模块定义为一个类或函数,以及对象的名称,以及它们对类或函数的引用。然后再仔细检查它是否可以使用该名称再次加载相同的类或函数。
cv2.Boost
班的理智检查失败了。你有一个类的实例名为Boost
,并声称来自cv2
模块,但当pickle
然后转到cv2
模块并查找该模块的Boost
属性时,它发现了一个不同的对象。这意味着您的数据无法被打开。
有办法纠正这个问题;你需要教pickle
模块使用不同的函数再次加载相同的数据,使用copyreg.pickle()
function;如果cv2.Boost
类有这样的注册,那么pickle
将不会进行上述检查:
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.4.x版本的cv2
;我只是提到cv2.Boost()
documentation来猜测这样一个类会有什么属性。你可能需要调整它。这个想法是,对于cv2.Boost().__class__
类型,调用_pickle_boost()
函数,返回一个可调用的(cv2.Boost
)来创建一个新实例,以及你想要传递给那个可调用的参数。
如果上述值中的任何一个本身是更多表现出相同问题的cv2
类型,那么您需要注册更多函数。