콘텐츠로 건너뛰기

세분화 개체 격리

세그먼트 작업을 수행한 후 추론 결과에서 고립된 개체를 추출하는 것이 바람직할 때가 있습니다. 이 가이드에서는 Ultralytics 예측모드를 사용하여 이를 수행하는 방법에 대한 일반적인 방법을 제공합니다.

격리된 개체 세분화 예시

레시피 워크스루

  1. 필요한 라이브러리 설치에 대한 빠른 안내는Ultralytics 빠른 시작 설치 섹션을 참조하세요.


  2. 모델을 로드하고 실행 predict() 메서드를 사용합니다.

    from ultralytics import YOLO
    
    # Load a model
    model = YOLO("yolo11n-seg.pt")
    
    # Run inference
    results = model.predict()
    

    예측 인수가 없나요?

    소스를 지정하지 않으면 라이브러리에 있는 예제 이미지가 사용됩니다:

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

    이는 신속한 테스트에 유용합니다. predict() 메서드를 사용합니다.

    세분화 모델에 대한 자세한 내용은 다음을 참조하세요. 세그먼트 작업 페이지로 이동합니다. 다음에 대해 자세히 알아보려면 predict() 메서드에 대한 자세한 내용은 예측 모드 섹션을 참조하세요.


  3. 이제 결과와 윤곽선을 반복합니다. 이미지를 파일로 저장하려는 워크플로우의 경우 소스 이미지 base-name 및 탐지 class-label 는 나중에 사용할 수 있도록 검색됩니다(선택 사항).

    from pathlib import Path
    
    import numpy as np
    
    #  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):
            #  Get detection class name
            label = c.names[c.boxes.cls.tolist().pop()]
    
    For-Loop

    단일 이미지는 첫 번째 루프를 한 번만 반복합니다. 단일 감지만 있는 단일 이미지는 각 루프를 한 번만 반복합니다.


  4. 먼저 소스 이미지에서 이진 마스크를 생성한 다음 마스크에 채워진 윤곽을 그립니다. 이렇게 하면 개체를 이미지의 다른 부분과 분리할 수 있습니다. 예시 bus.jpg 탐지된 것 중 하나에 대해 person 클래스 객체를 오른쪽에 표시합니다.

    바이너리 마스크 이미지

    import cv2
    
    # Create binary mask
    b_mask = np.zeros(img.shape[:2], np.uint8)
    
    #  Extract contour result
    contour = c.masks.xy.pop()
    #  Changing the type
    contour = contour.astype(np.int32)
    #  Reshaping
    contour = contour.reshape(-1, 1, 2)
    
    
    # Draw contour onto mask
    _ = cv2.drawContours(b_mask, [contour], -1, (255, 255, 255), cv2.FILLED)
    

    확장하여 정의할 때 어떤 일이 발생하는지 이해합니다. contour 변수입니다.

    • c.masks.xy :: 마스크 윤곽점의 좌표를 다음과 같은 형식으로 제공합니다. (x, y). 자세한 내용은 예측 모드의 마스크 섹션.

    • .pop() :: As masks.xy 가 단일 요소를 포함하는 목록인 경우, 이 요소는 pop() 메서드를 사용합니다.

    • .astype(np.int32) :: 사용 masks.xy 은 데이터 유형이 float32를 사용할 수 있지만, 이는 OpenCV drawContours() 함수를 호출하면 데이터 유형이 다음과 같이 변경됩니다. int32 호환성을 확인합니다.

    • .reshape(-1, 1, 2) :: 데이터를 필요한 모양으로 다시 포맷합니다. [N, 1, 2] 어디 N 는 윤곽 점의 수이며, 각 점은 단일 항목으로 표시됩니다. 1항목은 다음과 같이 구성됩니다. 2 값입니다. The -1 는 이 차원의 값 수가 유연하다는 것을 나타냅니다.

    확장하면 drawContours() 구성.

    • 캡슐화 contour 변수를 대괄호 안에 넣습니다, [contour]를 사용하면 테스트 중에 원하는 윤곽 마스크를 효과적으로 생성하는 것으로 나타났습니다.

    • -1 에 지정된 drawContours() 매개변수는 이미지에 존재하는 모든 윤곽선을 그리도록 함수에 지시합니다.

    • 그리고 tuple (255, 255, 255) 는 이 이진 마스크에서 윤곽선을 그릴 때 원하는 색상인 흰색을 나타냅니다.

    • 추가 cv2.FILLED 는 윤곽 경계로 둘러싸인 모든 픽셀의 색을 동일하게 지정하며, 이 경우 둘러싸인 모든 픽셀은 흰색이 됩니다.

    • 참조 OpenCV 문서 drawContours() 에서 자세한 내용을 확인하세요.


  5. 다음으로 이 시점에서 이미지를 진행하는 방법에 대한 두 가지 옵션과 각 옵션에 대한 후속 옵션이 있습니다.

    개체 격리 옵션

    # Create 3-channel mask
    mask3ch = cv2.cvtColor(b_mask, cv2.COLOR_GRAY2BGR)
    
    # Isolate object with binary mask
    isolated = cv2.bitwise_and(mask3ch, img)
    
    어떻게 작동하나요?
    • 먼저 바이너리 마스크가 먼저 단일 채널 이미지에서 3채널 이미지로 변환됩니다. 이 변환은 마스크와 원본 이미지가 결합되는 후속 단계에 필요합니다. 블렌딩 작업과 호환되려면 두 이미지의 채널 수가 같아야 합니다.

    • 원본 이미지와 3채널 바이너리 마스크는 OpenCV 함수를 사용하여 병합됩니다. bitwise_and(). 이 작업은 다음을 유지합니다. 0보다 큰 픽셀 값 (> 0) 를 제거합니다. 마스크 픽셀이 0보다 크므로 (> 0) 윤곽선 영역 내에서 원본 이미지에서 남은 픽셀은 윤곽선과 겹치는 픽셀입니다.

    검은색 픽셀로 격리: 하위 옵션

    전체 크기 이미지

    전체 크기 이미지를 유지하는 경우 추가 단계가 필요하지 않습니다.

    전체 크기 고립된 개체 이미지 검정색 배경 예시
    전체 크기 출력 예시

    잘린 개체 이미지

    객체 영역만 포함하도록 이미지를 자르려면 추가 단계가 필요합니다.

    격리된 개체 이미지 자르기 예시 검은색 배경

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

    이 코드는 어떤 기능을 하나요?
    • 그리고 c.boxes.xyxy.cpu().numpy() 호출은 바운딩 박스를 NumPy 배열로 검색합니다. xyxy 형식으로, 여기서 xmin, ymin, xmaxymax 는 바운딩 박스 직사각형의 좌표를 나타냅니다. 참조 예측 모드의 박스 섹션 에서 자세한 내용을 확인하세요.

    • 그리고 squeeze() 연산은 NumPy 배열에서 불필요한 치수를 제거하여 예상되는 모양을 갖도록 합니다.

    • 다음을 사용하여 좌표 값 변환하기 .astype(np.int32) 에서 상자 좌표 데이터 유형을 변경합니다. float32int32를 사용하여 인덱스 슬라이스를 사용한 이미지 자르기에 호환됩니다.

    • 마지막으로 인덱스 슬라이싱을 사용하여 이미지에서 바운딩 박스 영역을 잘라냅니다. 경계는 [ymin:ymax, xmin:xmax] 감지 경계 상자의 좌표입니다.

    # Isolate object with transparent background (when saved as PNG)
    isolated = np.dstack([img, b_mask])
    
    어떻게 작동하나요?
    • NumPy 사용 dstack() 함수(깊이 축을 따라 배열 스태킹)를 생성된 이진 마스크와 함께 사용하면 4개의 채널이 있는 이미지가 생성됩니다. 이렇게 하면 오브젝트 윤곽선 외부의 모든 픽셀을 투명하게 만들 수 있습니다. PNG 파일을 만듭니다.

    투명 픽셀로 격리: 하위 옵션

    전체 크기 이미지

    전체 크기 이미지를 유지하는 경우 추가 단계가 필요하지 않습니다.

    전체 크기 고립된 개체 이미지 예시 배경 없음
    전체 크기 출력 + 투명 배경 예시

    잘린 개체 이미지

    객체 영역만 포함하도록 이미지를 자르려면 추가 단계가 필요합니다.

    배경 없이 고립된 개체 이미지 자르기 예시

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

    이 코드는 어떤 기능을 하나요?
    • 사용 시 c.boxes.xyxy.cpu().numpy()를 사용하여 경계 상자를 NumPy 배열로 반환합니다. xyxy 상자 좌표 형식으로, 포인트에 해당하는 xmin, ymin, xmax, ymax 바운딩 박스(직사각형)의 경우, 다음을 참조하십시오. 예측 모드의 박스 섹션 에서 자세한 내용을 확인하세요.

    • 추가 squeeze() 는 불필요한 차원이 NumPy 배열에서 제거되도록 합니다.

    • 다음을 사용하여 좌표 값 변환하기 .astype(np.int32) 에서 상자 좌표 데이터 유형을 변경합니다. float32int32 인덱스 슬라이스를 사용하여 이미지를 자를 때 호환됩니다.

    • 마지막으로 인덱스 슬라이싱을 사용하여 경계 상자에 대한 이미지 영역을 자르고, 여기서 경계는 [ymin:ymax, xmin:xmax] 감지 경계 상자의 좌표입니다.

    배경을 포함하여 잘린 개체를 원하면 어떻게 하나요?

    이 기능은 Ultralytics 라이브러리에 내장된 기능입니다. 라이브러리에서 save_crop 에 대한 인수 예측 모드 추론 인수 를 참조하세요.


  6. 다음에 수행할 작업은 전적으로 개발자에게 달려 있습니다. 가능한 다음 단계(나중에 사용할 수 있도록 이미지를 파일에 저장)의 기본 예가 나와 있습니다.

    • 참고: 이 단계는 선택 사항이며 특정 사용 사례에 필요하지 않은 경우 건너뛸 수 있습니다.
    최종 단계 예시
    # Save isolated object to file
    _ = cv2.imwrite(f"{img_name}_{label}-{ci}.png", iso_crop)
    
    • 이 예제에서는 img_name 은 소스 이미지 파일의 기본 이름입니다, label 은 감지된 클래스 이름이고 ci물체 감지 (동일한 클래스 이름을 가진 인스턴스가 여러 개 있는 경우).

