英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论