1. 接收上传的图像文件

flask的接口定义如下,接收单张图像,返回检测结果。

@app.route('/detect', methods=['POST'])
def detect_api():
    try:
        file = request.files.get("file")
        if file is not None:
            detections = detect(file, tracker, device=device, classes=classes)
        else:
            return '上传文件失败'
    except:
        logger.exception('detect error')
        return 'detect error', 400

    return jsonify({'detections': detections})

对于file = request.files.get(“file”),打印file的类型:<class ‘werkzeug.datastructures.FileStorage’>

FileStorage无法用cv2.imread直接读取,有以下几种方式处理。

1.1 FileStorage先转成bytes,再转换成np.array

import numpy as np
imgbytes = file.read()
imgstring = np.array(imgbytes.tostring()
imgstring = np.asarray(bytearray(imgstring), dtype="uint8")
image = cv2.imdecode(imgstring, cv2.IMREAD_COLOR)

1.2 直接用PIL的Image.open

import cv2
import numpy as np
from PIL import Image
# 假设上传的图像是三通道,大小为: h=1080, w=810
image = Image.open(file)
print(image.size)  # (810, 1080), 是(w, h)的格式

# 转成cv2的格式
image_cv2 = np.array(image)  # 这里的image_cv2是RGB的格式,不是BGR的
print(image.shape)  # (1080, 810, 3), 是(h, w, c)的格式

1.3 利用imageio库来读取

(可能需要先pip install imageio-ffmpeg等相关的库)

import imageio
image = imageio.imread(file)
print(image.shape)  # 直接就是array的格式,返回的shape是(h, w, c),且是RGB格式

可以根据需要选择合适的方式,对接收的图像进行后续的处理。

2. 接收上传的视频文件

假设flask接口的定义跟上面的一样,接收的文件变成视频文件。

可以利用imageio.get_reader进行处理。(这里建议imageio的版本为2.9.0)

import imageio
import cv2

vid_reader = imageio.get_reader(file, 'ffmpeg')

# 遍历视频中的每一帧img,进行后续的处理
for index, img in enumerate(vid_reader.iter_data()):
    pass
    # img_bgr = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)

这里的img跟也是RGB格式的array数据,跟用imageio.imread得到的数据格式一致。

(处理视频流的方式后续再补充别的方法。)

总结:

  1. 有需要的话,可以先执行file = file.read(),把FileStorage格式先转成bytes,再进行后续的处理。
  2. 注意各个方式获取图像数据之后的格式,例如是RGB还是BGR的,shape(w, h)还是(h, w)等等。

结束。

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