Meet YOLO26: next-gen vision AI.

Link to this sectionUltralytics YOLO를 사용하여 세그멘테이션 객체를 분리하는 방법#

인스턴스 세그멘테이션은 감지된 모든 객체에 대해 픽셀 단위의 정밀한 마스크를 생성하므로, 각 객체를 이미지에서 개별적으로 추출할 수 있습니다. 이 가이드는 Predict Mode와 OpenCV를 사용하여 Ultralytics YOLO 세그멘테이션 결과를 독립된 객체로 변환하는 방법을 보여줍니다. 배경을 검은색으로 하거나 PNG로 저장하기 위한 투명 배경으로 설정할 수 있습니다.



Watch: How to Remove Background and Isolate Objects with Ultralytics YOLO Segmentation & OpenCV in Python 🚀

Link to this section세그멘테이션 객체를 분리하는 이유는 무엇인가요?#

이미지에서 개별 객체를 추출하면 다양한 후속 워크플로가 가능해집니다:

  • 제품 사진, 카탈로그 또는 창의적인 편집을 위한 배경 제거.
  • 감지 결과로부터 분류 데이터셋을 구축하기 위한 객체별 크롭(crop).
  • OCR, 색상 분석 또는 측정과 같은 후속 단계에서 주변 장면이 아닌 객체만 볼 수 있도록 하는 집중 처리.
  • 객체를 새로운 배경에 합성하기 위한 투명 PNG 내보내기.

이 레시피는 모든 Ultralytics YOLO 세그멘테이션 모델에서 작동하며 네 단계로 진행됩니다: 추론 실행각 윤곽선 추출객체 분리결과 저장.

Link to this section세그멘테이션 추론 실행#

필요한 라이브러리를 설치한 다음, 세그멘테이션 모델(마스크 생성에 필요한 -seg 접미사가 붙은 모델)을 로드하고 소스 이미지에 대해 예측을 실행합니다:

from ultralytics import YOLO

# Load a segmentation model
model = YOLO("yolo26n-seg.pt")

# Run inference on a source
results = model.predict(source="path/to/image.jpg")
소스가 없나요? YOLO는 번들로 제공된 샘플 이미지를 사용합니다

If you call model.predict() without a source, Ultralytics falls back to the example images shipped with the package (bus.jpg and zidane.jpg), which is handy for quickly testing the workflow.

Link to this section객체 윤곽선 추출#

results의 각 항목은 하나의 이미지에 해당하며, 결과를 반복하면 한 번에 하나의 감지 결과를 얻을 수 있습니다. 모든 감지 결과에 대해 원본 이미지를 복사하고, 클래스 레이블을 읽은 뒤, 빈 이진 마스크 위에 해당 객체의 마스크 윤곽선을 그립니다. 이 마스크의 흰색 영역은 객체에 속하는 정확한 픽셀을 표시합니다.

이 섹션과 다음 섹션의 코드 조각은 아래의 감지 루프 내부에서 실행됩니다. 전체 스크립트는 전체 예제를 참조하십시오.

이진 마스크 이미지{ width="240", align="right" }

from pathlib import Path

import cv2
import numpy as np

for r in results:
    img = np.copy(r.orig_img)
    img_name = Path(r.path).stem  # source image base-name

    # Iterate each detected object in the image
    for ci, c in enumerate(r):
        label = c.names[c.boxes.cls.tolist().pop()]  # class name

        # Build a binary mask and draw the object contour onto it
        b_mask = np.zeros(img.shape[:2], np.uint8)
        contour = c.masks.xy[0].astype(np.int32).reshape(-1, 1, 2)
        cv2.drawContours(b_mask, [contour], -1, (255, 255, 255), cv2.FILLED)
`c.masks.xy[0].astype(np.int32).reshape(-1, 1, 2)`는 무엇을 하나요?
  • c.masks.xy[0]은 이 단일 감지 결과에 대한 객체의 마스크 윤곽선을 (x, y) 점 좌표로 반환합니다.
  • .astype(np.int32) converts the points from float32, which OpenCV's drawContours() does not accept.
  • .reshape(-1, 1, 2) reshapes the points into the [N, 1, 2] layout drawContours() expects, where N is the number of contour points.

Passing [contour] with the index -1 draws all points of the supplied contour, and cv2.FILLED fills every enclosed pixel white.

Link to this section객체 분리#

이진 마스크가 준비되면 이를 원본 이미지와 결합합니다. 배경을 어떻게 설정할지에 따라 두 가지 일반적인 스타일이 있습니다:

분리 스타일 선택

마스크를 3채널로 변환하고 객체와 겹치는 픽셀만 유지합니다. 윤곽선 외부의 모든 것은 검은색이 됩니다:

