Phân lập các đối tượng phân đoạn
Sau khi thực hiện Nhiệm vụ phân đoạn , đôi khi bạn muốn trích xuất các đối tượng bị cô lập từ kết quả suy luận. Hướng dẫn này cung cấp công thức chung về cách thực hiện việc này bằng cách sử dụng Ultralytics Chế độ dự đoán .
Công thức hướng dẫn
-
Xem phần Cài đặt nhanh Ultralytics để biết 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ó lập luận dự đoán?
Nếu không nêu rõ nguồn, hình ảnh ví dụ từ thư viện sẽ được sử dụng:
Điều này hữu ích cho việc thử nghiệm nhanh với
predict()
phương pháp.Để biết thêm thông tin về Mô hình phân đoạn, hãy truy cập Nhiệm vụ phân đoạn trang. Để tìm hiểu thêm về
predict()
phương pháp, xem Chế độ dự đoán phần Tài liệu.
-
Bây giờ lặp lại các kết quả và đường viền. Đối với các quy trình công 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 lấy lại để sử dụng sau (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 của 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ỉ có một phát hiện duy nhất sẽ chỉ lặp lại mỗi vòng lặp một lần.
-
Bắt đầu bằng cách tạo mặt nạ nhị phân từ hình ảnh nguồn và sau đó vẽ đường viền đã tô lên mặt nạ. Điều này sẽ cho phép tách biệt đối tượng khỏi các phần khác của hình ảnh. Một ví dụ từ
bus.jpg
cho một trong những 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
nhìn thấy Phần Mặt nạ từ Chế độ Dự đoán. -
Ở đây các giá trị được đúc thành
np.int32
để tương thích vớidrawContours()
chức năng từ MởCV. -
OpenCV là gì?
drawContours()
chức năng mong đợi các đườ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 những gì đang xảy ra khi xác định
contour
biến đổi.-
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()
:: BẰNGmasks.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()
chức năng, 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 theo hình dạng yêu cầu[N, 1, 2]
Ở đâuN
là số điểm đường đồng mức, với mỗi điểm được biểu diễn bằng một mục nhập duy nhất1
và mục nhập được tạo thành từ2
giá trị. Các-1
biểu thị rằng số lượng giá trị dọc theo chiều này là linh hoạt.
Mở rộng để giải thích về
drawContours()
cấu hình.-
Đóng gói các
contour
biến trong dấu ngoặc vuông,[contour]
, được phát hiện có hiệu quả trong việc tạo ra mặt nạ đường viền mong muốn trong quá trình thử nghiệm. -
Giá trị
-1
được chỉ định chodrawContours()
tham số hướng dẫn hàm vẽ tất cả các đường viền có trong hình ảnh. -
Các
tuple
(255, 255, 255)
biểu thị 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ổ sung
cv2.FILLED
sẽ tô màu giống nhau cho tất cả các điểm ảnh được bao quanh bởi đường viền, trong trường hợp này, tất cả các điểm ảnh được bao quanh sẽ có màu trắng. -
Nhìn thấy 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 di chuyển hình ảnh từ điểm này và các tùy chọn tiếp theo cho mỗi tùy chọn.
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)
Việc này diễn ra thế nào?
-
Đầu tiên, mặt nạ nhị phân được chuyển đổi từ hình ảnh một kênh sang hình ảnh ba kênh. Việc chuyển đổi này là cần thiết cho bước tiếp theo khi mặt nạ và hình ảnh gốc được kết hợp. Cả hai hình ảnh phải có cùng số kênh để tương thích với thao tác pha trộn.
-
Hình ảnh gốc và mặt nạ nhị phân ba kênh được hợp nhất bằng cách sử dụng hàm OpenCV
bitwise_and()
. Hoạt động này giữ lại chỉ một giá trị pixel lớn hơn 0(> 0)
từ cả hai hình ảnh. Vì các điểm ảnh mặt nạ lớn hơn không(> 0)
chỉ một trong vùng đường viền, các điểm ảnh còn lại từ hình ảnh gốc là những điểm ảnh chồng lên đường viền.
Tách biệt với các điểm ảnh đen: Tùy chọn phụ
Hình ảnh kích thước đầy đủ
Không cần thực hiện thêm bước nào nữa nếu muốn giữ nguyên hình ảnh có kích thước đầy đủ.
Đối tượng được cắt xén Hình ảnh
Cần thực hiện các bước bổ sung để cắt ảnh sao cho 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ả hộp giới hạn , hãy xem Phần Hộp từ Chế độ Dự đoán
Mã này có tác dụng gì?
-
Các
c.boxes.xyxy.cpu().numpy()
gọi lấy các hộp giới hạn dưới dạng một mảng NumPy trongxyxy
định dạng, nơixmin
,ymin
,xmax
, Vàymax
biểu diễn tọa độ của hình chữ nhật hộp giới hạn. Xem Phần hộp từ chế độ dự đoán để biết thêm chi tiết. -
Các
squeeze()
hoạt động này loại bỏ mọi kích thước không cần thiết khỏi mảng NumPy, đảm bảo mảng có hình dạng mong muốn. -
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
, làm cho chúng tương thích với việc cắt ảnh bằng cách sử dụng các lát cắt chỉ mục. -
Cuối cùng, vùng hộp giới hạn được cắt từ hình ảnh bằng cách sử dụng cắt chỉ mục. Các giới hạn đượ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])
Việc này diễn ra thế nào?
- Sử dụng NumPy
dstack()
chức năng (xếp chồng mảng 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 có 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ài liệu.
Tách biệt với các điểm ảnh trong suốt: Tùy chọn phụ
Hình ảnh kích thước đầy đủ
Không cần thực hiện thêm bước nào nữa nếu muốn giữ nguyên hình ảnh có kích thước đầy đủ.
Đối tượng được cắt xén Hình ảnh
Cần thực hiện các bước bổ sung để cắt ảnh sao cho 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ả hộp giới hạn, hãy xem Phần Hộp từ Chế độ Dự đoán
Mã này có tác dụng 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
đối với hộp giới hạn (hình chữ nhật), hãy xem Phần hộp từ chế độ dự đoán để biết thêm thông tin. -
Thêm
squeeze()
đảm bảo rằng mọi kích thước không cần thiết đều bị 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ác lát cắt chỉ mục. -
Cuối cùng, vùng hình ảnh cho hộp giới hạn được cắt bằng cách sử dụng cắt chỉ mục, trong đó các giới hạn đượ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.
Tôi phải làm sao nếu muốn cắt đối tượng bao gồm cả nền?
Đây là một tính năng được tích hợp sẵn cho Ultralytics thư viện. Xem
save_crop
lập luận cho Đối số suy luận chế độ dự đoán để biết thêm chi tiết.
-
-
Việc tiếp theo hoàn toàn do bạn với tư cách là nhà phát triển quyết định. Một ví dụ cơ bản về một bước tiếp theo có thể thực hiện (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
- 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 có nhiều trường hợp có 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. Đối với việc sử dụng nhiều lần, sẽ là tối ưu khi xác định một hàm để thực hiện một số hoặc tất cả các lệnh có trong for
-vòng lặp, nhưng đó là 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 đang được điền vào
contour
được kết hợp thành một dòng duy nhất ở đây, trong khi ở trên nó đã được tách 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 Phân đoạn nhiệm vụ để 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 thế nào để tôi cô lập các đối tượng bằng cách sử dụng Ultralytics YOLO11 cho nhiệm vụ phân đoạn?
Để cô lập các đối tượng bằng cách sử dụng Ultralytics YOLO11 , hãy làm theo các bước sau:
-
Tải mô hình và chạy suy luận:
-
Tạo mặt nạ nhị phân và vẽ đường viền:
-
Cô lập đối tượng bằng cách sử dụng mặt nạ nhị phân:
Tham khảo hướng dẫn về Chế độ dự đoán và Nhiệm vụ phân đoạn để biết thêm thông tin.
Có những tùy chọn nào để lưu các đối tượng bị cô 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:
-
Với Nền Trong Suốt:
Để biết thêm chi tiết, hãy truy cập phần Chế độ dự đoán .
Làm thế nào tôi có thể cắt các đối tượng bị cô lập vào hộp giới hạn của chúng bằng cách sử dụng Ultralytics YOLO11 ?
Để cắt các đối tượng bị cô lập vào hộp giới hạn của chúng:
-
Lấy tọa độ hộp giới hạn:
-
Cắt hình ảnh bị cô lập:
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 để cô lập đối tượng trong các tác vụ phân đoạn?
Ultralytics YOLO11 cung cấp:
- Phát hiện và phân đoạn đối tượng theo thời gian thực tốc độ cao .
- Tạo hộp giới hạn và mặt nạ chính xác để phân lập đối tượng một cách chính xác.
- Tài liệu toàn diện 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 bị cô lập bao gồm cả nền bằng cách sử dụng Ultralytics YOLO11 ?
Vâng, đây là một tính năng tích hợp sẵn trong Ultralytics YOLO11 . Sử dụng save_crop
lập luận trong predict()
phương pháp. Ví dụ:
Đọc thêm về save_crop
lập luận trong Đối số suy luận chế độ dự đoán phần.