7

I am trying to return an image in FastAPI after comparing two images using Opencv.

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?

4
  • Do you mind pasting the requirements? Commented Jun 13, 2020 at 18:53
  • @MarceloTrylesinski , I want to return an image using fastapi , is that possible? Commented Jun 13, 2020 at 21:42
  • Does How do I return an image in fastAPI? answer your question? Commented Jun 14, 2020 at 18:05
  • Does this answer your question? How do I return an image in fastAPI? Commented Jun 29, 2021 at 4:21

3 Answers 3

26

Yes you can return an image with FastAPI, it's actually so simple.

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:

AssertionError: 'aiofiles' must be installed to use FileResponse

If you have an image as bytes consider using 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")

Sign up to request clarification or add additional context in comments.

1 Comment

i did install aiofiles, but still getting the same error
2

The solution can be found here. You are converting the Opencv Image before encoding it in the 3rd line.

    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 = 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}

Comments

1

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

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? (note: the solutions are in javascript, but it's quite easy to adapt it for python)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.