Bỏ qua nội dung

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 .

Ví dụ về phân đoạn đối tượng bị cô lập

Công thức hướng dẫn

  1. 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.


  2. 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:

    'ultralytics/assets/bus.jpg'
    'ultralytics/assets/zidane.jpg'
    

    Đ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.


  3. 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ện class-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()]
    
    1. Để 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 .
    2. Để 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.


  4. 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ện person Các đối tượng lớp được hiển thị ở bên phải.

    Hình ảnh mặt nạ nhị phân

    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)
    
    1. Để 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.

    2. Ở đây các giá trị được đúc thành np.int32 để tương thích với drawContours() chức năng từ MởCV.

    3. 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ẰNG 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ụng pop() phương pháp.

    • .astype(np.int32) :: Sử dụng masks.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 OpenCV drawContours() chức năng, vì vậy điều này sẽ thay đổi kiểu dữ liệu thành int32 để 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] Ở đâu N 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ất 1và 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 cho drawContours() 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.


  5. 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 đủ.

    Ví dụ Hình ảnh đối tượng bị cô lập kích thước đầy đủ Nền đen
    Ví dụ đầu ra 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.

    Ví dụ Cắt ảnh đối tượng bị cô lập Nền đen

    # (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]
    

    1. Để 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 trong xyxy định dạng, nơi xmin, 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 ĐẾN int32, 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ạng PNG 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 đủ.

    Ví dụ Hình ảnh đối tượng bị cô lập kích thước đầy đủ Không có nền
    Ví dụ đầu ra kích thước đầy đủ + nền trong suốt

    Đố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.

    Ví dụ Cắt ảnh đối tượng bị cô lập Không có nền

    # (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]
    

    1. Để 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ụng xyxy định dạng tọa độ hộp, tương ứng với các điểm xmin, 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 ĐẾN int32 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.


  6. 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
    # 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 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)
  1. 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.
  2. Những gì ở đây là tùy thuộc vào bạn!
  3. Xem Chế độ dự đoán để biết thêm thông tin.
  4. Xem Phân đoạn nhiệm vụ để biết thêm thông tin.
  5. Tìm hiểu thêm về Làm việc với Kết quả
  6. 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:

  1. 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")
    
  2. 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)
    
  3. 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ánNhiệ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:

  1. Với nền đen:

    mask3ch = cv2.cvtColor(b_mask, cv2.COLOR_GRAY2BGR)
    isolated = cv2.bitwise_and(mask3ch, img)
    
  2. 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 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:

  1. Lấy tọa độ hộp giới hạn:

    x1, y1, x2, y2 = results[0].boxes.xyxy[0].cpu().numpy().astype(np.int32)
    
  2. Cắt hình ảnh bị 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 để 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ụ:

results = model.predict(source="path/to/your/image.jpg", save_crop=True)

Đọc thêm về save_crop lập luận trong Đối số suy luận chế độ dự đoán phần.

📅 Được tạo ra cách đây 1 năm ✏️ Đã cập nhật cách đây 2 tháng

Bình luận