그래디언트 크기를 구하고 임계값을 설정해줘서 에지를 검출할 경우, 윤곽선이 너무 두껍게 표현된다는 단점이 있다.
이를 보완한 것이 캐니 에지 검출 방법이다.
캐니 에지 검출
- 좋은 에지 검출기의 조건
- 정확한 검출 - Good detection
픽셀이 조명에 의해 미세한 영향을 받게 되어 임계점보다 크거나 낮아질 수 있다.
이처럼 에지가 아닌 점을 에지로 찾거나 또는 에지인데 에지로 찾지 못하는 확률을 최소화 한것을 정확한 검출이라고 한다. - 정확한 위치 - Good localization
실제 에지의 중심을 검출하는 것 - 단일 에지 - Single edge
하나의 에지는 하나의 점으로 표현한다는 것
이 세가지 조건을 충족해야 좋은 에지라고 할 수 있다.
케니 에지 검출 4단계
1. 가우시안 필터링
가우시안 필터링을 통해 잡음을 제거한다.
소벨필터에 어느정도 가우시안이 적용되어 있으므로 선택적이다.
2. 그래디언트 계산
그래디언트 계산은 주로 소벨 마스크를 사용한다.
이전에는 크기만 계산하여 윤곽선을 추출했지만 캐니 에지 검출은 크기와 방향 모두 사용한다.
방향은 4구역으로 단순화 한다. 45도를 한 구역으로 설정하고 180도에 대한 4구역을 구한다. 나머지 180도는 계산된 구역의 대칭부분이므로 4구역만 이용한다.
3. 비최대 억제 - Non maximum suppression
비 최대 억제는 최대 크기의 픽셀만 골라내서 에지 픽셀로 설정하는 것이다.
하나의 에지가 여러 개의 픽셀로 표현되는 현상을 없애기 위하여 그래디언트 크기가 국지적 최대(local maximum)인 픽셀만을 에지 픽셀로 설정한다.
그래디언트 방향에 위치한 두 개의 픽셀을 조사하여 국지적 최대를 검사한다.
소벨필터 임계값으로 에지를 검출할 때 5개가 검출된다면 이 중 최댓값은 1개이다. 이 최댓값만 도출한다.
미분값을 좌우랑 비교해서 오른쪽, 왼쪽보다 크면 에지로 선정하고 나머지는 다 없앤다.
그래디언트 방향에 위치한 픽셀만을 조사한다.
4. 히스테리시스 에지 트래킹 - Hysteresis edge tracking
두 개의 임계값을 사용한다. ($T_{low}$, $T_{high}$)
조명이나 다른 변수의 영향으로 인해 영상의 그래디언트가 미세하게 변화할 수 있다. 이때 픽셀 값이 임계점보다 커지거나 낮아질 수 있는데, 이를 방지하기 위해 두 개의 임계값을 이용한다.
상한 임계값, 하한 임계값 두 개를 이용한다.
- 상한 임계값보다 높으면 강한 에지가 되며 항상 에지로 선정
- 상한 임계값보다 작고 하한 임계값보다 높으면 약한 에지로 부르는데 강한 에지와 연결되어 있으면 에지로 선정
- 하한 임계값보다 작으면 에지가 아님
☑︎ 캐니 에지 검출 과정
✔︎ 캐니 에지 검출 함수 - cv2.Canny
edges = cv2.Canny(image, threshold1, threshold2, edges=None, apertureSize=None,
L2gradient=None)
- image : 입력 영상
- threshold1 : 하단 임계값
- threshold2 : 상단 임계값
- edges : 에지 영상
- apertureSize : 소벨 연산을 위한 커널 크기. 기본값은 3
- L2gradient : True이면 L2 norm 사용, False이면 L1 norm 사용. 기본값은 False.
L2gradient인자에서 L2 norm이 L1 norm보다 정확하지만 연산이 오래걸려 속도가 느리다. 그래서 L1 norm(기본값)을 주로 이용한다.
주의할 점은 입력 영상에 그레이스케이 영상을 입력해주는 것이 좋다.
컬러 영상을 입력할 시에 RGB픽셀 따로따로 캐니해서 최댓값을 검출하므로 가급적으로 그레이스케일 영상으로 입력하는 것이 좋다.
💬 캐니 에지 검출 예제
import sys
import numpy as np
import cv2
src = cv2.imread('building.jpg', cv2.IMREAD_GRAYSCALE)
if src is None:
print('Image load failed!')
sys.exit()
dst = cv2.Canny(src, 50, 150)
cv2.imshow('src', src)
cv2.imshow('dst', dst)
cv2.waitKey()
cv2.destroyAllWindows()
⬇︎
'OpenCV' 카테고리의 다른 글
[OpenCV with Python] 영상의 특징 추출 : 영상에서 원 검출하기 - 허프 변환 (0) | 2022.02.04 |
---|---|
[OpenCV with Python] 영상의 특징 추출 : 영상에서 직선 검출하기 - 허프 변환 (0) | 2022.02.04 |
[OpenCV with Python] 영상의 특징 추출 : 그래디언트와 에지 검출 (0) | 2022.02.04 |
[OpenCV with Python] 영상의 특징 추출 : 영상의 미분과 소벨 필터 (0) | 2022.02.04 |
[OpenCV with Python] 영상 기하학적 변환 : 리매핑(remapping) - cv2.remap (0) | 2022.02.02 |