I edited the question after i experimented a bit more !
I am experimenting with yolo8.
I made a test script to show the problem:
#
# test script to explore multi contours for 1 found object.
import numpy as np
import cv2
img = cv2.imread('demo.jpg')
imgcopy = img.copy()
from ultralytics import YOLO
# Load a model
model = YOLO('yolov8n-seg.pt') # load an official model
#model = YOLO('path/to/best.pt') # load a custom model
# Predict with the model
results = model(img, retina_masks=True, save=True, imgsz = 640, conf=0.5, boxes=False, show_labels=False, show_conf=False, save_crop=True, save_txt=True, save_conf=True) # predict on an image
for result in results:
masks = result.masks
for mask in masks.data:
mask_np= mask.cpu().numpy().astype(np.uint8)
#contours, _ = cv2.findContours(mask_np, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours, _ = cv2.findContours(mask_np, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
print ('We found ' + str(len(contours)) + ' objects')
# i know i get 3 contours so this works !
imgcopy = cv2.drawContours(imgcopy, contours=contours[0], contourIdx=-1, color=(0, 255, 0), thickness=2, lineType=cv2.LINE_AA)
imgcopy = cv2.drawContours(imgcopy, contours=contours[1], contourIdx=-1, color=(255, 255, 0), thickness=2, lineType=cv2.LINE_AA)
imgcopy = cv2.drawContours(imgcopy, contours=contours[2], contourIdx=-1, color=(255,0, 255), thickness=2, lineType=cv2.LINE_AA)
cv2.imwrite('result.jpg', imgcopy)
I expected to find 1 contour but i find 3 contours in this example.
So 1 mask belongs to 1 found object but it has 3 contours.
Why is it finding multiple contours ?
How should i filter out the correct contour ? I found that the first found contour is not allways the correct one.