전체 예제 코드

여기에서는 이전 섹션의 모든 단계를 하나의 코드 블록으로 결합합니다. 반복적으로 사용하려면 일부 또는 모든 명령을 수행하는 함수를 정의하는 것이 가장 좋습니다. for-루프를 사용할 수도 있지만, 이는 독자의 판단에 맡기겠습니다.

from pathlib import Path

import cv2
import numpy as np

from ultralytics import YOLO

m = YOLO("yolo11n-seg.pt")  
res = m.predict()  

# Iterate detection results 
for r in res:
    img = np.copy(r.orig_img)
    img_name = Path(r.path).stem

    # Iterate each object contour 
    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 
        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 

자주 묻는 질문

세분화 작업에 Ultralytics YOLO11 을 사용하여 개체를 격리하려면 어떻게 하나요?

Ultralytics YOLO11 을 사용하여 개체를 격리하려면 다음 단계를 따르세요:

  1. 모델을 로드하고 추론을 실행합니다:

    from ultralytics import YOLO
    
    model = YOLO("yolo11n-seg.pt")
    results = model.predict(source="path/to/your/image.jpg")
    
  2. 바이너리 마스크를 생성하고 윤곽선을 그립니다:

    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. 바이너리 마스크를 사용하여 개체를 분리합니다:

    mask3ch = cv2.cvtColor(b_mask, cv2.COLOR_GRAY2BGR)
    isolated = cv2.bitwise_and(mask3ch, img)
    

