In this post, we will write 2 python scripts -

1. First one, to load a image, extract the keypoints and save them in a file.
2. Second one, load the file saved in the previous script and draw the contours on the same image used in step 1.

Normally, for loading and saving data, we will use cPickle package. To store data in a file we use the dump function and to load data we use loads function. The problem with OpenCV’s keypoint type is that we cannot directly dump keypoints objects using dump function. If we try to do so, we’ll get an error as shown below -

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

So, we need to serialize and deserialize the keypoints data.

So, let’s write code, for the first script for saving the keypoints in a file.

 1 import cv2
2 import cPickle
3
5 gr = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
6 d = cv2.FeatureDetector_create("SIFT")
7 kp = d.detect(gr)
8
9 index = []
10 for point in kp:
11 temp = (point.pt, point.size, point.angle, point.response, point.octave, point.class_id
12 index.append(temp)
13
14 # Dump the keypoints
15 f = open("/home/bikz05/Desktop/dataset/keypoints.txt", "w")
16 f.write(cPickle.dumps(index))
17 f.close()

We have saved our keypoints in keypoints.txt. Now, let’s load those keypoints in a separate script and draw them on the same image.

Now let’s write second script which will load the keypoints from the file and display them on the image.

 1 import cv2
2 import cPickle
3
6 kp = []
7
8 for point in index:
9     temp = cv2.KeyPoint(x=point[0][0],y=point[0][1],_size=point[1], _angle=point[2], _response=point[3], _octave=point[4], _class_id=point[5])
10     kp.append(temp)
11
12 # Draw the keypoints
13 imm = cv2.drawKeypoints(im, kp);
14 cv2.imshow("Image", imm);
15 cv2.waitKey(0)

That’s it, the above script when run will display the image with all the keypoints marked on it.