0. Contour Detection
contour은 윤곽이라는 뜻을 나타내며, Contour Detection은 이미지에서 객체의 contour을 추출하는 작업을 의미한다.
이러한 고전 컴퓨터비전의 Contour Detection은 일반적으로 딥러닝 모델 학습을 위한 데이터 가공시에 활용하는 편이다.
딥러닝을 이용하여 task를 수행하기 위해서는 다량의 데이터가 필요한데 이러한 데이터를 딥러닝을 이용하여 생성하다보면 딥러닝의 취약점을 가진 이미지들이 생성되기 떄문에 관계없는 방법으로 생성한 데이터를 이용하여 학습한다.
Contour Detection은 아래의 과정을 거쳐서 진행되는데 각각의 과정에 대하여 알아보도록 하자.
`Edge Detection` -> `Dilation`->`Contour Detection`
1. Edge Detection
우선 `Edge`란 이미지, 영상에서 픽셀값이 한쪽으로 급격하게 변하는 부분을 가리킨다. 사물과 사물이나 사물과 배경 사이에 Edge가 존재하기 때문에 이러한 것들을 구분할 수 있는 것이다.
Edge Detection 작업에는 보통 컴퓨터 비전에서 가장 많이 사용되는 `Canny Edge Detector`을 사용한다.
이는 1996년에 John Canny가 개발한 Detector이다.
장점으로는 정확도가 높으나, 실행시간이 느리고 구현이 복잡하다는 단점이 있다.
Canny Edge Detector은 4가지 단계를 거쳐 실행된다.
노이즈제거 ->이미지 내 높은 미분값 찾기 -> 최대값이 아닌 픽셀 값 0으로 치환 -> 하이퍼파라미터 튜닝을 통한 엣지 검출.
코드로는 OpenCV에 있는 함수를 통해 한줄로 적용해볼 수 있다.
edges = cv2.Canny(img, 350, 500) # Canny Edge Detection을 수행합니다
1-1. 노이즈 제거
이미지 내에 노이즈가 존재한다면 엣지를 찾는데 어려움을 겪기 때문에 사전에 `가우시안 필터`를 이용하여 노이즈를 제거해준다.
가우시안 필터는 가우시안 분포 함수를 근사하여 만든 필터 마스크로, 이 마스크 행렬은 중앙부에서 큰 값을 가지고 외각으로 갈 수록 0에 가까운 작은 값을 가진다.
1-2. Find the intensity gradient
다음으로 sobel 커널을 각 방향으로 적용하여 gradient를 추출한다. sobel 커널이란 행 또는 열의 변화율을 계산하는 마스크로 엣지 검출에 특화적이다.
엣지란 위에서 픽셀값이 급격히 변하는 부분이라고 언급했었는데, 따라서 이를 찾기위해서는 픽셀값의 변화율을 구하면 된다. 이 변화율은 즉 미분값을 의미한다. 엣지는 급격히 변하는 부분이라고 했으므로, 가장 높은 미분값을 찾으면 된다.
그러기 위해서는 미분값들을 모두 구해야한다.
픽셀의 미분값을 구하기 위해서 중앙 차분에서 파생된 특정 미분 마스크를 사용하여 각 픽셀의 영역과 곱한 뒤 모두 더하는 연산을 하면 미분을 근사화할 수 있게 된다. 위의 이미지에서 왼쪽은 x축 방향의 미분 마스크, 오른쪽은 y축 방향의 미분 마스크를 의미한다. Sobel Kernel은 위의 단순한 커널을 보다 범위가 크게 만든 커널을 사용한다.
아래와 같이 특정 이미지를 x축과 y축의 커널을 이용하여 분리한 이미지를 볼 수 있는데, 오른쪽 사진에서 기둥의 경우 엣지가 수평방향으로 있기 때문에 x축 커널에서는 검출되고 y축 커널에서는 검출되지 않는 것을 볼 수 있다.
이렇게 커널을 적용한 후 적절한 thresh hold를 설정하여 이미지의 edge를 구분한다.
이러한 미분마스크의 수학적 접근은 다음 블로그를 참고하면 좋을 것 같다.
https://velog.io/@olxtar/Sobel-Kernel
1-3. Non Maximum Suppression
다음으로 엣지 검출에 기여하지 않은 픽셀을 제거하는 과정으로, 각 방향마다 이전에 구한 gradient값을 비교하며 엣지가 아닌 것으로 판단되는 픽셀값들을 0으로 치환(제거)한다.
sober 필터를 적용하여 다음과 같은 gradient 값들이 나왔다고 할 때, 우선 필터의 중심 5를 기준으로 8개의 방향에대하여 확인을한다. 8개의 방향에 `7`이라는 현재 커널의 중심 `5`보다 큰 값이 있기 때문에 이 5는 0으로 치환된다.
필터를 움직이며 과정을 반복하고 최종적으로 오른쪽 이미지와 같이 변환된다.
1-4. Hyteresis Thresholding
마지막으로 하이퍼 파라미터 튜닝의 과정으로, 여러 threshold를 적용하며 적절한 edge를 찾게된다.
1-5. Edge Detection 참고 블로그
사실 Contour Detection은 위의 Edge Detection에서 검출된 Edge들을 모두 잇기만 하면 된다.
이러한 Contour Detection의 프로세스 또한 OpenCV 라이브러리에 `cv2.findContours()`에 쉽게 구현되어있어 사용해볼 수 있다.
# contours 변수에 경계선을 찾아 저장합니다. cv2.RETR_EXTERNAL로 외부 경계만 검출하며, cv2.CHAIN_APPROX_SIMPLE로 경계점을 간결하게 저장합니다.
contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
Edge를 모두 이을경우 너무 세밀한 부분의 엣지들도 전부 포함될 수도 있기 때문에 `Dilation`과 같은 과정을 거쳐서 보완해줄 수도 있다.
위의 이미지가 Deilation을 적용하지 않은 이미지이고, 아래 이미지가 적용한 뒤 Contour Detection을 한 과정이다.
'ML & DL > Computer vision' 카테고리의 다른 글
AlexNet (0) | 2024.01.30 |
---|---|
Backbone과 Decoder 개념 (0) | 2024.01.29 |
Morphological Transform (0) | 2024.01.29 |
DeepLabV3plus (0) | 2023.10.26 |
U-Net (0) | 2023.10.26 |