Search code examples
pythonjsonopencvsiftkeypoint

Object of type 'KeyPoint' is not JSON serializable opencv


I am trying to send a server request with the image keypoints and descriptor as a json object... here is my code..

import cv2 
import requests
import json

imgDetail = {'keypoints': '', 'descriptor': ''}
sift = cv2.xfeatures2d.SIFT_create()

img = cv2.imread('images/query.jpg', 0)  
kp, des = sift.detectAndCompute(img, None)

des = des.tolist()

imgDetail['keypoints'] = kp  
imgDetail['descriptor'] = des

jsonDump = json.dumps(imgDetail)

resp = requests.post("http://localhost:5000", json=jsonDump, headers={'content-type': 'application/json'})

but its giving me the following error...........

Traceback (most recent call last):
File "E:/python projects/mawa/image.py", line 23, in <module>
jsonDump = json.dumps(imgDetail)
File "E:\Programs\Python\Python36\lib\json\__init__.py", line 231, in dumps
return _default_encoder.encode(obj)
File "E:\Programs\Python\Python36\lib\json\encoder.py", line 199, in encode
chunks = self.iterencode(o, _one_shot=True)
File "E:\Programs\Python\Python36\lib\json\encoder.py", line 257, in iterencode return _iterencode(o, 0)
File "E:\Programs\Python\Python36\lib\json\encoder.py", line 180, in default o.__class__.__name__)

TypeError: Object of type 'KeyPoint' is not JSON serializable

Can anyone give a solution for this?


Solution

  • If you see your kp variable, it's a list of KeyPoint instances. i.e: kp looks like [<KeyPoint 0x109f6da50>, <KeyPoint 0x109f6dd50>, <KeyPoint 0x10a1b2060>, <KeyPoint 0x10a1b2090>, <KeyPoint 0x10a1b20c0>, <KeyPoint 0x10a1b2030>, <KeyPoint 0x10a1a0a80>, <KeyPoint 0x10a1a0660>,...]

    When you try to dump the imgDetail, the keypoints (i.e: kp) is giving error as the KeyPoint instance cannot be serializable.

    You need to loop over the kp list and change instances to dict.

    imgDetail['keypoints'] = [{'angle': k.angle, 'response': k.response} for k in kp]
    

    The KeyPoint class does not have tolist() or __dict__() method. So you may need to create your own dict and pass to the json.dumps().