주요 콘텐츠

Segment Anything Model을 사용하여 대화형 ROI에서 객체 분할하기

이 예제에서는 SAM(Segment Anything Model)을 사용하여 영상에서 선택한 ROI(관심 영역)에 있는 객체를 대화형 방식으로 분할하는 방법을 보여줍니다.

SAM은 딥러닝 신경망을 사용하여 훈련 없이도 영상 내 객체를 정확하게 분할합니다[1]. SAM을 사용하면 점, 상자, 마스크 로짓 같은 시각적 프롬프트를 통해 사용자가 피드백을 제공하여 분할을 적극적으로 유도하고 미세 조정할 수 있습니다. 이 예제에서는 SAM이 대화형 방식으로 영상에서 선택한 ROI를 시각적 프롬프트로 사용합니다. SAM을 시작하려면 Get Started with Segment Anything Model for Image Segmentation 항목을 참조하십시오.

이 예제를 실행하려면 Image Processing Toolbox™ Model for Segment Anything Model이 필요합니다. 애드온 탐색기에서 Image Processing Toolbox Model for Segment Anything Model을 설치할 수 있습니다. 애드온 설치에 대한 자세한 내용은 애드온을 받고 관리하기 항목을 참조하십시오. Image Processing Toolbox Model for Segment Anything Model을 사용하려면 Deep Learning Toolbox™와 Computer Vision Toolbox™가 필요합니다.

샘플 영상 불러오기

샘플 영상을 작업 공간으로 불러옵니다. 최적의 SAM 성능을 위해 데이터 범위가 [0, 255]인 영상(예: uint8형 영상)을 사용하십시오. 입력 영상의 데이터 범위가 더 크면 rescale 함수를 사용하여 픽셀 값 범위를 다시 스케일링하십시오.

I = imread("peppers.png");

모델 만들기

segmentAnythingModel 객체를 사용하여 SAM을 만듭니다.

samObj = segmentAnythingModel;

임베딩 추출하기

계산 시간을 줄이기 위해 가능한 경우 GPU 프로세싱을 사용하십시오.

if(canUseGPU)
    I = gpuArray(I);
end

extractEmbeddings 객체 함수를 사용하여 이 모델의 인코더로부터 입력 영상 I의 특징 임베딩을 추출합니다.

embeddings = extractEmbeddings(samObj,I);

대화형 인터페이스 구성하기

SAM 대화형 분할을 위해 영상 디스플레이를 준비합니다. 새 Figure 창과 좌표축을 만들고 영상을 표시합니다.

f = figure;
hAX = axes(f);
hIm = imshow(I,Parent=hAX);

drawrectangle 함수를 사용하여, 분할할 객체가 포함된 ROI를 영상 위에 Rectangle 객체로 지정합니다. 영상 디스플레이에서 분할하려는 객체 주위에 사각형 ROI를 그립니다.

roi = drawrectangle(hAX);

Figure contains an axes object. The hidden axes object contains 2 objects of type image, images.roi.rectangle.

영상에서 대화형 방식으로 객체 분할하기

객체를 분할하기 위해, segmentObjectsFromEmbeddings 객체 함수를 사용하여 영상 특징 임베딩에 대해 SAM 디코더를 실행합니다. 경계 상자의 시각적 프롬프트 BoundingBox를 영상 디스플레이에서 대화형 방식으로 그려놓은 사각형 ROI의 위치로 지정합니다.

mask = segmentObjectsFromEmbeddings(samObj,embeddings,size(I),BoundingBox=roi.Position);

insertObjectMask (Computer Vision Toolbox) 함수를 사용하여, 영상 디스플레이에서 분할 마스크가 영상에 겹쳐지게 시각화합니다.

imgOverlay = insertObjectMask(gather(I),mask);
hIm.CData = imgOverlay; 

Figure contains an axes object. The hidden axes object contains 2 objects of type image, images.roi.rectangle.

이동 가능한 ROI에서 대화형 방식으로 객체 분할하기

영상 디스플레이에서 사용자가 객체 주위로 ROI를 이동하거나 ROI 크기를 조정할 때마다 객체가 자동 분할되도록 하기 위해, addlistener 함수를 사용하여 ROI 이동 이벤트에 대한 리스너를 구성합니다. 여기에 정의된 segmentObjectInROI 헬퍼 함수를 사용하여 리스너 콜백을 지정합니다. segmentObjectInROI 헬퍼 함수는 지정된 ROI의 현재 위치에서 객체 분할을 수행하고, 영상에 분할 마스크를 표시합니다.

function segmentObjectInROI(evt,samObj,embeddings,img,hIm)
    boxPrompt = evt.CurrentPosition;
    mask = segmentObjectsFromEmbeddings(samObj,embeddings,size(img),BoundingBox=boxPrompt);
    imgOverlay = insertObjectMask(gather(img),mask);
    hIm.CData = imgOverlay; 
end
addlistener(roi,"ROIMoved",@(src,evt)segmentObjectInROI(evt,samObj,embeddings,I,hIm));

영상 내 여러 다른 객체 주위로 ROI를 이동하거나 ROI 크기를 조정하여 각 객체를 분할합니다. 아래 GIF는 각 객체 주변으로 ROI를 이동하고 ROI 크기를 조정하여 한 번에 하나씩 객체를 분할하는 방법을 보여줍니다.

SAM_GIF.gif

참고 문헌

[1] Kirillov, Alexander, Eric Mintun, Nikhila Ravi, Hanzi Mao, Chloe Rolland, Laura Gustafson, Tete Xiao, et al. "Segment Anything," April 5, 2023. https://doi.org/10.48550/arXiv.2304.02643.

참고 항목

| |

도움말 항목