When we are using opencv SIFT algorithm to compute the similarity between two images, we will get two objects: keypoint, descriptor. In order to save processing time, we may save them to a file using python pickle. However, we may get this error: TypeError: can’t pickle cv2.KeyPoint objects. In this tutorial, we will introduce you how t fix it.
For example:
keypoint1, descriptor1 = computeSIFT(image_1_data) print(type(keypoint1)) for k in keypoint1: print(type(k)) with open("test.txt", "wb") as f: pickle.dump(keypoint1, f)
Here keypoint1 is python list, it contains some <class ‘cv2.KeyPoint’>
Run this code, we will get this error:
TypeError: can’t pickle cv2.KeyPoint objects
How to fix this error?
In order to save KeyPoint object using pickle, we can wrap it by using a python dictionary.
For example:
#------------------------------------------------------------- new_k = [] k = keypoint1 for i in range(len(k)): temp = {'pt': k[i].pt, 'size': k[i].size, 'angle': k[i].angle, 'octave': k[i].octave, "response":k[i].response, "octave":k[i].octave, 'class_id': k[i].class_id } # 把这些信息写入到字典中 new_k.append(temp) data = [new_k, descriptor1] with open("key.txt", 'wb') as fp: pickle.dump(data, fp)
Run this code, we will save keypoint1 and descriptor1 to a key.txt
How to load keypoint1 and descriptor1and from key.txt file?
We should rebuild keypoint1 from points saved in key.txt
For example:
with open("key.txt", 'rb') as fp: data = pickle.load(fp) descriptor1 = data[1] new_k = data[0] keypoint1 = [] for temp in new_k: point = cv2.KeyPoint(x=temp['pt'][0], y=temp['pt'][1], _size=temp['size'], _angle=temp['angle'], _response=temp['size'], _octave=temp['octave'], _class_id=temp['class_id']) keypoint1.append(point) #------------------------
Run this code, we can find keypoint1 and descriptor1 are restored.