22

I am sending an image by curl to flask server, i am using this curl command

curl -F "[email protected]" http://localhost:8000/home

and I am trying to read the file using OpenCV on the server side.

On the server side I handle the image by this code

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

I am getting this error-

img = cv.imread(data)
TypeError: expected string or Unicode object, FileStorage found

How do I read the file using OpenCV on the server side?

Thanks!

1

4 Answers 4

45

I had similar issues while using opencv with flask server, for that first i saved the image to disk and read that image using saved filepath again using cv.imread()

Here is a sample code:

data =request.files['file']
filename = secure_filename(file.filename) # save file 
filepath = os.path.join(app.config['imgdir'], filename);
file.save(filepath)
cv.imread(filepath)

But now i have got even more efficient approach from here by using cv.imdecode() to read image from numpy array as below:

#read image file string data
filestr = request.files['file'].read()
#convert string data to numpy array
file_bytes = numpy.fromstring(filestr, numpy.uint8)
# convert numpy array to image
img = cv.imdecode(file_bytes, cv.IMREAD_UNCHANGED)
Sign up to request clarification or add additional context in comments.

2 Comments

For 2nd trick, use img = cv2.imdecode(npimg,cv2.IMREAD_COLOR) for opencv 3.1
From @user1 the same for version 4.5.5
7

After a bit of experimentation, I myself figured out a way to read the file using CV2. For this I first read the image using PIL.image method

This is my code,

@app.route('/home', methods=['POST'])
def home():
    data =request.files['file']
    img = Image.open(request.files['file'])
    img = np.array(img)
    img = cv2.resize(img,(224,224))
    img = cv2.cvtColor(np.array(img), cv2.COLOR_BGR2RGB)
    fact_resp= model.predict(img)
    return jsonify(fact_resp)

I wonder if there is any straight forward way to do this without using PIL.

Comments

5

So incase you want to do something like ,

file = request.files['file']
img = cv.imread(file) 

then do it like this

import numpy as np
file = request.files['file']
file_bytes = np.fromfile(file, np.uint8)
file = cv.imdecode(file_bytes, cv.IMREAD_COLOR)

Now you don't need to do cv.imread() again, but can use this in the next line of codes.

This applies to OpenCV v3.x and onwards

Comments

1

Two-line solution, change grayscale to what you need

 file_bytes = numpy.fromfile(request.files['image'], numpy.uint8)
 # convert numpy array to image
 img = cv.imdecode(file_bytes, cv.IMREAD_GRAYSCALE)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.