# Isolate object with a black background
mask3ch = cv2.cvtColor(b_mask, cv2.COLOR_GRAY2BGR)
isolated = cv2.bitwise_and(mask3ch, img)
![Example Full size Isolated Object Image Black Background](https://cdn.jsdelivr.net/gh/ultralytics/assets@main/docs/full-size-isolated-object-black-background.avif){ width=240 }
Full-size object on a black background
바운딩 박스로 크롭

전체 크기 이미지 대신 객체 영역만 유지하려면 감지의 바운딩 박스에 맞춰 슬라이스합니다:

# Bounding box coordinates
x1, y1, x2, y2 = c.boxes.xyxy.cpu().numpy().squeeze().astype(np.int32)
# Crop the isolated image to the object region
iso_crop = isolated[y1:y2, x1:x2]
![Example Crop Isolated Object Image Black Background](https://cdn.jsdelivr.net/gh/ultralytics/assets@main/docs/example-crop-isolated-object-image-black-background.avif){ width=240 }
Object cropped to its bounding box
원본 배경을 포함한 크롭이 필요한가요?

That is built in. Pass save_crop=True to predict() and Ultralytics saves bounding-box crops automatically, no masking required.

Link to this section결과 저장 (선택 사항)#

분리된 각 객체로 무엇을 할지는 사용자의 결정에 달려 있습니다. 일반적으로 수행되는 다음 단계는 나중에 사용할 수 있도록 디스크에 저장하는 것입니다:

# Save the isolated object to file
cv2.imwrite(f"{img_name}_{label}-{ci}.png", isolated)

여기서 img_name은 소스 이미지 이름이고, label은 클래스 이름이며, ci는 감지 인덱스이므로 동일 클래스의 여러 인스턴스가 고유한 파일 이름을 가집니다. 위에 언급된 선택적 크롭을 적용한 경우 isolatediso_crop으로 바꾸십시오.

Link to this section전체 예제#

아래 스크립트는 모든 단계를 하나의 실행 가능한 블록으로 결합합니다. 기본적으로 검은색 배경을 사용하며, 투명한 PNG를 원하면 표시된 한 줄을 np.dstack([img, b_mask])로 변경하십시오:

from pathlib import Path

import cv2
import numpy as np

from ultralytics import YOLO

model = YOLO("yolo26n-seg.pt")
results = model.predict(source="path/to/image.jpg")

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

    for ci, c in enumerate(r):
        label = c.names[c.boxes.cls.tolist().pop()]

        # Build a binary mask from the object contour
        b_mask = np.zeros(img.shape[:2], np.uint8)
        contour = c.masks.xy[0].astype(np.int32).reshape(-1, 1, 2)
        cv2.drawContours(b_mask, [contour], -1, (255, 255, 255), cv2.FILLED)

        # Isolate the object (black background)
        mask3ch = cv2.cvtColor(b_mask, cv2.COLOR_GRAY2BGR)
        isolated = cv2.bitwise_and(mask3ch, img)  # transparent PNG: isolated = np.dstack([img, b_mask])

        # Save or add your custom post-processing here
        cv2.imwrite(f"{img_name}_{label}-{ci}.png", isolated)

        # Optional: crop to the bounding box before saving
        # x1, y1, x2, y2 = c.boxes.xyxy.cpu().numpy().squeeze().astype(np.int32)
        # cv2.imwrite(f"{img_name}_{label}-{ci}.png", isolated[y1:y2, x1:x2])

반복적으로 사용하려면 루프 본문을 함수로 래핑하여 여러 이미지에서 호출할 수 있도록 하십시오.

Link to this section결론#

이제 Ultralytics YOLO로 세그멘테이션 객체를 분리하는 전체 레시피를 갖추었습니다: 추론을 실행하고, 각 윤곽선에서 이진 마스크를 생성한 다음, 검은색 또는 투명 배경에서 객체를 추출하고 선택적으로 바운딩 박스로 크롭합니다. 워크플로를 자신의 클래스에 맞게 조정하려면 전체 Segment TaskPredict Mode 문서를 살펴보십시오.

Link to this sectionFAQ#

Link to this sectionUltralytics YOLO를 사용하여 세그멘테이션 작업의 객체를 어떻게 분리하나요?#

세그멘테이션 모델을 로드하고, 추론을 실행하고, 각 감지 결과의 윤곽선에서 이진 마스크를 만든 다음 이를 원본 이미지와 결합합니다:

import cv2
import numpy as np

from ultralytics import YOLO

model = YOLO("yolo26n-seg.pt")
results = model.predict(source="path/to/your/image.jpg")

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)

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

감지별 루프 전체는 전체 예제를 참조하십시오.

Link to this section세그멘테이션 후 분리된 객체를 저장하기 위한 어떤 옵션이 있나요?#

두 가지 주요 스타일이 있습니다. 검은색 배경의 경우 마스크를 3채널로 변환하고 cv2.bitwise_and()를 사용합니다. 투명 배경(PNG로 저장 시)의 경우 np.dstack([img, b_mask])를 사용하여 마스크를 네 번째 알파 채널로 쌓습니다. 두 방법 모두 객체 분리에서 확인할 수 있습니다.

Link to this section분리된 객체를 바운딩 박스로 어떻게 크롭하나요?#

감지 결과에서 바운딩 박스 좌표를 읽어 분리된 이미지를 슬라이스합니다:

x1, y1, x2, y2 = results[0].boxes.xyxy[0].cpu().numpy().astype(np.int32)
iso_crop = isolated[y1:y2, x1:x2]

바운딩 박스 결과에 대한 자세한 내용은 Predict Mode 문서를 참조하십시오.

Link to this section세그멘테이션 작업에서 객체 분리를 위해 Ultralytics YOLO를 사용해야 하는 이유는 무엇인가요?#

Ultralytics YOLO는 정확한 마스크 및 바운딩 박스 생성을 통해 빠르고 실시간인 인스턴스 세그멘테이션을 제공하며, 간단한 Python API를 통해 몇 줄의 OpenCV 코드로 추론 결과를 독립된 객체로 변환할 수 있습니다.

Link to this sectionUltralytics YOLO를 사용하여 배경을 포함한 분리된 객체를 저장할 수 있나요?#

Yes. Use the save_crop argument in predict() to save bounding-box crops with their original background:

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

Predict Mode 추론 인수 섹션에서 자세한 내용을 읽어보십시오.

댓글