_pickle.PicklingError: Can't pickle (class 'cv2.KeyPoint'): it's not the same object as cv2.KeyPoint

解决方法参考:https://stackoverflow.com/questions/10045363/pickling-cv2-keypoint-causes-picklingerror

在使用SIFT将提取到的特征保存到pkl文件时,会出现如下错误:

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

这是由于cv2.KeyPoint的class类无法直接通过pickle.dump写入到pkl文件中。

代码如下:(出错代码)

self.sift = cv2.xfeatures2d.SIFT_create()
k, d = self.sift.detectAndCompute(im, mask=None)
self.key_tpls.append(k) #包含所有的关键点信息
self.desc_tpls.append(d)
with open(pkl_fn, 'wb') as f:
	data = [self.key_tpls, self.desc_tpls]
	pickle.dump(data, f)

此时需要对sift.detectAndCompute函数返回的k转换数据类型。

1.K得到的是关键点相关的信息(坐标、尺寸、角度等),将这些值保存到tuple(元组)或者dict(字典)中。

2.代码修改方式

    1)例如:(写入元组tuple)

new_k = []
for i in range(len(k)):
    temp = (k[i].pt , k[i].size , k[i].angle , k[i].response , k[i].octave , k[i].class_id)      
      #把这些信息写入到元组中
    new_k.append(temp)
	self.key_tpls.append(new_k) #包含所有的关键点信息

    2)例如:(写入字典dict)

new_k = []
for i in range(len(k)):
	temp = {'pt':k[i].pt , 'size':k[i].size , 'angle':k[i].angle ,'octave':k[i].octave ,
                         'class_id':k[i].class_id}#把这些信息写入到字典中
	new_k.append(temp)
	self.key_tpls.append(new_k) #包含所有的关键点信息

这样再pickle.dump(data,f)就不会出错了。个人建议用“字典”的形式,因为在下面调用的时候直接k[‘pt’]就可以了,如果是元组的话,还需要自己去看第几位保存的是‘pt’值。

不写入pickle.dump中可以直接用k.pt就可读取到‘pt’值,写入后要用k[‘pt’]。


                                                                             分割线


补充,如出现:AttributeError: module 'cv2.cv2' has no attribute 'xfeatures2d'

原因:opencv-python版本太高

方法:

        1) pip uninstall opencv-contrib-python

        2)pip install opencv-contrib-python==3.3.0.10

(ps:据说opencv3.4以上写了专利了)

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值