这里post接收数据后,并没有保存成文件,而是全部在内存中操作,减少文件IO有利于提高使用效率,如有需要,可以通过cv2.imwirite()方法实现持久化
- flask接收post方法传递json数据,包含base64编码的图像
@app.route('/imagePredictJSON',methods=['Post'])
def imagePredictJSON():
data = request.json
try:
base64str = data['data']['image'].split(',')[1]
image = base64_to_image(base64str)
pred_2 = predict_frame(image)
except Exception as e:
print(e)
abort(500)
finally:
return jsonify({"status":0, "message":"success","data":{"count":len(pred_2),"results":pred_2}})
记住几个知识点,
- json数据通过request.json获得
- 需要将头部去除,base64前面的是头部,说明了文件类型,通过base64_str.split(‘,’)[1]获取图片数据,这部分也可以放到前端完成
- base64转成cv2图像函数需要另写,为
def base64_to_image(base64_code):
# base64解码
img_data = base64.b64decode(base64_code)
# 转换为np数组
img_array = np.fromstring(img_data, np.uint8)
# 转换成opencv可用格式
img = cv2.imdecode(img_array, cv2.COLOR_RGB2BGR)
return img
- flask接收post方法表单数据
@app.route('/imagePredict',methods=['post'])
def imagePredict():
img = request.files['image']
print(type(img))
img = Image.open(img.stream)
img = cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR)
pred_2 = predict_frame(img)
return jsonify({"status":0, "message":"success","data":{"count":len(pred_2),"results":pred_2}})
这里的知识点是:
1.form上传的文件通过request.files[‘filed_name’]得到,得到的是一个文件流
2.Image方法是PIL提供的,需要引入 :from PIL import Image
3.文件流写入到内存后,需要通过cvtColor将文件的数组转换成cv2的格式,便于后面调用
- flask接口返回图片流
这里情况有点特殊,我做的项目是前端上传一张图,请求接口之后想要返回处理后的图,用于演示,为了不产生实体文件,直接在内存中处理完了就返回前端。所以这里只能使用post方法,
from flask import Flask, send_file, render_template, Response, jsonify, request, abort
from PIL import Image
import cv2
@app.route('/imageTest',methods=['post'])
def imagePredictTest():
# img = cv2.imread('./data/4.jpg')
img = request.files['image']
img = Image.open(img.stream)
img = cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR)
pred_2,image = predict_frame(img)
print(image)
ret, jpeg = cv2.imencode('.jpg', image)
frame = jpeg.tobytes()
return Response( (b'--frame\r\n'
b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n'),
mimetype='multipart/x-mixed-replace; boundary=frame')
这里的知识点是:
1.request中拿到的是文件流,需要把流读到内存中要使用Image.open(img.stream)方法
2.上述方法得到的是一个图片类型的实例,需要进一步转为cv2的图片类型,img = cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR)
3.cv2的图像不能直接返回给前端,前端需要二进制的jpeg格式的或者其它,这里以jpeg为例,需要cv2编码成jpg格式,然后构造一个二进制的返回消息