2.인공지능/MediaPipe

6.MediaPipe Interactive Image Segmenter 사용 : 코드 예시

쿼드큐브 2025. 5. 13. 16:47
728x90

MediaPipe의 인터랙티브 세분화 기능은 사용자가 이미지 내의 특정 지점을 클릭하면 해당 위치를 중심으로 객체의 경계를 추정하여 분할 마스크를 생성하는 기능입니다. 이 기능은 단일 이미지, 비디오 파일 또는 실시간 비디오 스트림에서 작동하며, 선택된 객체를 강조 표시하거나 배경을 흐리게 처리하는 등의 효과를 적용할 수 있습니다

 

MediaPipe Interactive Image Segmenter 사용 : 코드 예시

 

목차

1. Interactive Image Segmenter 개요

2. Interactive Image Segmenter 구조 

3. MagicTouch 모델

4. 예시 코드 기본 구조

5. 예시 1 :  배경은 흐리게, 객체만 선명

6. 예시 2 : 객체를 잘라 배경에 붙여넣기

7. 예시 3 : 라벨링용 마스크 저장

관련 글 링크

 

 

1. Interactive Image Segmenter 개요

MediaPipe Interactive Image Segmenter는 사용자가 클릭한 지점을 기반으로 이미지 내 객체를 자동으로 분할하는 머신러닝 기반의 세분화(segmentation) 도구입니다.

주요 특징

  • 객체의 윤곽을 자동으로 예측하여 마스크로 생성
  • 클릭 한 번으로 복잡한 라벨링이나 객체 추출이 가능
  • 정지 이미지, 동영상, 실시간 스트림 모두 지원
  • Python, Android, Web 환경에서 동일한 인터페이스 제공

MediaPipe Interactive Image Segmenter
출처:https://ai.google.dev/edge/mediapipe/solutions/vision/interactive_segmenter?hl=ko

 

2. Interactive Image Segmenter 구조

MediaPipe의 Interactive Image Segmenter는 단순히 이미지를 분석하는 것을 넘어, 사용자의 클릭 좌표(관심 지점)를 중심으로 해당 객체를 자동으로 추출하는 구조로 설계되어 있습니다.

입력 이미지 처리 - 처리에는 이미지 회전, 크기 조절, 정규화, 색상 공간 변환이 포함됩니다.

 

  태스크 입력

Interactive Image Segmenter가 동작하기 위해 필요한 입력은 두 가지입니다:

1, 관심 지점(Point of Interest)

  - 사용자가 클릭하거나 터치한 지점의 (x, y) 좌표

  - 좌표는 이미지 전체 크기를 기준으로 정규화되어 0~1 사이 값으로 변환됩니다.

  - 이 좌표는 “이 근처의 객체를 감지해달라”는 명령으로 사용됩니다.

2. 처리할 이미지 파일

  - RGB 형식의 정적 이미지 또는 프레임

  - 웹캠, 비디오 프레임, 이미지 파일 모두 사용 가능

 

  태스크 출력

이 태스크는 세분화된 객체 영역을 이미지 형태로 출력합니다. 출력 형식은 구성 옵션에 따라 달라지며, 다음 두 가지가 있습니다:

두 마스크는 동시에 출력할 수 있으며, 각각 다른 후처리에 적합합니다.

1. CATEGORY_MASK (uint8 형식)

  - 객체가 위치한 영역은 픽셀 값 0, 배경은 255으로 나타내는 이진 마스크

  - 세그멘트 결과를 즉시 시각화하거나 객체만 추출할 때 사용

  - 사용 예: "클릭한 물체만 강조"

 

2. CONFIDENCE_MASK (float32 형식)

  - 각 픽셀이 객체일 확률(신뢰도) 값을 포함한 부드러운 마스크

  - 픽셀 값은 0.0 ~ 1.0 사이의 실수이며, 경계가 뚜렷하지 않은 경우 유용

  - 사용 예: "알파 블렌딩 기반 마스크 처리", "불확실한 객체 탐지"

 

구성 옵션 (Configuration Options)

옵션 설명 값 범위 기본값
output_category_mask True로 설정하면 CATEGORY_MASK 출력 포함 {True, False} False
output_confidence_masks True로 설정하면 CONFIDENCE_MASK 출력 포함 {True, False} True
display_names_locale 라벨 언어 설정 (메타데이터 기반 다국어 지원 가능) 언어 코드 ("en", "ko" 등) "en"

 

3. MagicTouch 모델

모델 구조

MagicTouch는 MediaPipe의 Interactive Image Segmenter에서 사용하는 기본 세분화 모델입니다.

