6

I am currently able to send OpenCV image frames to my Flask Server using the following code

def sendtoserver(frame):
    imencoded = cv2.imencode(".jpg", frame)[1]
    headers = {"Content-type": "text/plain"}
    try:
        conn.request("POST", "/", imencoded.tostring(), headers)
        response = conn.getresponse()
    except conn.timeout as e:
        print("timeout")


    return response

But I want to send a unique_id along with the frame I tried combining the frame and the id using JSON but getting following error TypeError: Object of type 'bytes' is not JSON serializable does anybody have any idea how I can send some additional data along with the frame to the server.

UPDATED:

json format code

def sendtoserver(frame):
    imencoded = cv2.imencode(".jpg", frame)[1]
    data = {"uid" : "23", "frame" : imencoded.tostring()}
    headers = {"Content-type": "application/json"}
    try:
        conn.request("POST", "/", json.dumps(data), headers)
        response = conn.getresponse()
    except conn.timeout as e:
        print("timeout")


    return response
Mohd Shibli
  • 950
  • 10
  • 17
  • Could you paste how you have tried to combine your frame and unique ID? Additionally, if you are explicitly converting your unique_id to bytes, you'll find this error. LEave it to JSON to handle the encoding decoding of things as explained here: https://stackoverflow.com/questions/44682018/typeerror-object-of-type-bytes-is-not-json-serializable – Rahul Raghunath Sep 16 '18 at 05:21
  • I have added my json code in the question @RahulRaghunath – Mohd Shibli Sep 16 '18 at 05:29

3 Answers3

10

I have actually solved the query by using the Python requests module instead of the http.client module and have done the following changes to my above code.

import requests
def sendtoserver(frame):
    imencoded = cv2.imencode(".jpg", frame)[1]
    file = {'file': ('image.jpg', imencoded.tostring(), 'image/jpeg', {'Expires': '0'})}
    data = {"id" : "2345AB"}
    response = requests.post("http://127.0.0.1/my-script/", files=file, data=data, timeout=5)
    return response

As I was trying to send a multipart/form-data and requests module has the ability to send both files and data in a single request.

Mohd Shibli
  • 950
  • 10
  • 17
0

You can try encoding your image in base64 string

import base64

with open("image.jpg", "rb") as image_file:
    encoded_string = base64.b64encode(image_file.read())

And send it as a normal string.

0

As others suggested base64 encoding might be a good solution, however if you can't or don't want to, you could add a custom header to the request, such as

headers = {"X-my-custom-header": "uniquevalue"}

Then on the flask side:

unique_value = request.headers.get('X-my-custom-header')

or

unique_value = request.headers['X-my-custom-header']

That way you avoid the overhead of processing your image data again (if that matters) and you can generate a unique id for each frame with something like the python uuid module.

Hope that helps

rb4
  • 1