I'm working on project named "Faciel Actions Units Detection" I'm using python2.7 and opencv 2.4
The error:
pickle.PicklingError: Can't pickle <type 'cv2.Boost'>: it's not the same object as cv2.Boost
A partial traceback, transcribed from 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)
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:You are using data that is not picklable.
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.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.That sanity check failed for the
cv2.Boost
class. You have instances of a class is namedBoost
and that claims to have come from thecv2
module, but whenpickle
then goes to thecv2
module and looks up theBoost
attribute of that module it found a different object. This means your data could not be unpickled.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 thecopyreg.pickle()
function; if such a registration exists for thecv2.Boost
class thenpickle
will not make the above check: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 thecv2.Boost()
documentation to guess at what attributes such a class would have. You'll probably need to adjust it. The idea is that for thecv2.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.If any of the above values are themselves more
cv2
types that exhibit the same problem, then you need to register more functions.