구성요소 설명
인코더 MobileNetV3 기반 경량 네트워크
디코더 객체 경계를 복원하는 커스텀 디코더
입력 형태 512x512x4 (RGB + 클릭 위치 히트맵)
출력 CATEGORY_MASK, CONFIDENCE_MASK
정밀도 float32 (양자화 없음)

 

성능

모바일 기기에서도 사용할 수 있도록 최적화되어 있으며, 클릭한 위치 주변의 시각 정보를 분석해 객체를 빠르게 분할해냅니다.

처리방식 평균 지연 시간
CPU 130.11ms
GPU 67.25ms

 

4. 예시 코드 기본 구조

MagicTouch 모델을 다운로드하여 magic_touch.tflite 파일로 저장해둡니다.

 

1. 라이브러리 임포트 및 모델 초기화

import mediapipe as mp
from mediapipe.tasks import python
from mediapipe.tasks.python import vision
from mediapipe.tasks.python.components import containers

import cv2  # OpenCV 라이브러리
import numpy as np  # NumPy 라이브러리
import os  # 파일 경로 처리를 위한 os 모듈
import math  # 수학 함수

# 모델 파일 경로를 설정합니다.
BASE_DIR = os.path.dirname(os.path.abspath(__file__))  # 현재 파일의 디렉토리 경로
model_path = os.path.join(BASE_DIR, './models/magic_touch.tflite')  # 모델 파일 경로

# ImageSegmenter의 기본 옵션을 설정합니다.
# NotImplementedError: GPU Delegate is not yet supported for Windows
base_options = python.BaseOptions(model_asset_path=model_path, 
                                  delegate=python.BaseOptions.Delegate.CPU)
# ImageSegmenter 옵션을 설정합니다.
options = vision.ImageSegmenterOptions(
    base_options=base_options,  # 기본 옵션
    running_mode=vision.RunningMode.IMAGE,  # 실행 모드: 이미지 처리
    output_category_mask=True,  # 카테고리 마스크를 출력하도록 설정
    output_confidence_masks=False  # 신뢰도 마스크를 출력하지 않도록 설정
)

 

2. segment_object 함수 정의

segment_object() 함수는 RGB 이미지와 클릭 좌표(x, y)를 입력받아, 해당 위치에 존재하는 객체를 추론하고 픽셀 단위의 객체 마스크(category mask)를 반환합니다.

이 함수는 MediaPipe의 MagicTouch 기반 Interactive Image Segmenter 모델을 사용하며, 사용자의 클릭 좌표를 정규화한 후 객체 경계를 추론합니다.

반환된 마스크는 원본 이미지와 동일한 크기로 리사이즈되어 후속 시각화, 객체 추출, 라벨링 등에 활용할 수 있습니다.

 

# 객체 세분화를 수행하는 함수
def segment_object(image_rgb, click_x, click_y):
    h, w, _ = image_rgb.shape
    print(f"Image shape: {image_rgb.shape}")
    norm_x = click_x / w
    norm_y = click_y / h

    mp_image = mp.Image(image_format=mp.ImageFormat.SRGB, data=image_rgb)

    RegionOfInterest = vision.InteractiveSegmenterRegionOfInterest
    NormalizedKeypoint = containers.keypoint.NormalizedKeypoint

    roi = RegionOfInterest(
        format=RegionOfInterest.Format.KEYPOINT,
        keypoint=NormalizedKeypoint(norm_x, norm_y)
    )

    # 세분화 요청을 생성합니다. 이미지 사이즈와 mask 사이즈가 같습니다.
    segmenter_result = segmenter.segment(mp_image, roi)
    mask = segmenter_result.category_mask.numpy_view()
    print(f"Category mask shape : {mask.shape}")
    print(f"Category mask unique values: {np.unique(mask)}, dtype: {mask.dtype}")
    return mask

 

3. segmenter 생성 및 테스트 수행

MediaPipe의 MagicTouch 기반 세그멘테이션 모델을 활용하여,
객체 강조, 객체 추출 및 배경 합성, 라벨링용 마스크 생성 등의 작업을 수행하는 세 가지 함수 구조로 구성되어 있습니다.

# 객체를 강조 표시하는 함수
def highlight_object_with_blur(image_path):

# 객체를 잘라내고 배경에 붙이는 함수
def cut_and_paste_object(foreground_path, background_path):

# 세그멘테이션을 위한 labeling 마스크 생성
def generate_mask_for_labeling(image_path):


