Excepción de salmuera para cv2.Boost cuando se utiliza multiprocesamiento

Estoy trabajando en el proyecto llamado “Detección de unidades de acciones faciel” Estoy usando python2.7 y opencv 2.4

El error:

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

Un rastreo parcial, transcrito de una captura de pantalla :

 Loading classifier for action unit 27 Traceback (most recent call last): File "C:\Python27\audetect-master\audetect-interactive.py", line 59, in  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 es utilizado por el módulo de multiprocessing para comunicarse entre las diferentes partes, y en las pautas de progtwigción explica que debe asegurarse de que todos los datos que pasa entre procesos deben ser compatibles con el decapado:

Picklability : asegúrese de que los argumentos de los métodos de los proxies son pickable.

Está utilizando datos que no son seleccionables.

Específicamente, lo que está mal es que la clase cv2.Boost no dice la verdad sobre cómo puedes crear más copias de la clase. pickle almacena referencias a clases y funciones, no a su definición, porque es mucho más eficiente. Esto significa que las instancias solo necesitan almacenar los datos para esa instancia, no también toda la jerarquía de clases y las definiciones de métodos.

Para hacer esto, pickle toma el módulo en el que se define una clase o función, y el nombre del objeto, y juntos es la referencia a la clase o función. Luego , vuelve a verificar que puede usar ese nombre para volver a cargar la misma clase o función.

Esa comprobación de cv2.Boost falló para la clase cv2.Boost . Las instancias de una clase se denominan Boost y se dice que provienen del módulo cv2 , pero cuando pickle va al módulo cv2 y busca el atributo Boost de ese módulo, encontró un objeto diferente . Esto significa que sus datos no pueden ser descifrados.

Hay maneras de corregir esto; debe enseñar al módulo pickle a usar una función diferente para volver a cargar los mismos datos, usando la función copyreg.pickle() ; si existe tal registro para la clase cv2.Boost , pickle no realizará la comprobación anterior:

 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) 

ADVERTENCIA : Realmente no cv2 si lo anterior funcionará, porque no tengo una versión 2.4.x de cv2 instalada localmente; Simplemente me referí a la documentación de cv2.Boost() para adivinar qué atributos tendría tal clase. Probablemente necesites ajustarlo. La idea es que para el tipo cv2.Boost().__class__ , se _pickle_boost() función _pickle_boost() , devolviendo un cv2.Boost ( cv2.Boost ) para crear una nueva instancia, y los argumentos que desea pasar a ese callab.

Si alguno de los valores anteriores son más tipos de cv2 que presentan el mismo problema, deberá registrar más funciones.