Skip to content

Instantly share code, notes, and snippets.

@kylehounslow
Last active April 23, 2024 10:58
Show Gist options
  • Save kylehounslow/767fb72fde2ebdd010a0bf4242371594 to your computer and use it in GitHub Desktop.
Save kylehounslow/767fb72fde2ebdd010a0bf4242371594 to your computer and use it in GitHub Desktop.
Send and receive images using Flask, Numpy and OpenCV
from __future__ import print_function
import requests
import json
import cv2
addr = 'http://localhost:5000'
test_url = addr + '/api/test'
# prepare headers for http request
content_type = 'image/jpeg'
headers = {'content-type': content_type}
img = cv2.imread('lena.jpg')
# encode image as jpeg
_, img_encoded = cv2.imencode('.jpg', img)
# send http request with image and receive response
response = requests.post(test_url, data=img_encoded.tostring(), headers=headers)
# decode response
print(json.loads(response.text))
# expected output: {u'message': u'image received. size=124x124'}
from flask import Flask, request, Response
import jsonpickle
import numpy as np
import cv2
# Initialize the Flask application
app = Flask(__name__)
# route http posts to this method
@app.route('/api/test', methods=['POST'])
def test():
r = request
# convert string of image data to uint8
nparr = np.fromstring(r.data, np.uint8)
# decode image
img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
# do some fancy processing here....
# build a response dict to send back to client
response = {'message': 'image received. size={}x{}'.format(img.shape[1], img.shape[0])
}
# encode response using jsonpickle
response_pickled = jsonpickle.encode(response)
return Response(response=response_pickled, status=200, mimetype="application/json")
# start flask app
app.run(host="0.0.0.0", port=5000)
@fjolublar
Copy link

fjolublar commented Oct 23, 2020

how can i get image in flask api responce?

frame = analyze_and_modify_frame( frame )  
_, frame  = cv.imencode('.jpg', frame)
response_pickled  = jsonpickle.encode( frame )
return Response(response=response_pickled, status=200, mimetype="application/json") 

and on receiving client:

frame = jsonpickle.decode( response.text ) 
frame = frame.tobytes()

@atinesh-s
Copy link

How can we send and receive multiple images, is it possible to encapsulate images and other data in a dictionary object and send

@MaybeSHAH
Copy link

it tooks more time to send image to flask, if i tried on localhost it works well but got issue when trying to post image to hosted app. any suggestions?

@MarcelAdamski
Copy link

MarcelAdamski commented Apr 21, 2021

r = request
nparr = np.fromstring(r.data, np.uint8)
# decode image
img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)

img = cv2.rotate(img, cv2.ROTATE_90_COUNTERCLOCKWISE)

img = cv2.imencode('.png', img)

response_pickled = jsonpickle.encode(img)

return Response(response=response_pickled, status=200, mimetype="application

How to get this image rotated back as a response? Any suggestions?
cv2.imencode function not work properly to receive image for example in postman

@amarnathreddy0201
Copy link

how can I use cv2.imshow() in server.
Please let us.

@reddytocode
Copy link

@amarnathreddy0201 you can't use cv2.imshow in server
What imshow does, is open a window and display the image in there right?
And from a server side you don't usually have a user interface ... what I would do
1: generate the image using cv2 saving it on a file o just keeping it on memory
2: Find out how to share that image to someone outside the server (Make a RESt API maybe or generate something with sockets)

Maybe this will help https://stackoverflow.com/questions/55822414/how-to-display-an-encoded-opencv-image-on-a-flask-web-server

@Arnold-git
Copy link

Thanks for this @kylehounslow passing cv2.IMREAD_COLOR to cv2.imdecode was where I was missing it.[ np.fromstring ](https://numpy.org/devdocs/reference/generated/numpy.fromstring.html) is deprecated tho. np.drombuffer should be used

@Arnold-git
Copy link

Arnold-git commented Mar 15, 2022

Anyone that wants to get image from client and store in buffer can use this snippet below for flask

       ```
        original_image = request.files.get('original image')
        compare_image = request.files.get('compare image')
        original_img = cv2.imdecode(np.frombuffer(original_image.read(), np.uint8), cv2.IMREAD_COLOR)
        compare_img = cv2.imdecode(np.frombuffer(compare_image.read(), np.uint8), cv2.IMREAD_COLOR)
        known_encoding = face_recognition.face_encodings(original_img)[0]
        unknown_encoding = face_recognition.face_encodings(compare_img)[0]

        results = face_recognition.compare_faces([known_encoding], unknown_encoding)

@kulkarnikeerti
Copy link

@kylehounslow Thanks for the this understandable scripts.
I would like to pass some more additional information along with image to server. Something like below

meta = {'camera': 'camera', 'distance': 'distance'}
response = requests.post(test_url, data=img_encoded.tostring(), headers=headers, json=meta)

And I access this meta information on the server as input_json = r.get_json(force=True)

But this results in error in client side as below.

Traceback (most recent call last):
  File "/home/keerti/PycharmProjects/Flask_Api/client.py", line 21, in <module>
    print(json.loads(response.text))
  File "/usr/lib/python3.10/json/__init__.py", line 346, in loads
    return _default_decoder.decode(s)
  File "/usr/lib/python3.10/json/decoder.py", line 337, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/lib/python3.10/json/decoder.py", line 355, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

Could you please help me with this? If this is the right way to pass additional information

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment