http - 如何解码从服务器发送到 Flutter 应用程序的图像?
问题描述
我正在将我的 json 响应从服务发送到我的 Flutter 应用程序。API 处理从移动设备获取图像到服务器并检测对象。检测后,从服务器发送的响应正文是一个图像,该图像具有对图像中检测到的类的注释。我正在向它发送一个在 toString() 的帮助下编码的编码图像文件。服务器端代码:
import time
from absl import app, logging
import cv2
import numpy as np
import tensorflow as tf
from yolov3_tf2.models import (
YoloV3, YoloV3Tiny
)
from yolov3_tf2.dataset import transform_images, load_tfrecord_dataset
from yolov3_tf2.utils import draw_outputs
from flask import Flask, request, Response, jsonify, send_from_directory, abort
import os
# customize your API through the following parameters
classes_path = './data/labels/obj.names'
weights_path = './weights/yolov3-tiny.tf'
tiny = True # set to True if using a Yolov3 Tiny model
size = 416 # size images are resized to for model
output_path = './detections/' # path to output folder where images with detections are saved
num_classes = 1 # number of classes in model
# load in weights and classes
physical_devices = tf.config.experimental.list_physical_devices('GPU')
if len(physical_devices) > 0:
tf.config.experimental.set_memory_growth(physical_devices[0], True)
if tiny:
yolo = YoloV3Tiny(classes=num_classes)
else:
yolo = YoloV3(classes=num_classes)
yolo.load_weights(weights_path).expect_partial()
print('weights loaded')
class_names = [c.strip() for c in open(classes_path).readlines()]
print('classes loaded')
# Initialize Flask application
app = Flask(_name_)
# API that returns image with detections on it
@app.route('/image', methods= ['POST'])
def get_image():
image = request.files["images"]
image_name = image.filename
image.save(os.path.join(os.getcwd(), image_name))
img_raw = tf.image.decode_image(
open(image_name, 'rb').read(), channels=3)
img = tf.expand_dims(img_raw, 0)
img = transform_images(img, size)
t1 = time.time()
boxes, scores, classes, nums = yolo(img)
t2 = time.time()
print('time: {}'.format(t2 - t1))
print('detections:')
for i in range(nums[0]):
print('\t{}, {}, {}'.format(class_names[int(classes[0][i])],
np.array(scores[0][i]),
np.array(boxes[0][i])))
img = cv2.cvtColor(img_raw.numpy(), cv2.COLOR_RGB2BGR)
img = draw_outputs(img, (boxes, scores, classes, nums), class_names)
cv2.imwrite(output_path + 'detection.jpg', img)
print('output saved to: {}'.format(output_path + 'detection.jpg'))
# prepare image for response
_, img_encoded = cv2.imencode('.jpg', img)
response = img_encoded.tostring()
#remove temporary image
os.remove(image_name)
try:
return Response(response=response, status=200, mimetype='image/jpg')
except FileNotFoundError:
abort(404)
if _name_ == '_main_':
app.run(debug=True, host = '0.0.0.0', port=5000)
客户端代码
final String url_API = "http://18b8b114.ngrok.io/image"; //Post the image to the Object detection API for classification Future <Response> dio_upload(String imagePath) async {
http.MultipartRequest request = http.MultipartRequest('POST', Uri.parse(url_API));
request.files.add(
await http.MultipartFile.fromPath(
'images',
image.path,
contentType: MediaType('application', 'jpeg'),
),
);
http.StreamedResponse response = await request.send();
print(response.statusCode);
print(await response.stream.transform(utf8.decoder).join());
最后一个打印语句引发错误,指出错误的 UTF 字符串。我应该以什么形式解码响应?这是我唯一知道的 MultipartRequest 代码。
解决方案
好吧,创建一个 static_url_path 并访问图像将很容易完成这项工作。
app = Flask(__name__, static_url_path='/static')
此外,创建从目录发送的路由也可以完美运行。
@app.route('/result')
def send_js():
return send_from_directory('static/images', 'detection.jpg')
然后简单地在颤振中使用 NetworkImage 可以帮助获取图像:)
推荐阅读
- bash - 如何在 Bash 脚本中使用 JQ 通过变量修改 json 文件?
- visual-studio - 调试时,Visual Studio 输出窗口转到“显示来自:生成的输出”
- qt - 设置媒体源后无需等待即可读取 QMediaMetaData
- mediapipe - Mediapipe facemesh 顶点映射
- flutter - 雪碧没有出现在使用火焰的颤振应用程序中
- selenium - Selenium Python,通过网站解析,打开新标签,然后抓取?
- c# - 移动到另一个项目时,现有的实体框架迁移不起作用
- linux - tcsh 脚本函数应该有洋红色显示蓝色
- ldap - JBoss HA 在一个事务中发送两次 ldap 身份验证请求,导致用户锁定在最大尝试次数的一半
- javascript - JQuery .width() 不会改变宽度