with vision.InteractiveSegmenter.create_from_options(options) as segmenter:
    image_path = os.path.join(BASE_DIR, './images/table.jpg')
    cup_path = os.path.join(BASE_DIR, './images/cup.jpg')

    # 객체 강조 표시
    # highlight_object_with_blur(image_path)
    
    # 객체 잘라내기 및 붙이기
    cut_and_paste_object(cup_path, image_path)

    # 라벨링 마스크 생성
    # generate_mask_for_labeling(cup_path)

 

 

5. 예시 1 :  배경은 흐리게, 객체만 선명

highlight_object_with_blur(image_path) 함수는 입력 이미지에서 클릭한 객체를 중심으로 강조 표시하기 위해,
객체 외 배경 영역에 블러 효과를 적용하는 시각화 함수입니다.

사용자가 이미지를 클릭하면 MediaPipe의 세그멘테이션 모델을 통해 객체 마스크를 생성하고,
해당 객체는 선명하게 유지한 채 나머지 영역은 흐리게 처리하여 객체가 돋보이도록 시각적으로 강조합니다.

# 객체를 강조 표시하는 함수
def highlight_object_with_blur(image_path):
    image_bgr = cv2.imread(image_path)
    image_rgb = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2RGB)
    clone = image_rgb.copy()

    def mouse_callback(event, x, y, flags, param):
        if event == cv2.EVENT_LBUTTONDOWN:
            mask = segment_object(image_rgb, x, y)
            # 마스크를 사용하여 원본 이미지와 블러 처리된 이미지를 결합합니다.
            blurred_image = cv2.GaussianBlur(clone, (51, 51), 0)
            result = np.where(mask[:, :, None] == 0, clone, blurred_image)
            result = cv2.cvtColor(result, cv2.COLOR_RGB2BGR)
            cv2.imshow("Result", result)

    cv2.imshow("Image", image_bgr)
    cv2.setMouseCallback("Image", mouse_callback)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

MediaPipe Interactive Image Segmenter

 

6. 예시 2 : 객체를 잘라 배경에 붙여넣기

cut_and_paste_object(foreground_path, background_path) 함수는 사용자가 클릭한 객체를 전경 이미지에서 추출하여,
다른 배경 이미지 위에 자연스럽게 합성(붙이기) 하는 기능을 수행합니다.

객체를 클릭하면 MediaPipe 세그멘테이션을 통해 객체 마스크를 생성하고, 해당 영역을 투명 배경의 RGBA 이미지로 만들어 잘라낸 후, 배경 이미지의 중앙에 블렌딩 방식으로 합성하여 객체 이동 효과를 시각적으로 표현합니다.

# 객체를 잘라내고 배경에 붙이는 함수
def cut_and_paste_object(foreground_path, background_path):
    fg = cv2.imread(foreground_path)
    bg = cv2.imread(background_path)
    fg_rgb = cv2.cvtColor(fg, cv2.COLOR_BGR2RGB)

    def create_rgba_object(image_bgr, mask_binary):
        """
        마스크를 기반으로 객체만 추출하고 알파 채널 추가한 RGBA 이미지 생성
        """
        object_only = cv2.bitwise_and(image_bgr, image_bgr, mask=mask_binary)
        object_rgba = cv2.cvtColor(object_only, cv2.COLOR_BGR2BGRA)
        alpha_channel = (mask_binary * 255).astype(np.uint8)
        object_rgba[:, :, 3] = alpha_channel
        return object_rgba

    def crop_object_rgba(object_rgba):
        """
        알파 채널이 존재하는 RGBA 이미지에서 불투명 영역만 사각형으로 잘라냄
        """
        alpha = object_rgba[:, :, 3]
        x, y, w, h = cv2.boundingRect(alpha)
        return object_rgba[y:y + h, x:x + w]

    def overlay_rgba_on_background(bg_bgr, fg_rgba, x_offset, y_offset):
        """
        알파 채널을 포함한 RGBA 이미지를 배경 BGR 이미지 위에 블렌딩하여 삽입
        """
        fg_h, fg_w = fg_rgba.shape[:2]
        alpha = fg_rgba[:, :, 3:4] / 255.0
        bg_roi = bg_bgr[y_offset:y_offset + fg_h, x_offset:x_offset + fg_w]
        blended = (fg_rgba[:, :, :3] * alpha + bg_roi * (1 - alpha)).astype(np.uint8)
        bg_bgr[y_offset:y_offset + fg_h, x_offset:x_offset + fg_w] = blended
        return bg_bgr

    def click(event, x, y, flags, param):
        if event == cv2.EVENT_LBUTTONDOWN:
            mask = segment_object(fg_rgb, x, y)
            mask = (mask == 0).astype(np.uint8)  # 0: 객체, 1: 배경

            rgba_object = create_rgba_object(fg_rgb, mask)
            cropped_object = crop_object_rgba(rgba_object)

            # 대상 이미지 크기에 맞게 붙이기
            bg_h, bg_w = bg.shape[:2]
            obj_h, obj_w = cropped_object.shape[:2]
            x_offset = (bg_w - obj_w) // 2
            y_offset = (bg_h - obj_h) // 2

            # 배경에 붙이기
            composed = overlay_rgba_on_background(bg.copy(), cropped_object, x_offset, y_offset)
            result = cv2.cvtColor(composed, cv2.COLOR_RGBA2BGRA)
            cv2.imshow("Result", result)

    cv2.imshow("Foreground", fg)
    cv2.setMouseCallback("Foreground", click)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

