ultralytics / ultralytics

NEW - YOLOv8 🚀 in PyTorch > ONNX > OpenVINO > CoreML > TFLite
https://docs.ultralytics.com
GNU Affero General Public License v3.0
28.58k stars 5.68k forks source link

YOLOv8 Onnx Deploy #14968

Open ProgrammerZhujinming opened 1 month ago

ProgrammerZhujinming commented 1 month ago

Search before asking

Question

Hi! I trained the yolov8 model with my custom dataset. I export the model as onnx format and it only accept input with shape(640640), but when I use the model to interface my test image which has the resolution about 1944 2592, I found it will resize my image to 480 640 and object can be detected. But the onnx weight can only accept the input with 640 640. I read the code about preprocess but I cannot find some code to handle this situation.
` stride = 32

ori_img = cv2.imread("datasets/yimu/images/train/11.bmp")
h, w, c = ori_img.shape

shape = ori_img.shape[:2]  # current shape [height, width]
new_shape = [640, 640]

r = min(new_shape[0] / shape[0], new_shape[1] / shape[1])

# Compute padding
ratio = r, r  # width, height ratios
new_unpad = int(round(shape[1] * r)), int(round(shape[0] * r))
dw, dh = new_shape[1] - new_unpad[0], new_shape[0] - new_unpad[1]  # wh padding

dw, dh = np.mod(dw, stride), np.mod(dh, stride)  # wh padding

dw /= 2  # divide padding into 2 sides
dh /= 2

if shape[::-1] != new_unpad:  # resize
    ori_img = cv2.resize(ori_img, new_unpad, interpolation=cv2.INTER_LINEAR)

#top, bottom = int(round(dh - 0.1))
#left, right = int(round(dw - 0.1))

top, bottom = 0, int(round(dh + 0.1))
left, right = 0, int(round(dw + 0.1))

ori_img = cv2.copyMakeBorder(
    ori_img, top, bottom, left, right, cv2.BORDER_CONSTANT, value=(114, 114, 114)
)  # add border

ori_img = np.expand_dims(ori_img, axis=0)

ori_img = ori_img[..., ::-1].transpose((0, 3, 1, 2))  # BGR to RGB, BHWC to BCHW, (n, 3, h, w)
ori_img = np.ascontiguousarray(ori_img)  # contiguous
img_tensor = torch.from_numpy(ori_img)

img_tensor = img_tensor / 255

` this is important because if I cannot keep consistent with your handling method I cannot get the correct result. Actually, I use Triton to deploy the model, so if I need another ways to keep my input consistent with the training process, please offer me related code to solve this problem. Thanks for your reply.

Additional

No response

pderrenger commented 1 month ago

@ProgrammerZhujinming thank you for your detailed question. It seems like the issue arises from the preprocessing steps required to maintain consistency between training and inference. When exporting to ONNX, the model expects a fixed input size (640x640 in your case). To ensure consistent preprocessing, you need to replicate the same resizing and padding steps used during training.

For deployment with Triton, you should ensure that your preprocessing script resizes and pads the input images to 640x640, similar to the training process. This involves resizing the image while maintaining the aspect ratio and then padding it to the required size.

If you are still facing issues, please verify that you are using the latest version of the Ultralytics package. This ensures you have the latest bug fixes and improvements. For more detailed guidance on exporting and deploying YOLOv8 models to ONNX, you can refer to our ONNX Export Guide.

Feel free to reach out if you have any further questions.