利用flask写的接口(base64, 二进制, 上传视频流)+异步+gunicorn部署Flask服务+多gpu卡部署

一.flask写的接口

1.1 manage.py启动服务(发送图片base64版)

这里要注意的是用docker的话,记得端口映射

#coding:utf-8
import base64
import io
import logging
import pickle

from flask import Flask, jsonify, request
from PIL import Image
from sklearn import metrics

logging.basicConfig(
    format="%(asctime)s %(levelname)s: %(message)s",
    level=logging.INFO,
    datefmt="%Y-%m-%d %H:%M:%S",
)

app = Flask(__name__)

@app.route("/evaluate", methods=["POST"])
def evaluate():
    """评价指标"""
    logging.info("Call evaluate")
    truth = request.json["truth"]
    predcition = request.json["prediction"]
    accuracy = metrics.accuracy_score(truth, predcition)
    f1 = metrics.f1_score(truth, predcition, average="macro")
    precision = metrics.precision_score(truth, predcition, average="macro")
    recall = metrics.recall_score(truth, predcition, average="macro")
    return jsonify(
        {"accuracy": accuracy, "precision": precision, "recall": recall, "f1": f1}
    )

@app.route("/ocr", methods=["POST"])
def ocr():
    """图像分析 OCR"""
    logging.info("OCR")
    base64str = request.json["img"]
    # print('base64str:',base64str)
    img = Image.open(io.BytesIO(base64.b64decode(base64str)))
    print('img:',img.size)
    # text = pytesseract.image_to_string(Image.open(io.BytesIO(img)), lang="chi_sim")
    return jsonify({"text": 'Success'})

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=6006)

1.2.test_route  测试路由文件(发送图片base64版)

#coding:utf-8
from io import BytesIO
from PIL import Image
import base64
import json
import re
import requests

def image_to_base64(img_path):
    with open(img_path, "rb") as f:  # 转为二进制格式
        data_base64 = base64.b64encode(f.read()).decode()  # 使用base64进行加密
    return data_base64

def base64_to_image(base64_str):
    base64_data = re.sub('^data:image/.+;base64,', '', base64_str)
    byte_data = base64.b64decode(base64_data)
    image_data = BytesIO(byte_data)
    img = Image.open(image_data)
    return img

def json_send(dataPModel,url):
    headers = {"Content-type": "application/json", "Accept": "text/plain", "charset": "UTF-8"}
    response = requests.post(url=url, headers=headers, data=json.dumps(dataPModel))
    # print('response:',response)
    return json.loads(response.text)

if __name__ == "__main__":
    url = 'http://192.168.102.193:1112/ocr'
    img = Image.open('haha.png').convert('RGB')
    print('img.size:', img.size)
    img_base64 = image_to_base64('haha.png')

    dataPModel = {}
    dataPModel['img'] = img_base64
    # dataPModel['uid'] = "0x031"
    print('dataPModel:', dataPModel)
    result = json_send(dataPModel, url)
    print(result['text'])

服务器返回结果:

本地返回结果:

2.1.manage.py启动服务(发送图片二进制版)

#coding:utf-8
"""
fzh created on 2020/06/28
"""
import logging
logging.basicConfig(
    format="%(asctime)s %(levelname)s: %(message)s",
    level=logging.INFO,
    datefmt="%Y-%m-%d %H:%M:%S",
)
import os
import base64
import io
from PIL import Image
import os
from flask import Flask, jsonify, request
import cv2
import glob
import numpy as np
import json
import datetime
import time
import re
import random

app = Flask(__name__)


@app.route("/express_reco", methods=["POST"])
def express_reco():
    logging.info('====快递单接收图片成功====')
    st1_time = time.time()
    algirm_info = {}
    path = './algrim_img'
    os.makedirs(path, exist_ok=True)
    

    #二进制图片方式
    name_ = random.randint(0, 1000)
    data_binary = request.files['encode_data']
    img_path = os.path.join(path, str(name_)+'.jpg')
    data_binary.save(img_path)#data_binary.filename
    img = cv2.imread(img_path)
   
if __name__ == "__main__":
    app.run(host="0.0.0.0", port=6006)#注意部署要改为6006

2.2.test_route  测试路由文件(发送图片二进制版)

#coding:utf-8
import json
import os
import requests
import base64