MediaPipe Interactive Image Segmenter

 

7. 예시 3 : 라벨링용 마스크 저장

generate_mask_for_labeling(image_path) 함수는
입력 이미지에서 사용자가 클릭한 객체 영역을 자동으로 분할(masking)하고,
그 결과를 기반으로 세그멘테이션 학습용 라벨링 마스크 이미지를 생성 및 저장합니다.

클릭한 객체는 초록색으로 반투명하게 강조되어 시각적으로 확인 가능하며,
객체 영역은 흰색(255), 배경은 검정색(0)으로 구성된 이진 마스크(label_mask.png) 가 저장됩니다.
이 마스크는 딥러닝 세그멘테이션 모델 학습 시 라벨로 사용할 수 있습니다.

# 세그멘테이션을 위한 labeling 마스크 생성
def generate_mask_for_labeling(image_path):
    image_bgr = cv2.imread(image_path)
    image_rgb = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2RGB)
    clone = image_bgr.copy()

    def click(event, x, y, flags, param):
        if event == cv2.EVENT_LBUTTONDOWN:
            mask = segment_object(image_rgb, x, y)

            colored_mask = np.zeros_like(clone)
            colored_mask[mask == 0] = (0, 255, 0)

            # 원본 이미지(clone)는 70% 비중으로 유지되고
            # 객체 영역은 초록색으로 30% 비중으로 덧씌워져서
            # 반투명한 녹색 하이라이트가 생깁니다.
            blended = cv2.addWeighted(clone, 0.7, colored_mask, 0.3, 0)
            cv2.imshow("Label Mask", blended)

            # 마스크 저장 (객체 영역은 흰색 255)
            binary_mask = (mask == 0).astype(np.uint8) * 255
            cv2.imwrite("label_mask.png", binary_mask)

    cv2.imshow("Image", clone)
    cv2.setMouseCallback("Image", click)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

MediaPipe Interactive Image Segmenter

 

 


t7_interactive_segmenter.py
0.01MB

 

관련 글 링크

https://ai.google.dev/edge/mediapipe/solutions/vision/interactive_segmenter?hl=ko

 

대화형 이미지 세분화 작업 가이드  |  Google AI Edge  |  Google AI for Developers

LiteRT 소개: 온디바이스 AI를 위한 Google의 고성능 런타임(이전 명칭: TensorFlow Lite)입니다. 이 페이지는 Cloud Translation API를 통해 번역되었습니다. 의견 보내기 대화형 이미지 세분화 작업 가이드 Medi

ai.google.dev

[2.인공지능/MediaPipe] - 5.MediaPipe Hair Segmenter로 머리카락 염색 효과 테스트

 

5.MediaPipe Hair Segmenter로 머리카락 염색 효과 테스트

MediaPipe의 Hair Segmenter를 활용하면 이미지 속 머리카락을 감지하여 자연스러운 색상 변경 효과를 구현할 수 있습니다.이 글에서는 머리카락을 분리한 뒤 3가지 방식으로 염색 효과를 테스트하며,

quadcube.tistory.com

[2.인공지능/MediaPipe] - 4.MediaPipe Image Segmentation 사용하기 : 이미지 분할

 

4.MediaPipe Image Segmentation 사용하기 : 이미지 분할

MediaPipe Image Segmenter의 주요 기능과 실행 모드를 중심으로 이미지 세그멘테이션의 개념과 활용법을 소개합니다.SelfieSegmenter, HairSegmenter, SelfieMulticlass, DeepLab-v3 등 다양한 모델 비교와 Python 코드 예

quadcube.tistory.com

 

728x90