자세한 내용은 예측 모드세그먼트 작업에 대한 가이드를 참조하세요.

세분화 후 분리된 개체를 저장하는 데 사용할 수 있는 옵션에는 어떤 것이 있나요?

Ultralytics YOLO11 는 격리된 개체를 저장하는 두 가지 주요 옵션을 제공합니다:

  1. 검은색 배경:

    mask3ch = cv2.cvtColor(b_mask, cv2.COLOR_GRAY2BGR)
    isolated = cv2.bitwise_and(mask3ch, img)
    
  2. 투명한 배경을 사용합니다:

    isolated = np.dstack([img, b_mask])
    

자세한 내용은 예측 모드 섹션을 참조하세요.

Ultralytics YOLO11 을 사용하여 고립된 개체를 경계 상자로 자르려면 어떻게 해야 하나요?

고립된 개체를 경계 상자로 자릅니다:

  1. 바운딩 박스 좌표를 검색합니다:

    x1, y1, x2, y2 = results[0].boxes.xyxy[0].cpu().numpy().astype(np.int32)
    
  2. 분리된 이미지를 자릅니다:

    iso_crop = isolated[y1:y2, x1:x2]
    

바운딩 박스 결과에 대한 자세한 내용은 예측 모드 문서를 참조하세요.

세분화 작업에서 개체 격리를 위해 Ultralytics YOLO11 을 사용해야 하는 이유는 무엇인가요?

Ultralytics YOLO11 를 제공합니다:

  • 고속 실시간 객체 감지 및 세분화.
  • 정확한 바운딩 박스 및 마스크 생성으로 정확한 오브젝트 격리가 가능합니다.
  • 효율적인 개발을 위한 포괄적인 문서와 사용하기 쉬운 API를 제공합니다.

세그먼트 작업 문서에서 YOLO 사용의 이점을 살펴보세요.

Ultralytics YOLO11 을 사용하여 배경을 포함하여 고립된 개체를 저장할 수 있나요?

예, 이것은 Ultralytics YOLO11 에 내장된 기능입니다. 이 기능을 사용하려면 save_crop 인수의 predict() 메서드를 사용합니다. 예를 들어

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

자세히 알아보기 save_crop 인수의 예측 모드 추론 인수 섹션으로 이동합니다.

📅1 년 전 생성됨 ✏️ 5개월 전 업데이트됨

댓글