def json_send(url,dataPModel):
    # header = {"Content-type": "application/json", "Accept": "text/plain", "charset": "UTF-8"}
    header = {'Content-Type': 'application/json'}
    # response = requests.post(url=url, headers=header, data=json.dumps(dataPModel))
    response = requests.post(url=url, files=dataPModel)

    # print('response:', response)
    return json.loads(response.text)

def send_express_reco():
    url = 'http://192.168.102.191:3112/express_reco'
    dataPModel = {}

    import cv2
    img_path = './快递单原始数据'
    imgs_list_path = [os.path.join(img_path, i) for i in os.listdir(img_path)]

    for i, img_list_path in enumerate(imgs_list_path[:10]):
        print('==img_list_path:', img_list_path)
        dataPModel['encode_data'] = open(img_list_path, 'rb')
        result = json_send(url, dataPModel)
        print('result:', result)

    print('==imgs_list_path[0]:',imgs_list_path[0])
    for i in range(10):
        dataPModel['encode_data'] = open(imgs_list_path[0], 'rb')
        result = json_send(url, dataPModel)
        print('result:', result)

3.1 flask上传视频流

(1)代码结构:

其中index.html用来渲染页面,app.py用来起服务

(2)index.html代码:

<!doctype html>
<html lang="en">
<head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css"
          integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">

    <title>Live Streaming Demonstration</title>
</head>
<body>
<div class="container">
    <div class="row">
        <div class="col-lg-8  offset-lg-2">
            <h3 class="mt-5">视频显示</h3>
            <img src="{{ url_for('video_feed') }}" width="100%">
        </div>
    </div>
</div>
</body>
</html>

(3)app.py代码:

#coding:utf-8
from flask import Flask, render_template, Response
import cv2

app = Flask(__name__)
camera = cv2.VideoCapture(0)  # use 0 for web camera
# Use Ip Camera/CCTV/RTSP Link
# cv2.VideoCapture('rtsp://username:password@camera_ip_address:554/user=username_password='password'_channel=channel_number_stream=0.sdp')
### Example RTSP Link
# cv2.VideoCapture('rtsp://mamun:123456@101.134.16.117:554/user=mamun_password=123456_channel=0_stream=0.sdp') ```
def gen_frames():  # generate frame by frame from camera
    while True:
        # Capture frame-by-frame
        success, frame = camera.read()  # read the camera frame
        # print('===frame.shape', frame.shape)
        if not success:
            break
        else:
            ret, buffer = cv2.imencode('.jpg', frame)
            frame = buffer.tobytes()

            yield (b'--frame\r\n'
                   b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')  # concat frame one by one and show result


@app.route('/video_feed')
def video_feed():
    #Video streaming route. Put this in the src attribute of an img tag
    return Response(gen_frames(), mimetype='multipart/x-mixed-replace; boundary=frame')

@app.route('/video', methods=["get"])
def index():
    """Video streaming home page."""
    return render_template('index.html')


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

python app.py启动服务即可

3.2查看视频流

二.开异步:

https://docs.python.org/3/library/concurrent.futures.html#concurrent.futures.ThreadPoolExecutor

from concurrent.futures import ThreadPoolExecutor
executor = ThreadPoolExecutor(1)

executor.submit(second_send_houduan,json_info)

注意传递参数要放在外面

#coding:utf-8
from threading import Thread
import os
import base64
import io
import logging
import pickle
from whole_image_detect_first_plate import main_plate
from whole_image_detect_second_recognize import main_recoginze
from third_title_word_recognize import main_title_word_recoginze
from flask import Flask, jsonify, request
from PIL import Image
from config import model_title_detect, model_word_detect,crnn_model
# from sklearn import metrics
import requests
import json
import time
from time import sleep
from sql_tools import *
import asyncio
from multiprocessing import Process, Pool

from concurrent.futures import ThreadPoolExecutor
executor = ThreadPoolExecutor(1)

logging.basicConfig(
    format="%(asctime)s %(levelname)s: %(message)s",
    level=logging.INFO,
    datefmt="%Y-%m-%d %H:%M:%S",
)

app = Flask(__name__)

def json_send_head(dataPModel,url):
    # headers = {"Content-type": "application/json", "Accept": "text/plain", "charset": "UTF-8"}
    response = requests.post(url=url, data=dataPModel)
    # print('response:',response)
    return json.loads(response.text)


#第二次算法返回的结果
def second_send_houduan(json_info):
    print('entrance second houduan!!!')
    # 发给后端
    url = 'http://tc.aa.zhangzb.site:9091/api/page/plateGetJson'
    dataPmodel = {}
    if len(json_info):
        info = main_recoginze(json_info, model_title_detect, model_word_detect, crnn_model)
        dataPmodel['json'] = json.dumps(info)
        text = json_send_head(url, dataPmodel)
        print('text:', text)
    else:
        dataPmodel = {}
        info = {'NO': 'NO JSON INFO!!'}
        dataPmodel['json'] = json.dumps(info)
        json_send_head(url, dataPmodel)

#第二次对接,后端发给我版面框划分好后传的json信息
@app.route("/second_recognize", methods=["POST"])
def second_recognize():
    logging.info("second_recognize")
    str_info = request.json["json"]
    json_info = json.loads(str_info)
    # json_info = str_info #自己调试用
    print('json_info:', json_info)
    executor.submit(second_send_houduan,json_info)
    # print('len(json_info):', len(json_info))
    data = {}
    if len(json_info):
        data['msg'] = ''
        data['code'] = '200'
    else:
        data['msg'] = '接收的json有问题'
        data['code'] = '201'

    return jsonify(data)


if __name__ == "__main__":
    app.run(host="0.0.0.0", port=6006)


三.gunicorn部署Flask服务

pip install gunicorn

gunicorn命令启动

gunicorn -w 4 -b ip:port xxx:app启动一个Flask应用

例如:gunicorn -w 4 -b 0.0.0.0:6006 manage:app

  • -w 4是指预定义的工作进程数为4,
  • -b 127.0.0.1:4000指绑定地址和端口
  • manage是flask的启动python文件,app则是flask应用程序实例 
# run.py
from flask import Flask
app = Flask(__name__)

进行配置config.py

# gunicorn config
workers = 6  # must be 1, because of gpu
# threads = 4
bind = "0.0.0.0:6006"
worker_class = "gevent"
worker_connections = 1500
timeout = 60
loglevel = "debug"
accesslog = "-"
errorlog = "-"
daemon = False
pidfile = "master_pid"

启动的时候:gunicorn  -c ./config.py manage:app

退出gunicorn,通过下面命令查看

pstree -ap|grep gunicorn

在kill即可。

四.多GPU卡部署

 

 

 

参考:https://blog.miguelgrinberg.com/post/video-streaming-with-flask

  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是 Flask 应用程序的示例代码,用于将二进制图像发送到服务器并从服务器接收二进制图像。在这个示例中,我们将在客户端和服务器之间使用 HTTP POST 请求来发送和接收二进制图像。 发送二进制图片的客户端代码: ```python import requests url = 'http://localhost:5000/upload_image' filename = 'image.jpg' with open(filename, 'rb') as f: data = f.read() response = requests.post(url, data=data, headers={"Content-Type": "image/jpeg"}) ``` 在这个例子中,我们首先打开二进制图片文件,然后将图片数据读取到一个变量中。接下来,我们使用 requests 库的 post 方法发送 HTTP POST 请求到服务器。请求的数据是二进制图片数据,Content-Type 头部指定为 image/jpeg。 接收二进制图片的服务器端代码: ```python from flask import Flask, request, send_file app = Flask(__name__) @app.route('/upload_image', methods=['POST']) def upload_image(): # 获取二进制图片 image_data = request.data # 将图片保存到文件中 with open('received_image.jpg', 'wb') as f: f.write(image_data) # 返回图片 return send_file('received_image.jpg', mimetype='image/jpeg') if __name__ == '__main__': app.run() ``` 在这个例子中,我们定义了一个名为 upload_image 的路由,用于接收 HTTP POST 请求。在请求中,我们使用 request 对象的 data 属性获取二进制图片数据。接下来,我们将图片数据保存到 received_image.jpg 文件中,并将文件返回给客户端。使用 Flask 的 send_file 函数可以轻松地将文件发送回客户端。 需要注意的是,这个例子中没有使用 base64 编码来输图片数据,因此可以更快地输大量的图片数据。但是,需要注意的是,以这种方式输的图片数据不能直接在 HTML 中使用。如果需要在 HTML 中显示图片,需要将图片数据转换为 base64 编码,并将编码后的数据插入到 HTML 中。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值