Flask OpenCV 以字节为单位发送和接收图像

Posted

技术标签:

【中文标题】Flask OpenCV 以字节为单位发送和接收图像【英文标题】:Flask OpenCV Send and Receive Images in Bytes 【发布时间】:2019-02-18 21:29:31 【问题描述】:

我想在我的烧瓶 API 中以字节为单位发送和接收图像。我还想在图像旁边发送一些 json。我怎样才能做到这一点?

以下是我目前不起作用的解决方案

烧瓶:

    @app.route('/add_face', methods=['GET', 'POST'])
    def add_face():
    if request.method == 'POST':
        # print(request.json)
        nparr = np.fromstring(request.form['img'], np.uint8)
        print(request.form['img'])
        img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)

        cv2.imshow("frame", img)
        cv2.waitKey(1)

    return "list of names & faces"

客户:

def save_encoding(img_file):
    URL = "http://localhost:5000/add_face"
    img = open(img_file, 'rb').read()

    response = requests.post(URL, data="name":"obama", "img":str(img))
    print(response.content)

产生的错误:

cv2.imshow("frame", img)
cv2.error: OpenCV(3.4.3) /io/opencv/modules/highgui/src/window.cpp:356: error: (-215:Assertion failed) size.width>0 && size.height>0 in function 'imshow'

【问题讨论】:

“它不起作用”是什么意思?以什么方式? 您遇到了什么错误/异常? @randomir 更新错误 @IshanBhatt 更新错误 len(request.form[img]) 和 nparr.shape 返回什么?在此之前,您是否在客户端检查过 img 变量是否正确? 【参考方案1】:

以下内容对我有用。 我没有客户端代码,但我有一个 curl 请求。这应该可以解决问题,

服务器

from flask import request
from PIL import Image
import io

@app.route("/add_face", methods=["POST"])
def predict():
    image = request.files["image"]
    image_bytes = Image.open(io.BytesIO(image.read()))

客户端

curl -X POST -F image=@PATH/TO/FILE 'http://localhost:5000/add_face'

【讨论】:

但如果服务器和客户端之间有连续的帧流,这会更慢 不知道,我偶尔会点击请求,所以从来没有感觉到。如果你愿意,你可以用 gunicorn 或 gevent 包装你的烧瓶应用程序。【参考方案2】:

以 base64 格式发送图像更容易,因为您只需使用字符串即可解决发送/接收二进制数据的问题。在网络东西中也更方便。测试代码如下: 服务器端:

from flask import Flask, render_template, request
import pandas as pd
import cv2
import numpy as np
import base64

app = Flask(__name__)



@app.route('/add_face', methods=['GET', 'POST'])
def add_face():
    if request.method == 'POST':
        #  read encoded image
        imageString = base64.b64decode(request.form['img'])

        #  convert binary data to numpy array
        nparr = np.fromstring(imageString, np.uint8)

        #  let opencv decode image to correct format
        img = cv2.imdecode(nparr, cv2.IMREAD_ANYCOLOR);
        cv2.imshow("frame", img)
        cv2.waitKey(0)

    return "list of names & faces"
if __name__ == '__main__':
    app.run(debug=True, port=5000)

客户端:

import requests
import base64

URL = "http://localhost:5000/add_face"

#  first, encode our image with base64
with open("block.png", "rb") as imageFile:
    img = base64.b64encode(imageFile.read())

response = requests.post(URL, data="name":"obama", "img":str(img))
print(response.content)

如果您确定输入图像,则可以使用 COLOR 代替 ANYCOLOR。

【讨论】:

仍然会产生问题中提到的相同错误。 那么请在cmets中回答我的问题。 len(request.form[img]) 和 nparr.shape 返回什么?在此之前,您是否在客户端检查过 img 变量是否正确? 我已经回答了

以上是关于Flask OpenCV 以字节为单位发送和接收图像的主要内容,如果未能解决你的问题,请参考以下文章

Linux内核调优部分参数说明

哪些是同步通信 哪些是异步通信

TCP Socket在C#中接收数据错误

TCP可靠传输的实现

Python OpenCV 图像到字节字符串以进行 json 传输

Python - 使用 OpenCV 将字节图像转换为 NumPy 数组