Phân lập các đối tượng phân đoạn
Sau khi thực hiện Tác vụ Phân đoạn, đôi khi bạn muốn trích xuất các đối tượng riêng biệt từ kết quả suy luận. Hướng dẫn này cung cấp một công thức chung về cách thực hiện việc này bằng cách sử dụng Chế độ Dự đoán của Ultralytics.
Hướng dẫn từng bước theo công thức
-
Xem phần Cài đặt nhanh Ultralytics để có hướng dẫn nhanh về cách cài đặt các thư viện cần thiết.
-
Tải một mô hình và chạy
predict()
phương pháp trên một nguồn.from ultralytics import YOLO # Load a model model = YOLO("yolo11n-seg.pt") # Run inference results = model.predict()
Không có đối số dự đoán?
Nếu không chỉ định nguồn, ảnh ví dụ từ thư viện sẽ được sử dụng:
'ultralytics/assets/bus.jpg' 'ultralytics/assets/zidane.jpg'
Điều này hữu ích cho việc kiểm tra nhanh chóng với
predict()
phương thức.Để biết thêm thông tin về Mô hình Phân đoạn, hãy truy cập Tác vụ phân đoạn trang. Để tìm hiểu thêm về
predict()
phương thức, xem Chế độ Dự đoán phần của Tài liệu.
-
Bây giờ lặp lại các kết quả và các đường viền. Đối với các quy trình làm việc muốn lưu hình ảnh vào tệp, hình ảnh nguồn
base-name
và phát hiệnclass-label
được truy xuất để sử dụng sau này (tùy chọn).from pathlib import Path import numpy as np # (2) Iterate detection results (helpful for multiple images) for r in res: img = np.copy(r.orig_img) img_name = Path(r.path).stem # source image base-name # Iterate each object contour (multiple detections) for ci, c in enumerate(r): # (1) Get detection class name label = c.names[c.boxes.cls.tolist().pop()]
- Để tìm hiểu thêm về cách làm việc với kết quả phát hiện, hãy xem Phần Hộp cho Chế độ Dự đoán.
- Để tìm hiểu thêm về
predict()
kết quả xem Làm việc với Kết quả cho Chế độ Dự đoán
Vòng lặp For
Một hình ảnh duy nhất sẽ chỉ lặp lại vòng lặp đầu tiên một lần. Một hình ảnh duy nhất chỉ với một lần phát hiện sẽ lặp lại mỗi vòng lặp chỉ một lần.
-
Bắt đầu bằng cách tạo mặt nạ nhị phân từ ảnh gốc, sau đó vẽ một đường viền được tô lên mặt nạ. Điều này sẽ cho phép đối tượng được cô lập khỏi các phần khác của hình ảnh. Một ví dụ từ
bus.jpg
cho một trong các đối tượng được phát hiệnperson
các đối tượng lớp được hiển thị ở bên phải.import cv2 # Create binary mask b_mask = np.zeros(img.shape[:2], np.uint8) # (1) Extract contour result contour = c.masks.xy.pop() # (2) Changing the type contour = contour.astype(np.int32) # (3) Reshaping contour = contour.reshape(-1, 1, 2) # Draw contour onto mask _ = cv2.drawContours(b_mask, [contour], -1, (255, 255, 255), cv2.FILLED)
-
Để biết thêm thông tin về
c.masks.xy
xem Phần Mặt Nạ từ Chế Độ Dự Đoán. -
Ở đây, các giá trị được chuyển đổi thành
np.int32
để tương thích vớidrawContours()
function từ OpenCV. -
OpenCV
drawContours()
function yêu cầu đường viền có hình dạng[N, 1, 2]
mở rộng phần bên dưới để biết thêm chi tiết.
Mở rộng để hiểu điều gì đang xảy ra khi xác định
contour
biến.-
c.masks.xy
:: Cung cấp tọa độ của các điểm đường viền mặt nạ theo định dạng(x, y)
. Để biết thêm chi tiết, hãy tham khảo Phần Mặt Nạ từ Chế Độ Dự Đoán. -.pop()
:: Nhưmasks.xy
là một danh sách chứa một phần tử duy nhất, phần tử này được trích xuất bằng cách sử dụngpop()
phương pháp. -.astype(np.int32)
:: Sử dụngmasks.xy
sẽ trả về với kiểu dữ liệu làfloat32
, nhưng điều này sẽ không tương thích với OpenCVdrawContours()
function, vì vậy điều này sẽ thay đổi kiểu dữ liệu thànhint32
để tương thích. -.reshape(-1, 1, 2)
:: Định dạng lại dữ liệu thành hình dạng cần thiết của[N, 1, 2]
trong đóN
là số lượng điểm đường viền, với mỗi điểm được biểu diễn bằng một mục duy nhất1
, và mục nhập bao gồm2
giá trị. Các-1
biểu thị số lượng giá trị dọc theo chiều này là linh hoạt.Mở rộng để xem giải thích về
drawContours()
cấu hình.- Đóng gói
contour
biến trong dấu ngoặc vuông,[contour]
- Được chứng minh là tạo ra mặt nạ đường viền mong muốn hiệu quả trong quá trình kiểm thử. - Giá trị-1
được chỉ định chodrawContours()
tham số hướng dẫn hàm vẽ tất cả các đường viền hiện diện trong hình ảnh. - Cáituple
(255, 255, 255)
đại diện cho màu trắng, là màu mong muốn để vẽ đường viền trong mặt nạ nhị phân này. - Việc bổ sungcv2.FILLED
sẽ tô màu tất cả các pixel nằm trong biên giới đường viền, trong trường hợp này, tất cả các pixel nằm trong sẽ có màu trắng. - Xem Tài liệu OpenCV vềdrawContours()
để biết thêm thông tin.
-
-
Tiếp theo, có 2 tùy chọn về cách tiến hành với hình ảnh từ thời điểm này và một tùy chọn tiếp theo cho mỗi tùy chọn.
Các Tùy Chọn Cô Lập Đối Tượng
Ví dụ
# Create 3-channel mask mask3ch = cv2.cvtColor(b_mask, cv2.COLOR_GRAY2BGR) # Isolate object with binary mask isolated = cv2.bitwise_and(mask3ch, img)
Điều này hoạt động như thế nào?
-
Đầu tiên, mặt nạ nhị phân được chuyển đổi từ ảnh một kênh thành ảnh ba kênh. Việc chuyển đổi này là cần thiết cho bước tiếp theo, nơi mặt nạ và ảnh gốc được kết hợp. Cả hai ảnh phải có cùng số lượng kênh để tương thích với thao tác trộn.
-
Hình ảnh gốc và mặt nạ nhị phân ba kênh được hợp nhất bằng hàm OpenCV
bitwise_and()
. Thao tác này giữ lại chỉ giá trị pixel lớn hơn không(> 0)
từ cả hai hình ảnh. Vì các pixel mặt nạ lớn hơn không(> 0)
chỉ trong vùng đường viền, các pixel còn lại từ ảnh gốc là những pixel chồng lên đường viền.
Cô lập bằng Pixel đen: Các tùy chọn phụ
Ảnh kích thước đầy đủ
Không cần thêm bước nào nếu giữ nguyên kích thước ảnh đầy đủ.
Ví dụ: Đầu ra kích thước đầy đủ Ảnh đối tượng đã cắt
Các bước bổ sung cần thiết để cắt ảnh chỉ bao gồm vùng đối tượng.
# (1) Bounding box coordinates x1, y1, x2, y2 = c.boxes.xyxy.cpu().numpy().squeeze().astype(np.int32) # Crop image to object region iso_crop = isolated[y1:y2, x1:x2]
- Để biết thêm thông tin về kết quả khung giới hạn, hãy xem Phần Khung từ Chế độ Dự đoán
Đoạn mã này làm gì?
-
Hàm
c.boxes.xyxy.cpu().numpy()
gọi truy xuất các hộp giới hạn dưới dạng một mảng NumPy trongxyxy
định dạng, trong đóxmin
,ymin
,xmax
, vàymax
biểu thị tọa độ của hình chữ nhật bao quanh. Xem Phần Boxes từ Chế độ Dự đoán để biết thêm chi tiết. -
Hàm
squeeze()
operation loại bỏ mọi chiều không cần thiết khỏi mảng NumPy, đảm bảo nó có hình dạng như mong đợi. -
Chuyển đổi các giá trị tọa độ bằng cách sử dụng
.astype(np.int32)
thay đổi kiểu dữ liệu tọa độ hộp từfloat32
đếnint32
, giúp chúng tương thích để cắt ảnh bằng cách sử dụng các lát chỉ mục. -
Cuối cùng, vùng bounding box được cắt từ ảnh bằng cách sử dụng index slicing. Các ranh giới được xác định bởi
[ymin:ymax, xmin:xmax]
tọa độ của hộp giới hạn phát hiện.
# Isolate object with transparent background (when saved as PNG) isolated = np.dstack([img, b_mask])
Điều này hoạt động như thế nào?
- Sử dụng NumPy
dstack()
function (xếp chồng mảng dọc theo trục độ sâu) kết hợp với mặt nạ nhị phân được tạo ra, sẽ tạo ra một hình ảnh với bốn kênh. Điều này cho phép tất cả các pixel bên ngoài đường viền đối tượng trở nên trong suốt khi lưu dưới dạngPNG
tập tin.
Cô lập bằng Pixel trong suốt: Các tùy chọn phụ
Ảnh kích thước đầy đủ
Không cần thêm bước nào nếu giữ nguyên kích thước ảnh đầy đủ.
Ví dụ: Đầu ra kích thước đầy đủ + nền trong suốt Ảnh đối tượng đã cắt
Các bước bổ sung cần thiết để cắt ảnh chỉ bao gồm vùng đối tượng.
# (1) Bounding box coordinates x1, y1, x2, y2 = c.boxes.xyxy.cpu().numpy().squeeze().astype(np.int32) # Crop image to object region iso_crop = isolated[y1:y2, x1:x2]
- Để biết thêm thông tin về kết quả khung giới hạn, hãy xem Phần Khung từ Chế độ Dự đoán
Đoạn mã này làm gì?
-
Khi sử dụng
c.boxes.xyxy.cpu().numpy()
, các hộp giới hạn được trả về dưới dạng một mảng NumPy, sử dụngxyxy
định dạng tọa độ hộp, tương ứng với các điểmxmin, ymin, xmax, ymax
cho hộp giới hạn (hình chữ nhật), xem Phần Boxes từ Chế độ Dự đoán để biết thêm thông tin. -
Đang thêm
squeeze()
đảm bảo rằng mọi chiều ngoại lai được loại bỏ khỏi mảng NumPy. -
Chuyển đổi các giá trị tọa độ bằng cách sử dụng
.astype(np.int32)
thay đổi kiểu dữ liệu tọa độ hộp từfloat32
đếnint32
sẽ tương thích khi cắt ảnh bằng cách sử dụng các lát chỉ mục. -
Cuối cùng, vùng ảnh cho bounding box được cắt bằng cách sử dụng index slicing, trong đó các ranh giới được thiết lập bằng cách sử dụng
[ymin:ymax, xmin:xmax]
tọa độ của hộp giới hạn phát hiện.
Điều gì xảy ra nếu tôi muốn đối tượng được cắt bao gồm cả nền?
Đây là một tính năng được tích hợp sẵn cho thư viện Ultralytics. Xem
save_crop
đối số cho Các đối số suy luận của Chế độ Dự đoán để biết chi tiết.
-
-
Bước tiếp theo hoàn toàn tùy thuộc vào bạn với tư cách là nhà phát triển. Một ví dụ cơ bản về một bước tiếp theo có thể (lưu hình ảnh vào tệp để sử dụng trong tương lai) được hiển thị.
- LƯU Ý: bước này là tùy chọn và có thể bỏ qua nếu không cần thiết cho trường hợp sử dụng cụ thể của bạn.
Ví dụ: Bước Cuối Cùng
# Save isolated object to file _ = cv2.imwrite(f"{img_name}_{label}-{ci}.png", iso_crop)
- Trong ví dụ này,
img_name
là tên cơ sở của tệp hình ảnh nguồn,label
là tên lớp được phát hiện vàci
là chỉ số của phát hiện đối tượng (trong trường hợp nhiều đối tượng cùng tên lớp).
Mã Ví dụ đầy đủ
Ở đây, tất cả các bước từ phần trước được kết hợp thành một khối mã duy nhất. Để sử dụng lặp lại, sẽ tối ưu hơn nếu định nghĩa một hàm để thực hiện một số hoặc tất cả các lệnh có trong for
-loops, nhưng đó là một bài tập dành cho người đọc.
from pathlib import Path
import cv2
import numpy as np
from ultralytics import YOLO
m = YOLO("yolo11n-seg.pt") # (4)!
res = m.predict() # (3)!
# Iterate detection results (5)
for r in res:
img = np.copy(r.orig_img)
img_name = Path(r.path).stem
# Iterate each object contour (6)
for ci, c in enumerate(r):
label = c.names[c.boxes.cls.tolist().pop()]
b_mask = np.zeros(img.shape[:2], np.uint8)
# Create contour mask (1)
contour = c.masks.xy.pop().astype(np.int32).reshape(-1, 1, 2)
_ = cv2.drawContours(b_mask, [contour], -1, (255, 255, 255), cv2.FILLED)
# Choose one:
# OPTION-1: Isolate object with black background
mask3ch = cv2.cvtColor(b_mask, cv2.COLOR_GRAY2BGR)
isolated = cv2.bitwise_and(mask3ch, img)
# OPTION-2: Isolate object with transparent background (when saved as PNG)
isolated = np.dstack([img, b_mask])
# OPTIONAL: detection crop (from either OPT1 or OPT2)
x1, y1, x2, y2 = c.boxes.xyxy.cpu().numpy().squeeze().astype(np.int32)
iso_crop = isolated[y1:y2, x1:x2]
# TODO your actions go here (2)
- Dòng điền dữ liệu
contour
được kết hợp thành một dòng duy nhất ở đây, trong khi trước đó được chia thành nhiều dòng. - Những gì ở đây là tùy thuộc vào bạn!
- Xem Chế độ Dự đoán để biết thêm thông tin.
- Xem Tác vụ Phân đoạn để biết thêm thông tin.
- Tìm hiểu thêm về Làm việc với Kết quả
- Tìm hiểu thêm về Kết quả Mặt nạ Phân đoạn
Câu hỏi thường gặp
Làm cách nào để phân lập các đối tượng bằng Ultralytics YOLO11 cho các tác vụ phân đoạn?
Để cô lập các đối tượng bằng Ultralytics YOLO11, hãy làm theo các bước sau:
-
Tải mô hình và chạy suy luận:
from ultralytics import YOLO model = YOLO("yolo11n-seg.pt") results = model.predict(source="path/to/your/image.jpg")
-
Tạo mặt nạ nhị phân và vẽ đường viền:
import cv2 import numpy as np img = np.copy(results[0].orig_img) b_mask = np.zeros(img.shape[:2], np.uint8) contour = results[0].masks.xy[0].astype(np.int32).reshape(-1, 1, 2) cv2.drawContours(b_mask, [contour], -1, (255, 255, 255), cv2.FILLED)
-
Cô lập đối tượng bằng cách sử dụng mặt nạ nhị phân:
mask3ch = cv2.cvtColor(b_mask, cv2.COLOR_GRAY2BGR) isolated = cv2.bitwise_and(mask3ch, img)
Tham khảo hướng dẫn về Chế Độ Dự Đoán và Tác Vụ Phân Đoạn để biết thêm thông tin.
Những tùy chọn nào có sẵn để lưu các đối tượng được phân lập sau khi phân đoạn?
Ultralytics YOLO11 cung cấp hai tùy chọn chính để lưu các đối tượng bị cô lập:
-
Với Nền đen:
mask3ch = cv2.cvtColor(b_mask, cv2.COLOR_GRAY2BGR) isolated = cv2.bitwise_and(mask3ch, img)
-
Với Nền trong suốt:
isolated = np.dstack([img, b_mask])
Để biết thêm chi tiết, hãy truy cập phần Chế Độ Dự Đoán.
Làm cách nào để cắt các đối tượng bị cô lập thành các hộp giới hạn của chúng bằng Ultralytics YOLO11?
Để cắt các đối tượng bị cô lập thành các hộp giới hạn của chúng:
-
Truy xuất tọa độ hộp giới hạn:
x1, y1, x2, y2 = results[0].boxes.xyxy[0].cpu().numpy().astype(np.int32)
-
Cắt ảnh đã được cô lập:
iso_crop = isolated[y1:y2, x1:x2]
Tìm hiểu thêm về kết quả hộp giới hạn trong tài liệu Chế độ Dự đoán.
Tại sao tôi nên sử dụng Ultralytics YOLO11 để phân lập đối tượng trong các tác vụ phân đoạn?
Ultralytics YOLO11 cung cấp:
- Tốc độ cao trong phát hiện và phân đoạn đối tượng theo thời gian thực.
- Tạo bounding box và mask chính xác để phân lập đối tượng một cách chuẩn xác.
- Tài liệu đầy đủ và API dễ sử dụng để phát triển hiệu quả.
Khám phá những lợi ích của việc sử dụng YOLO trong tài liệu Nhiệm vụ phân đoạn.
Tôi có thể lưu các đối tượng riêng biệt bao gồm cả nền bằng Ultralytics YOLO11 không?
Có, đây là một tính năng tích hợp sẵn trong Ultralytics YOLO11. Sử dụng save_crop
đối số trong predict()
phương thức. Ví dụ:
results = model.predict(source="path/to/your/image.jpg", save_crop=True)
Đọc thêm về save_crop
đối số trong Các đối số suy luận của Chế độ Dự đoán ở phần này.