[OpenCV] 캐니 에지 검출기(Canny edge detector)

이번 글에서는 캐니 에지검출기(Canny edge detector) 에 대해 알아보겠습니다.

캐니 에지 검출기는 John Canny가 1986년에 효과적인 에지 검출에 대해 제시한 방법입니다.
아래 3가지 항목에 대해 충족하고자 하였습니다.

  1. Good detection
    – 에지를 검출하지 못하거나, 에지가 아닌데  검출하는 확률을 최소화
  2. Good localiztion
    – 실제 에지의 중심을 검출
  3. Single edge
    – 하나의 에지는 하나의 점으로 표현

위 조건을 충족하기 위해 캐니 에지 검출기는 아래 과정을 수행합니다.

첫번째, 잡음 제거

생략이 가능하며, 잡음 제거를 위해 가우시안 필터를 적용합니다.

두번째, 그래디언트 계산

첫번째 작업을 통해 잡음이 제거된 이미지에서, 그래디언트의 크기와 방향을 모두 고려합려합니다.

세번째, 비최대 억제

그래디언트를 얻고 난 후 비최대 억제 과정을 사용하여 에지가 두껍게 표현되는 현상을 방지합니다.

네번째, 이중 임계값을 사용한 히스테리시스 에지 트래킹

소벨처럼 특정 임계값보다 크면 에지로 인식, 작으면 에지가 아닌걸로 판단하는게 아니라 두개의 임계값을 사용합니다.

OpenCV에서 제공하는 캐니 에지 함수는 아래와 같습니다.

/** 
@param image 8bit 입력 영상
@param edges 출력 에지 영상. 8비트 단일 채널 영상
@param threshold1 첫번째 임계값
@param threshold2 두번째 임계값
@param apertureSize 소벨 마스크 크기
@param L2gradient 그래디언트 크기 계산 시 L2 노름을 사용할지 여부
 */
void Canny( InputArray image, OutputArray edges, double threshold1, double threshold2, int apertureSize = 3, bool L2gradient = false );

샘플 코드는 아래와 같습니다.

Mat src = imread("lenna.bmp", IMREAD_GRAYSCALE);
if (src.empty())
{
	cerr << "image load fail" << endl;
	return ;
}

Mat canny1;
Canny(src, canny1, 50, 100);

imshow("src", src);
imshow("canny1", canny1);

waitKey();
destroyAllWindows();

실행 결과는 아래와 같습니다.