Python/파이썬 OpenCV 공부

[파이썬 OpenCV] 영상의 윤곽선 검출하기 - 캐니 에지 검출 - cv2.Canny

AI 꿈나무 2020. 10. 8. 21:34
반응형

황선규 박사님의 <OpenCV 4로 배우는 컴퓨터 비전과 머신 러닝>를 공부한 내용을 정리해 보았습니다.

 

예제 코드 출처 :  황선규 박사님 github홈페이지

 

『OpenCV 4로 배우는 컴퓨터 비전과 머신 러닝』

예제 소스 코드는 아래 링크를 참고하세요

sunkyoo.github.io


 

 

[파이썬 OpenCV] 영상의 그래디언트와 에지 검출하기

황선규 박사님의 과 패스트 캠퍼스 OpenCV 강의를 공부하면서 내용을 정리해 보았습니다. 예제 코드 출처 :  황선규 박사님 github홈페이지 『OpenCV 4로 배우는 컴퓨터 비전과 머신 러닝』 예제 소��

deep-learning-study.tistory.com

 이전 포스팅에서 그래디언트 크기를 구하고 임계값을 설정해줘서 에지를 검출했습니다. 하지만 윤곽선이 너무 두껍게 표현된다는 단점이 있었습니다.

 이를 보완한 것이 캐니 에지 검출 방법입니다.

 

캐니 에지 검출

 좋은 에지 검출기의 조건은 3가지 입니다.

 

1. 정확한 검출 - Good detection

 픽셀이 조명에 의해 미세한 영향을 받게 되어 임계점보다 크거나 낮아질 수 있습니다.

 이처럼 에지가 아닌 점을 에지로 찾거나 또는 에지인데 에지로 찾지 못하는 확률을 최소화 한것을 정확한 검출이라고 합니다.

 

2. 정확한 위치 - Good localization

 실제 에지의 중심을 검출하는 것입니다.

 

3. 단일 에지 - Single edge

 하나의 에지는 하나의 점으로 표현한다는 것입니다.

 

 이 세가지 조건을 충족해야 좋은 에지라고 할 수 있습니다.

 

케니 에지 검출 4단계

 케니 에지 검출 방법은 4단계로 구성되어 있습니다.

 

1. 가우시안 필터링

 가우시안 필터링을 통해 잡음을 제거합니다.

 쇼벨필터에 어느정도 가우시안이 적용되어 있으므로 선택적입니다.

 

2. 그래디언트 계산

 그래디언트 계산은 주로 소벨 마스크를 사용합니다.

 크기와 방향을 계산합니다.

 이전 포스팅에서는 크기만 계산하여 윤곽선을 추출했지만 캐니 에지 검출은 크기와 방향 모두 이용합니다.

 

 

 방향은 4구역으로 단순화 합니다.

 45도를 한 구역으로 설정하고 180도에 대한 4구역을 구합니다.

 나머지 180도는 계산된 구역의 대칭부분이므로 4구역만 이용합니다.

 4부분만 처리한다면 연산 속도는 빨라질 것입니다.

 

3. 비최대 억제 - Non maximum suppression

 비 최대 억제는 최대 크기의 픽셀만 골라내서 에지 픽셀로 설정하는 것입니다.

 하나의 에지가 여러 개의 픽셀로 표현되는 현상을 없애기 위하여 그래디언트 크기국지적 최대(local maximum)인 픽셀만을 에지 픽셀로 설정합니다.

 

 그래디언트 방향에 위치한 두 개의 픽셀을 조사하여 국지적 최대를 검사합니다.

 

 소벨필터 임계값으로 에지를 검출할 때 5개가 검출된다면 이 중 최댓값은 1개입니다. 이 최댓값만 도출하는 것입니다.

 미분값을 좌우랑 비교해서 오른쪽, 왼쪽보다 크면 에지로 선정하고 나머지는 다 없앱니다.

 그래디언트 방향에 위치한 픽셀만을 조사합니다.

 

 

비최대 억제

 

 이처럼 그래디언트 방향의 최댓값을 제외하고 모든 픽셀을 제거한 것을 확인할 수 있습니다.

 

4. 히스테리시스 에지 트래킹 - Hysteresis edge tracking

 두 개의 임계값을 사용합니다.

 조명이나 다른 변수의 영향으로 인해 영상의 그래디언트가 미세하게 변화할 수 있습니다.

 이때문에 픽셀 값이 임계점보다 커지거나 낮아질 수 있는데, 이를 방지하기 위해 두 개의 임계값을 이용합니다.

 

 상한 임계값, 하한 임계값 두 개를 이용합니다.

 상한 임계값보다 높으면 강한 에지가 되며 항상 에지로 선정합니다.

 상한 임계값보다 작고 하한 임계값보다 높으면 약한 에지로 부르는데 강한 에지와 연결되어 있으면 에지로 선정합니다.

 하한 임계값보다 작으면 에지가 아닙니다.

 

 조명이나 다른 변수에 의해 에지가 갑자기 나타날 수 있습니다. 이를 방지해줍니다.

 

 

 이처럼 작은 에지들이 비최대 억제로 인해 검출된 에지입니다.

 이를 히스테리스 에지 트래킹으로 없앨 수 있습니다.

 

캐니 에지 검출 함수 - cv2.Canny

 OpenCV에서 캐니 에지 검출 함수를 제공하고 있습니다.

 

cv2.Canny(image, threshold1, threshold2, edges=None, apertureSize=None, L2gradient=None) -> edges

• image: 입력 영상
• threshold1: 하단 임계값
• threshold2: 상단 임계값
• edges: 에지 영상
• apertureSize: 소벨 연산을 위한 커널 크기. 기본값은 3
• L2gradient: True이면 L2 norm 사용, False이면 L1 norm 사용. 기본값은 False.

 하단 임계값과 상단 임계값은 실험상으로 결정해야 합니다.

 L2gradient인자에서 L2 norm이 L1 norm보다 정확하지만 연산이 오래걸려 속도가 느립니다.

 L1 norm(기본값)을 주로 이용합니다.

 

 주의할 점은 입력 영상에 그레이스케이 영상을 입력해주는 것이 좋습니다.

 컬러 영상을 입력할 시에 RGB픽셀 따로따로 캐니해서 최댓값을 검출하므로 가급적으로 그레이스케일 영상으로 입력하는 것이 좋습니다. 

 

캐니 에지 검출 예제

 황선규 박사님의 깃허브 코드를 참고했습니다.

 

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()

 

입력 영상

 

출력 영상

 

반응형