6

I am using OpenCV-Python binding to write my image processing application. I am finding a way to write keypoints of a image in to a file which we can get back for matching purpose. There is code in C/C++ to do this, but could not find a way to this by using python

Please anyone have an idea about this, please share with me & all of us

Thanks

  • 1
    This might be helpful, http://stackoverflow.com/questions/10045363/pickling-cv2-keypoint-causes-picklingerror – bikz05 Oct 22 '14 at 06:41

3 Answers3

9

This is how you can do it, inspired from the link I gave earlier.

Save keypoints in a file

import cv2
import cPickle

im=cv2.imread("/home/bikz05/Desktop/dataset/checkered-3.jpg")
gr=cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
d=cv2.FeatureDetector_create("SIFT")
kp=d.detect(gr)

index = []
for point in kp:
    temp = (point.pt, point.size, point.angle, point.response, point.octave, 
        point.class_id) 
    index.append(temp)

# Dump the keypoints
f = open("/home/bikz05/Desktop/dataset/keypoints.txt", "w")
f.write(cPickle.dumps(index))
f.close()

Load and Display keypoints in the image

import cv2
import cPickle

im=cv2.imread("/home/bikz05/Desktop/dataset/checkered-3.jpg")

index = cPickle.loads(open("/home/bikz05/Desktop/dataset/keypoints.txt").read())

kp = []

for point in index:
    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]) 
    kp.append(temp)

# Draw the keypoints
imm=cv2.drawKeypoints(im, kp);
cv2.imshow("Image", imm);
cv2.waitKey(0)

INPUT IMAGE to 1st script

enter image description here

Displayed IMAGE in 2nd script

enter image description here

bikz05
  • 1,575
  • 12
  • 17
1

I have find a way to do it without "pickle".

  import cv2

  img1 = cv2.imread("bat1.jpg")
  gr_img1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
  sift = cv2.SIFT()
  kps = sift.detect(gr_img1)
  f = open("bat_dump.txt", "w")

  for point in kps:
    p = str(point.pt[0]) + "," + str(point.pt[1]) + "," + str(point.size) + "," + str(point.angle) + "," + str(
    point.response) + "," + str(point.octave) + "," + str(point.class_id) + "\n"
    f.write(p)

  f.close()

  kps = []
  lines = [line.strip() for line in open('bat_dump.txt')]

  for line in lines:
    list = line.split(',')
    kp = cv2.KeyPoint(x=float(list[0]), y=float(list[1]), _size=float(list[2]), _angle=float(list[3]),
                  _response=float(list[4]), _octave=int(list[5]), _class_id=int(list[6]))
    kps.append(kp)

  img2 = cv2.imread("bat1.jpg") 
  img2 = cv2.drawKeypoints(img2, kps)
  cv2.imshow("img2", img2)
  cv2.waitKey(0)
0

For this i would suggest using Pickle or cPickle. Its simple and for me it works in the most situations. A short introduction you can find on PyMOTW - Pickle.

To note is that you can dump more times in a File and able to get your data back with loads for each dump.

Edit: If you wish to save the data into a file, here is a short snippet:

import pickle

data = ['your stuff']

with open('fileNameToSave.ext', 'wb') as f:
    pickle.dump(data, f, -1)  # -1 for best compression available

If you need more control at how the data is stored, you could use Struct (PyMOTW). Here you have full control but also have to compress the data yourself if memory matter. In return you have control over Endianness (Byte-Order), Padding etc. So cross-language data-exchange is relative simple.

Hope i could help :)

Acuda
  • 68
  • 9
  • 1
    But this answer does't tell how to save the cv2's KeyPoint data type. For me `pickle.dump(keypoints, open('myKeypoints.ext', 'wb'), -1)` raises the error: TypeError: can't pickle cv2.KeyPoint objects. – Khashayar Oct 26 '21 at 23:24