개강한 공대생 2024. 10. 2. 23:00

void grabCut(cv::InputArray img, cv::InputOutputArray mask, cv::Rect rect, cv::InputOutputArray bdgModel, cv::InputOutputArray fgdModel, int iterCount, int mode)

이렇게 생겼다.

 

mask는 객체와 배경을 구분하는 마스크 이미지다. 여기서는 객체인지, 배경인지, 혹은 잘 모르는 부분인지 표시할 수 있다.

 

  • GC_BGD (0): 확실한 배경
  • GC_FGD (1): 확실한 객체
  • GC_PR_BGD (2): 아마도 배경
  • GC_PR_FGD (3): 아마도 객체

rect는 객체 이 포함된 사각형 영역의 좌표를 지정한다. 

bdgModel랑 fgdModel는 비워두면 알고리즘이 알아서 사용한다.

iterCount는 알고리즘이 수행할 반복 횟수로  보통 1 이상으로 설정하면 된다.

mode는 두 가지가 있다.

 

  • GC_INIT_WITH_RECT: 사각형으로 전경을 지정하는 모드. 처음에는 사각형으로 전경을 지정하고 알고리즘을 실행
  • GC_INIT_WITH_MASK: 마스크를 사용해 전경과 배경을 직접 지정하는 모드. 이 모드를 사용하면 사용자가 마스크를 통해 더 세밀하게 조정할 수 있다.

다음은 예제 코드다

여기서 나오는 전경은 객체를 말한다.

int main() {
    Mat result, bgdModel, fgdModel, image, foreground; // 결과 이미지와 전경/배경 모델, 원본 이미지, 전경 이미지를 저장할 변수들 선언
    image = imread("dog.png"); // 이미지를 불러옴

    // 전경을 포함하는 사각형 영역 지정 (x, y, width, height)
    Rect rectangle(15, 0, 155, 240);

    // GrabCut 알고리즘 실행 (전경/배경 모델 업데이트)
    grabCut(image, result, rectangle, bgdModel, fgdModel, 10, GC_INIT_WITH_RECT);

    // 전경 추출을 위해 결과 마스크를 이용해 전경과 아마도 전경인 부분을 비교
    compare(result, GC_PR_FGD, result, CMP_EQ);

    // 전경을 하얀색(255, 255, 255)으로 초기화하고, 전경 영역에 결과 복사
    foreground = Mat(image.size(), CV_8UC3, Scalar(255, 255, 255));
    image.copyTo(foreground, result);

    // 원본 이미지, GrabCut 결과 이미지, 추출된 전경 이미지 보여주기
    imshow("original", image); // 원본 이미지
    imshow("Result", result); // GrabCut 결과 (마스크)
    imshow("Foreground", foreground); // 추출된 전경 이미지
    
    waitKey(0); // 키 입력 대기
}