YOLOv8与FASTAPI错误:在函数’imwrite_’中找不到指定扩展名的写入器。

huangapple go评论114阅读模式
英文:

YOLOv8 with FASTAPI error could not find a writer for the specified extension in function 'imwrite_'

问题

I have code to run YOLO in FastAPI:

from fastapi import FastAPI, UploadFile, File
from ultralytics import YOLO
from PIL import Image
import io

app = FastAPI()
model = YOLO('yolov8n.yaml')
model = YOLO('runs/detect/train/weights/best.pt')

@app.post("/detect")
async def detect(file: UploadFile = File(...)):
    contents = await file.read()
    img = Image.open(io.BytesIO(contents))
    results = model.predict(source=img, save=True)

    return {
        "result": str(results)
    }

Show error:

[WARNING] Application callable raised an exception
[ERROR] Exception in callback <built-in method _loop_step of builtins.CallbackTaskHTTP object at 0x163b3bd30>
handle: <Handle CallbackTaskHTTP._loop_step>
Traceback (most recent call last):
  File "uvloop/cbhandles.pyx", line 61, in uvloop.loop.Handle._run
  File "/lib/python3.10/site-packages/fastapi/applications.py", line 270, in __call__
    await super().__call__(scope, receive, send)
  File "/lib/python3.10/site-packages/starlette/applications.py", line 124, in __call__
    await self.middleware_stack(scope, receive, send)
  File "/lib/python3.10/site-packages/starlette/middleware/errors.py", line 184, in __call__
    raise exc
  File "/lib/python3.10/site-packages/starlette/middleware/errors.py", line 162, in __call__
    await this app(scope, receive, _send)
  File "/lib/python3.10/site-packages/starlette/middleware/exceptions.py", line 79, in __call__
    raise exc
  File "/lib/python3.10/site-packages/starlette/middleware/exceptions.py", line 68, in __call__
    await self.app(scope, receive, sender)
  File "/lib/python3.10/site-packages/fastapi/middleware/asyncexitstack.py", line 21, in __call__
    raise e
  File "/lib/python3.10/site-packages/fastapi/middleware/asyncexitstack.py", line 18, in __call__
    await self.app(scope, receive, send)
  File "/lib/python3.10/site-packages/starlette/routing.py", line 706, in __call__
    await route.handle(scope, receive, send)
  File "/lib/python3.10/site-packages/starlette/routing.py", line 276, in handle
    await self.app(scope, receive, send)
  File "/lib/python3.10/site-packages/starlette/routing.py", line 66, in app
    response = await func(request)
  File "/lib/python3.10/site-packages/fastapi/routing.py", line 235, in app
    raw_response = await run_endpoint_function(
  File "/lib/python3.10/site-packages/fastapi/routing.py", line 161, in run_endpoint_function
    return await dependant.call(**values)
  File "detections/main.py", line 20, in detect
    results = model.predict(source=img, save=True, project="foto_ayam")
  File "/lib/python3.10/site-packages/torch/utils/_contextlib.py", line 115, in decorate_context
    return func(*args, **kwargs)
  File "/lib/python3.10/site-packages/ultralytics/engine/model.py", line 254, in predict
    return self.predictor.predict_cli(source=source) if is_cli else self.predictor(source=source, stream=stream)
  File "/lib/python3.10/site-packages/ultralytics/engine/predictor.py", line 195, in __call__
    return list(this stream_inference(source, model, *args, **kwargs))  # merge list of Result into one
  File "/lib/python3.10/site-packages/torch/utils/_contextlib.py", line 35, in generator_context
    response = gen.send(None)
  File "/lib/python3.10/site-packages/ultralytics/engine/predictor.py", line 276, in stream_inference
    this save_preds(vid_cap, i, str(this save_dir / p.name))
  File "/lib/python3.10/site-packages/ultralytics/engine/predictor.py", line 330, in save_preds
    cv2.imwrite(save_path, im0)
cv2.error: OpenCV(4.6.0) /Users/xperience/actions-runner/_work/opencv-python/opencv-python/opencv/modules/imgcodecs/src/loadsave.cpp:730: error: (-2:Unspecified error) could not find a writer for the specified extension in function 'imwrite_'

But if parameter save=False everything works well:

results = model.predict(source=img, save=False)

I have also tried running detection YOLOv8 without FASTAPI, and everything works well. How to solve this bug? Thanks.

英文:

I have code to run yolo in fastapi :

from fastapi import FastAPI, UploadFile, File
from ultralytics import YOLO
from PIL import Image
import io

app = FastAPI()
model = YOLO('yolov8n.yaml')
model = YOLO('runs/detect/train/weights/best.pt')


@app.post("/detect")
async def detect(file: UploadFile = File(...)):
    contents = await file.read()
    img = Image.open(io.BytesIO(contents))
    results = model.predict(source=img, save=True)

    return {
            "result": str(results)
        }

Show error :

[WARNING] Application callable raised an exception
[ERROR] Exception in callback <built-in method _loop_step of builtins.CallbackTaskHTTP object at 0x163b3bd30>
handle: <Handle CallbackTaskHTTP._loop_step>
Traceback (most recent call last):
  File "uvloop/cbhandles.pyx", line 61, in uvloop.loop.Handle._run
  File "/lib/python3.10/site-packages/fastapi/applications.py", line 270, in __call__
    await super().__call__(scope, receive, send)
  File "/lib/python3.10/site-packages/starlette/applications.py", line 124, in __call__
    await self.middleware_stack(scope, receive, send)
  File "/lib/python3.10/site-packages/starlette/middleware/errors.py", line 184, in __call__
    raise exc
  File "/lib/python3.10/site-packages/starlette/middleware/errors.py", line 162, in __call__
    await self.app(scope, receive, _send)
  File "/lib/python3.10/site-packages/starlette/middleware/exceptions.py", line 79, in __call__
    raise exc
  File "/lib/python3.10/site-packages/starlette/middleware/exceptions.py", line 68, in __call__
    await self.app(scope, receive, sender)
  File "/lib/python3.10/site-packages/fastapi/middleware/asyncexitstack.py", line 21, in __call__
    raise e
  File "/lib/python3.10/site-packages/fastapi/middleware/asyncexitstack.py", line 18, in __call__
    await self.app(scope, receive, send)
  File "/lib/python3.10/site-packages/starlette/routing.py", line 706, in __call__
    await route.handle(scope, receive, send)
  File "/lib/python3.10/site-packages/starlette/routing.py", line 276, in handle
    await self.app(scope, receive, send)
  File "/lib/python3.10/site-packages/starlette/routing.py", line 66, in app
    response = await func(request)
  File "/lib/python3.10/site-packages/fastapi/routing.py", line 235, in app
    raw_response = await run_endpoint_function(
  File "/lib/python3.10/site-packages/fastapi/routing.py", line 161, in run_endpoint_function
    return await dependant.call(**values)
  File "detections/main.py", line 20, in detect
    results = model.predict(source=img, save=True, project="foto_ayam")
  File "/lib/python3.10/site-packages/torch/utils/_contextlib.py", line 115, in decorate_context
    return func(*args, **kwargs)
  File "/lib/python3.10/site-packages/ultralytics/engine/model.py", line 254, in predict
    return self.predictor.predict_cli(source=source) if is_cli else self.predictor(source=source, stream=stream)
  File "/lib/python3.10/site-packages/ultralytics/engine/predictor.py", line 195, in __call__
    return list(self.stream_inference(source, model, *args, **kwargs))  # merge list of Result into one
  File "/lib/python3.10/site-packages/torch/utils/_contextlib.py", line 35, in generator_context
    response = gen.send(None)
  File "/lib/python3.10/site-packages/ultralytics/engine/predictor.py", line 276, in stream_inference
    self.save_preds(vid_cap, i, str(self.save_dir / p.name))
  File "/lib/python3.10/site-packages/ultralytics/engine/predictor.py", line 330, in save_preds
    cv2.imwrite(save_path, im0)
cv2.error: OpenCV(4.6.0) /Users/xperience/actions-runner/_work/opencv-python/opencv-python/opencv/modules/imgcodecs/src/loadsave.cpp:730: error: (-2:Unspecified error) could not find a writer for the specified extension in function 'imwrite_'

But if parameter save=False everything work well :

 results = model.predict(source=img, save=False)

I am also has try running detection YOLOv8 without FASTAPI all work well. How to solve this bug ? Thanks

答案1

得分: 0

OpenCV需要在图像名称中包含扩展名才能保存图像,您可以在这里看到示例。在您的情况下,输出图像的名称会被Ultralytics的管道自动推断。根据在model.predict文档中回答的问题这里,您可以尝试指定输出图像的名称和文件夹:

model.predict(source=img, save=True, project='folder/path/', name='name_with_extension.jpg')

我没有尝试过,请告诉我它是否有效!

英文:

OpenCV need the extension in the name of an image to save it as you can see here for instance. In you case the name of the output image is automatically inferred by ultralytics' pipeline. According to questions answered in the model.predict doc here, you can try to specify the name and the folder of the output image:

model.predict(source=img, save=True, project='folder/path/', name='name_with_extension.jpg')

I didn't try it so please tell me if it works!

答案2

得分: 0

通过尝试和错误,我找到了一个解决方案:
问题是FastAPI的异步性质与YOLOv8的预测过程冲突。

解决方法是以同步方式运行YOLOv8的预测,与FastAPI应用程序分开。您可以创建一个单独的函数来处理YOLOv8的预测,并在FastAPI端点内调用它。这里是一个示例:

import numpy as np

# ...

def run_yolov8_detection(image):
    results = model.predict(source=image, save=True)
    return results


@app.post("/detect")
async def detect(file: UploadFile = File(...)):
    contents = await file.read()
    img = Image.open(io.BytesIO(contents))

    # 将PIL图像转换为NumPy数组
    img_np = np.array(img)

    results = run_yolov8_detection(img_np)

    return {
        "result": str(results)
    }

通过将YOLOv8的预测分离到一个单独的函数中,您可以确保它以同步方式运行,不会与FastAPI的异步性质冲突。这应该有助于解决您遇到的错误。

英文:

After trial and error, i found a solution :
The problems is asynchronous nature of FastAPI conflicting with the prediction process of YOLOv8.

Solution is to run the YOLOv8 prediction in a synchronous manner, separate from the FastAPI application. You can create a separate function to handle the YOLOv8 prediction and call it within the FastAPI endpoint. Here's an example:

import numpy as np

# ...

def run_yolov8_detection(image):
    results = model.predict(source=image, save=True)
    return results


@app.post("/detect")
async def detect(file: UploadFile = File(...)):
    contents = await file.read()
    img = Image.open(io.BytesIO(contents))

    # Convert PIL Image to NumPy array
    img_np = np.array(img)

    results = run_yolov8_detection(img_np)

    return {
        "result": str(results)
    }

By separating the YOLOv8 prediction into a separate function, you can ensure that it runs synchronously and doesn't conflict with the asynchronous nature of FastAPI. This should help in resolving the error you encountered.

huangapple
  • 本文由 发表于 2023年7月18日 16:16:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/76710772.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定