<p>部分问题是<code>cv2.KeyPoint</code>是python中返回<code>cv2.KeyPoint</code>对象的函数。Pickle被搞糊涂了,因为字面意思是,“<code><type 'cv2.KeyPoint'></code>[是]<code>not the same object as cv2.KeyPoint</code>”。也就是说,<code>cv2.KeyPoint</code>是一个函数对象,而类型是<code>cv2.KeyPoint</code>。为什么OpenCV是这样的,我只能猜测,除非我去挖掘。我有一种感觉,它与一个围绕C/C++库的包装有关。</p>
<p>Python确实让您能够自己解决这个问题。<a href="https://stackoverflow.com/a/38509409/786020">I found the inspiration on this post about pickling methods of classes</a>。</p>
<p>实际上,我使用的是这段代码,经过高度修改后</p>
<pre><code>import copyreg
import cv2
def _pickle_keypoints(point):
return cv2.KeyPoint, (*point.pt, point.size, point.angle,
point.response, point.octave, point.class_id)
copyreg.pickle(cv2.KeyPoint().__class__, _pickle_keypoints)
</code></pre>
<p>注意要点:</p>
<ul>
<li>在Python 2中,需要使用<code>copy_reg</code>而不是<code>copyreg</code>,使用<code>point.pt[0], point.pt[1]</code>而不是<code>*point.pt</code>。</li>
<li>由于某种原因,您不能直接访问<code>cv2.KeyPoint</code>类,因此您需要创建一个临时对象并使用它。</li>
<li>当取消锁定时,<code>copyreg</code>修补将使用我在<code>_pickle_keypoints</code>输出中指定的其他有问题的<code>cv2.KeyPoint</code>函数,因此我们不需要实现取消锁定例程。</li>
<L>并且令人恶心地完成,^ {CD15}}是C++中的重载函数,但在Python,这不是一回事。而在C++中,有一个函数使用第一个参数的点,在Python中,它会尝试将它解释为^ {CD16}}。<code>*</code>将点展开为两个参数,<code>x</code>和<code>y</code>以匹配唯一的<code>int</code>参数构造函数。</li>
</ul>
<p>我一直在使用<a href="https://stackoverflow.com/a/11985056/786020">casper's excellent solution</a>直到我意识到这是可能的。</p>