简体   繁体   English

如何在 fastAPI 中返回图像

[英]How to return an image in fastAPI

I am trying to return an image in fastAPI after comparing two images using Opencv.在使用 Opencv 比较两个图像后,我试图在 fastAPI 中返回一个图像。

Here's what I have done so far:这是我到目前为止所做的:

from fastapi import FastAPI , File, UploadFile
import numpy as np
from cv2 import *
import os
import base64


app = FastAPI(debug = True)


@app.post("/uploadfile/")
async def create_upload_file(file: UploadFile = File(...),file1: UploadFile = File(...)):
    content = await file.read()
    nparr = np.fromstring(content, np.uint8)
    img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)

    content1 = await file1.read()
    nparr1 = np.fromstring(content1, np.uint8)
    img1 = cv2.imdecode(nparr1, cv2.IMREAD_COLOR)

    akaze = cv2.AKAZE_create()
    kpts1, desc1 = akaze.detectAndCompute(img, None)
    kpts2, desc2 = akaze.detectAndCompute(img1, None)
    matcher = cv2.DescriptorMatcher_create(cv2.DescriptorMatcher_BRUTEFORCE_HAMMING)
    matches_1 = matcher.knnMatch(desc1, desc2, 2)
    good_points = []
    for m,n in matches_1:
            if m.distance < 0.7 * n.distance:
                good_points.append(m)
    mat = (round(len(kpts2)/len(good_points),2))

where I am getting an error我在哪里出错

    return_img = cv2.processImage(img)
    _, encoded_img = cv2.imencode('.PNG', return_img)
    encoded_img = base64.b64encode(return_img)

    return {"The similarity is": mat,'encoded_img': endcoded_img}

What am I doing wrong?我究竟做错了什么?

Yes you can return an image with FastAPI, it's actually so simple.是的,您可以使用 FastAPI 返回图像,它实际上非常简单。

from fastapi import FastAPI
from fastapi.responses import FileResponse

some_file_path = "some_image.jpeg"
app = FastAPI()


@app.get("/")
async def main():
    return FileResponse(some_file_path)

Make sure to install aiofiles with pip install aiofiles otherwise, you'll be getting an error like this:确保使用 pip install aiofiles pip install aiofiles否则,您将收到如下错误:

AssertionError: 'aiofiles' must be installed to use FileResponse

If you have an image as bytes consider using StreamingResponse如果您将图像作为字节考虑使用StreamingResponse

from io import BytesIO

@app.post("/send_image")
async def send():
    image = BytesIO()
    img =                                        # Do something here to create an image
    img.save(image, format='JPEG', quality=85)   # Save image to BytesIO
    image.seek(0)                                # Return cursor to starting point
    return StreamingResponse(image.read(), media_type="image/jpeg")

If you want to return the image only, then return the image itself with the correct encoding in the header see Return a Response Directly如果您只想返回图像,则使用 header 中的正确编码返回图像本身,请参阅直接返回响应

If you need to also return other information with the image in the json, then see this SO question How do you put an image file in a json object?如果您还需要使用 json 中的图像返回其他信息,请参阅这个 SO 问题How do you put an image file in a json object? (note: the solutions are in javascript, but it's quite easy to adapt it for python) (注意:解决方案在 javascript 中,但很容易适应 python)

The solution can be found here .可以在这里找到解决方案。 You are converting the Opencv Image before encoding it in the 3rd line.您正在转换 Opencv 图像,然后再将其编码到第 3 行。

    return_img = cv2.processImage(img)
    _, encoded_img = cv2.imencode('.PNG', return_img)
    encoded_img = base64.b64encode(return_img)

    return {"The similarity is": mat,'encoded_img': endcoded_img}

Replace return_img with encoded_img and everything should be working as expected.return_img替换为encoded_img ,一切都应该按预期工作。

    return_img = cv2.processImage(img)
    _, encoded_img = cv2.imencode('.PNG', return_img)
    encoded_img = base64.b64encode(encoded_img)

    return {"The similarity is": mat,'encoded_img': endcoded_img}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM