The Problem:
Given a YOLO8 segmentation result, I need to create a binary mask representing all objects belonging to a specific class within the image. Additionally, I seek an efficient and elegant solution, potentially using a provided utility function or avoiding explicit looping mechanisms.
The Solutions:
Solution 1: Using torch operations
To create a mask from a YOLO8 segmentation result, you can use the following steps:
- Get the segmentation mask from the result.
- Convert the segmentation mask to a binary mask by thresholding it at 0.5.
- Resize the binary mask to the size of the original image.
- Multiply the binary mask with the original image to create the final mask.
Here is an example code that demonstrates these steps:
import cv2
import numpy as np
import torch
# Load the YOLO8 model and image
model = YOLOv8(weights='yolov8m-seg.pt')
image = cv2.imread('image.jpg')
# Get the segmentation result
result = model(image)
# Get the segmentation mask
mask = result.segmentation_mask()
# Convert the segmentation mask to a binary mask
binary_mask = np.where(mask > 0.5, 1, 0)
# Resize the binary mask
resized_mask = cv2.resize(binary_mask, (image.shape[1], image.shape[0]))
# Multiply the binary mask with the original image
final_mask = resized_mask * image
# Save the final mask
cv2.imwrite('mask.jpg', final_mask)
This code will create a mask that contains the segmented objects in the image. The mask will be saved as a JPEG file.
Solution 2: How to create a binary mask from a yolo8 segmentation result without loop
The given code can be improved by using the torch.any()
function to create a binary mask without a loop. Here’s the revised code:
from ultralytics import YOLO
import cv2
import torch
from pathlib import Path
# Load a pretrained YOLOv8n-seg Segment model
model = YOLO("weights/best.pt")
# Run inference on an image
results = model("images/img (1).jpg") # results list
# Extract the masks and classes
masks = results[0].masks.data
classes = results[0].boxes.data[:, 5]
# Create a binary mask for all objects with a specific class (e.g., class 0)
# Check if class 0 exists in the predictions
class_0_indices = torch.where(classes == 0)
if class_0_indices[0].shape[0] > 0:
class_0_masks = masks[class_0_indices]
class_0_mask = torch.any(class_0_masks, dim=0).int() * 255
cv2.imwrite("class_0_mask.jpg", class_0_mask.cpu().numpy())
This code will create a binary mask for all objects with class 0 without the need for a loop.
Q&A
How can I make a binary mask out of a yolo8 segmentation result?
Extract the people segmentations using the bbox classes. You will get an array of shape [channels, w, h]
. Then you can use any
over the channel dimension (which is equal to the number of people) to flatten the multi-channel array into a single channel array.
Is there a utility function in the yolo8 library that can create a binary mask from a segmentation result?
No, there is no utility function in the yolo8 library to create a binary mask from a segmentation result.
Video Explanation:
The following video, titled "Image segmentation with Yolov8 custom dataset | Computer vision ...", provides additional insights and in-depth exploration related to the topics discussed in this post.
Image segmentation with Yolov8 custom dataset | Computer vision tutorial. 41K views · 10 months ago #yolov8 #computervision #python ...more ...
The following video, titled "Image segmentation with Yolov8 custom dataset | Computer vision ...", provides additional insights and in-depth exploration related to the topics discussed in this post.
Image segmentation with Yolov8 custom dataset | Computer vision tutorial. 41K views · 10 months ago #yolov8 #computervision #python ...more ...