Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

serialization #4251

Open
opencv-pushbot opened this issue Jul 27, 2015 · 5 comments
Open

serialization #4251

opencv-pushbot opened this issue Jul 27, 2015 · 5 comments

Comments

@opencv-pushbot
Copy link
Contributor

Transferred from http://code.opencv.org/issues/379

|| James Bowman on 2010-06-11 00:47
|| Priority: High
|| Affected: None
|| Category: python bindings
|| Tracker: Feature
|| Difficulty: Medium
|| PR: 
|| Platform: None / None

serialization

It would be very nice if Python OpenCV objects were pickleable.

To do this, can the load/store methods of cpp objects accept strings?

History

Alexander Shishkov on 2012-02-12 21:33
-   Description changed from It would be very nice if Python [[OpenCV]]
    objects were pickleable. To do th... to It would be very nice if
    Python OpenCV objects were pickleable. To do this, ... More
Andrey Kamaev on 2012-04-05 08:49
-   Category changed from imgproc, video to python bindings
Vadim Pisarevsky on 2012-05-29 16:00
-   Target version set to 3.0
Stefan R on 2012-11-28 10:22
+1
Maksim Shabunin on 2015-04-28 13:50
-   Difficulty set to Medium
-   Target version changed from 3.0 to 3.1
@tzickel
Copy link

tzickel commented Feb 1, 2016

There are a few issues with python serialization (pickle/copy) and opencv. I'll be using the class KeyPoint for the examples.

  1. Currently the generated c-api code defines the C++ classes as both a python function and a python class (which isn't registered in the cv2 module, altough it's name is "cv2.". To my knowledge this is a big no-no and will block using the pickle subsystem at all.
  2. There is no reduce / copy_reg.pickle code generated for how to serialize the objects themselves (for saving/loading the actual object state).
>>> import cv2
>>> kp = cv2.KeyPoint(1, 2, 3)
>>> type(kp)
<type 'cv2.KeyPoint'>
>>> type(kp) == cv2.KeyPoint
False
>>> cv2.KeyPoint
<built-in function KeyPoint>
>>> import pickle
>>> pickle.dumps(kp, -1)
pickle.PicklingError: Can't pickle <type 'cv2.KeyPoint'>: it's not the same object as cv2.KeyPoint

I assume the only correct solution (unless I'm wrong) is to:

  1. Stop using the creation functions (like pyopencv_KeyPoint_KeyPoint) and instead create a true new and init implementations for all the cv2 classes and register them in cv2 instead of the creation functions.
  2. Implementing a auto generated reduce function for each of the classes.

I am not versed enough in the complex code of the gen2.py (especially it's edge cases), so if someone could shed more light on this issue (for example, is there an easier solution which is also as correct ?)

@autosquid
Copy link

this "bug" caught me, too.

@wilderrodrigues
Copy link

Just got caught by this one as well, although a different class:

Can't pickle <class 'cv2.CascadeClassifier'>: it's not the same object as cv2.CascadeClassifier

How is a fix coming together? Any help needed?

@mjpieters
Copy link

mjpieters commented May 17, 2018

The project should register pickling functions with the copyreg module. See my Stack Overflow answer for example on how to write one.

The underlying cause is that the __name__ attribute on the class of instances returned by functions such as cv2.Boost() points back to the function, not the actual type. The other work-around would be for the __name__ attribute to actually resolve back to the correct type.

@Vincent-CIRCL
Copy link

Vincent-CIRCL commented May 17, 2019

Very helpful. Thanks ! Your stackoverflow answer is really clear.

Here is the code snippet for Keypoints, as the same problem occurs for them :

def patch_Keypoint_pickiling(self):
    # Create the bundling between class and arguements to save for Keypoint class
    # See : https://stackoverflow.com/questions/50337569/pickle-exception-for-cv2-boost-when-using-multiprocessing/50394788#50394788
    def _pickle_keypoint(keypoint): #  : cv2.KeyPoint
        return cv2.KeyPoint, (
            keypoint.pt[0],
            keypoint.pt[1],
            keypoint.size,
            keypoint.angle,
            keypoint.response,
            keypoint.octave,
            keypoint.class_id,
        )
    # KeyPoint (float x, float y, float _size, float _angle=-1, float _response=0, int _octave=0, int _class_id=-1)

    # Apply the bundling to pickle
    copyreg.pickle(cv2.KeyPoint().__class__, _pickle_keypoint)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants