Passing image data to Flask server

Viewed 7563

I want to send an image by curl to flask server, i am trying this curl command

curl -F "file=@image.jpg" http://localhost:8000

but it did not work

On the server side I handle the image by this code

@app.route('/home', methods=['POST'])
def home():
    data =request.files['file']
    img = cv2.imread(data)
    fact_resp= model.predict(img)
    return jsonify(fact_resp)

fact_resp is an integer and i am trying to read the image using cv2

Is there anyway to do this?

3 Answers

You should use the right url for your curl command, which is http://localhost:8000/home, if in fact your app is running on localhost, port 8000.

When it comes to your cv2 code, if you have an issue, please open a separate question with different tags to get the proper help!

Edit:

Tested minimal example curling.py

from flask import Flask, jsonify, request

app = Flask(__name__)

@app.route('/home', methods=['POST'])
def home():
    data = request.files['file']
    return jsonify({"status":"ok"})

app.run(port=8000)

Start with python curling.py

In separate terminal window:

curl -F "file=@image.jpg" http://localhost:8000/home

Output:

{
  "status": "ok"
}

Typical problem: Client sends a .png image to server and server returns (a numpy array) as result.

For those trying to doing it without post and within Python, this may help:

server-side

import cv2
import numpy as np
import requests
from flask import Flask,jsonify,request,json
import jsonpickle

@app.route('/test',methods=['POST'])
def predict():
        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)

        # perform some inference and return numpy array
       response = np.arange(200).reshape(100,2) #dummy response
       response_pickled = jsonpickle.encode(response)
       return response_pickled

if __name__ == '__main__':
    app.run(host='0.0.0.0',port=5000, debug=True)
  

client-side

import requests
import json
import cv2
import jsonpickle

addr = 'http://localhost:5000'
test_url = addr + '/test'

# prepare headers for http request
content_type = 'image/png'
headers = {'content-type': content_type}

# read image to send to server
img = cv2.imread('m.png')

# encode image as png
_, img_encoded = cv2.imencode('.png', img)
response = requests.post(test_url, data=img_encoded.tostring(), headers=headers)

# check response/result
result = jsonpickle.decode(response.text)

print(np.array(result).shape) #[200,2]

You should use POST for this as well as right URL http://localhost:8000/home and send the corresponding header to emulate sending html form with file attached:

curl -i -X POST -H "Content-Type: multipart/form-data" -F "file=@/path/to/file" http://localhost:8000/home/
Related