Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update outputs #239

Merged
merged 13 commits into from Jan 11, 2023
Merged

Update outputs #239

merged 13 commits into from Jan 11, 2023

Conversation

Laughing-q
Copy link
Member

@Laughing-q Laughing-q commented Jan 11, 2023

@AyushExel @glenn-jocher

  • make the Predictor a python generator, then there won't be a memory problem.
  • return segments coordinate instead of masks.

python interface usage:
segmentation:

model = YOLO("weights/yolov8n-seg.pt")
for output in model.predict(source="ultralytics/assets"):
    if output:
        print(output['det'].shape)   # ndarray, Nx6, include box, cls score and cls
        print(len(output['segment']))  # List[ndarray], each element is the corresponding coordinate of segment

detection:

model = YOLO("weights/yolov8n.pt")
for output in model.predict(source="ultralytics/assets"):
    if output:
        print(output['det'].shape)   # ndarray, Nx6, include box, cls score and cls

cls:

model = YOLO("weights/yolov8n-cls.pt")
for output in model.predict(source="ultralytics/assets"):
    if output:
        print(output['prob'].shape)   # ndarray, shape: (num_class, )

set a arg return_outputs to control whether to return outputs.
return_outputs=True by default in python interface.
return_outputs=False by default in cli mode.

If don't want the outputs in python interface, just set it to False.

model = YOLO("weights/yolov8n-cls.pt")
model.predict(source="ultralytics/assets", return_outputs=False):

🛠️ PR Summary

Made with ❤️ by Ultralytics Actions

🌟 Summary

Refactoring prediction functionality to support iterative result generation and optional result return in Ultralytics YOLO models.

📊 Key Changes

  • Modified tests to iterate through predictions instead of relying on a direct list length check.
  • Added an optional return_outputs flag to the predict() method to control the output behavior.
  • Updated predictors to act as generators yielding results upon each iteration if return_outputs is set to True.
  • Altered client-facing scripts to reflect generator behavior and handle the option of not returning outputs.
  • Removed unused accumulation of all_outputs in favor of yielding or returning individual predictions.

🎯 Purpose & Impact

  • Purpose: To enhance the prediction methods by providing more flexible output handling and allowing incremental processing of results.
  • Impact for Developers: More control over how prediction results are processed and presented, making integration into larger applications smoother.
  • Impact for Users: Potential for improved performance and memory usage when handling large numbers of predictions, as not all results need to be kept in memory at once. 🚀

@github-actions
Copy link

github-actions bot commented Jan 11, 2023

CLA Assistant Lite bot All Contributors have signed the CLA. ✅

@AyushExel
Copy link
Contributor

@Laughing-q okay perfect! let's discuss this later today. I'll add some docs so we have them at the same time as release

@glenn-jocher
Copy link
Member

recheck

@AyushExel
Copy link
Contributor

@Laughing-q do we have a function in place to convert segment coordinates to masks?

@Laughing-q
Copy link
Member Author

@AyushExel here, but it serves dataset. never tested independently.

def polygon2mask(imgsz, polygons, color=1, downsample_ratio=1):
"""
Args:
imgsz (tuple): The image size.
polygons (np.ndarray): [N, M], N is the number of polygons, M is the number of points(Be divided by 2).
color (int): color
downsample_ratio (int): downsample ratio
"""
mask = np.zeros(imgsz, dtype=np.uint8)
polygons = np.asarray(polygons)
polygons = polygons.astype(np.int32)
shape = polygons.shape
polygons = polygons.reshape(shape[0], -1, 2)
cv2.fillPoly(mask, polygons, color=color)
nh, nw = (imgsz[0] // downsample_ratio, imgsz[1] // downsample_ratio)
# NOTE: fillPoly firstly then resize is trying the keep the same way
# of loss calculation when mask-ratio=1.
mask = cv2.resize(mask, (nw, nh))
return mask

@AyushExel
Copy link
Contributor

okay got it. We can make something similar later

@glenn-jocher
Copy link
Member

@Laughing-q good to merge?

@AyushExel
Copy link
Contributor

@glenn-jocher yes..But we need to update docs before putting out stable release.. You can merge this.. I'll start another PR for docs

@glenn-jocher glenn-jocher changed the base branch from main to 8.0.3/fixes January 11, 2023 14:43
@glenn-jocher glenn-jocher merged commit 59c9f55 into 8.0.3/fixes Jan 11, 2023
@glenn-jocher glenn-jocher deleted the update_outputs branch January 11, 2023 14:43
@glenn-jocher
Copy link
Member

Merged into 8.0.3 fixes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants