가우시안 블러와 엣지 검출
입력 영상은 미세한 노이즈가 포함되어 있기 때문에 엣지를 딸 때, 바로 미분을 적용한다면, 모든 구간에서 높은 엣지 값을 가질 수 있음
따라서 가우시안 블러를 적용하여 잡음을 제거한 후 엣지를 검출하는 것이 바람직함
1차 미분의 근사화
전진 차분(forward difference):
∂ I ∂ x ≅ I ( x + h ) − I ( x ) h \frac{\partial I}{\partial x} \cong \frac{I(x+h)-I(x)}{h} ∂ x ∂ I ≅ h I ( x + h ) − I ( x )
후진 차분(backward difference):
∂ I ∂ x ≅ I ( x ) − I ( x − h ) h \frac{\partial I}{\partial x} \cong \frac{I(x)-I(x-h)}{h} ∂ x ∂ I ≅ h I ( x ) − I ( x − h )
중앙 차분(centered difference): 가장 정확하게 계산하는 방식
중앙 차분 미분 마스크: {-1, 0, 1} (x로 미분, 세우면 y로 미분)
∂ I ∂ x ≅ I ( x + h ) − I ( x − h ) 2 h \frac{\partial I}{\partial x} \cong \frac{I(x+h)-I(x-h)}{2h} ∂ x ∂ I ≅ 2 h I ( x + h ) − I ( x − h )
\\
\\
다양한 에지 검출 마스크
TIP : 각 픽셀에 중간값인 128을 더해줘야 미분 값 < 0 혹은 미분값 > 255 인 부분을 잘 캐치해낼 수 있음
\\
\\
영상의 그래디언트
함수 f ( x , y ) f(x,y) f ( x , y ) 를 x x x 축과 y y y 으로 각각 편미분(partial derivative) 하여 벡터 형태로 표현
Δ f = [ f x f y ] = f x i + f y j \Delta f= \begin{bmatrix}f_{x} \\ f_{y} \end{bmatrix}=f_{x}i+f_{y}j Δ f = [ f x f y ] = f x i + f y j
그래디언트 크기(magnitude): 픽셀 값의 차이 정도, 변화량
크기는 f x f_{x} f x 와 f y f_{y} f y 벡터로 쪼갤 수 있음
직전 상태가 많이 어두웠다가 많이 밝아질수록 크기가 커짐
∣ Δ f ∣ = f x 2 + f y 2 |\Delta f|= \sqrt{f_{x}^2+f_{y}^2} ∣ Δ f ∣ = f x 2 + f y 2
그래디언트 방향(phase): 픽셀 값이 가장 급격하게 증가하는 방향
영상에서는 어두운쪽에서 밝은 쪽으로 향하는 방향
그래디언트 방향과 수직인 방향은 보통 접선으로, 엣지의 방향 이라 생각할 수 있음
θ = t a n − 1 ( f y f x ) \theta= tan^{-1} \bigg(\frac{\displaystyle f_{y}}{\displaystyle f_{x}}\bigg) θ = t a n − 1 ( f x f y )
\\
\\
소벨 필터를 이용한 엣지 검출
Sobel function으로 엣지를 구할 때, thresholds를 사용하여 자르는데, 크기가 강한 부분은 thresholds로 잘라도 그대로 살아남아있어서 더 선이 굵게 표현될 수 있고, 반면 thresholds근방의 살아남은 픽셀은 소수라서 선이 얇게 표현될 수 있음
void Sobel ( InputArray src, OutputArray dst, int ddepth,
int dx, int dy, int ksize= 3 , double scale= 1 ,
double delta= 0 , int borderType= BORDER_DEFAULT) ;
src
: 입력 영상
dst
: 출력 영상. src와 같은 크기, 같은 채널 수.
ddepth
: 출력 영상 자료형, -1이면 입력 영상과 같음, float 타입을 원하면 CV_32F
.
dx
, dy
: x방향과 y방향으로의 미분 차수, 보통 0,1 혹은 1,0으로 지정해서 dy 혹은 dx를 계산
ksize
: 커널 크기
kernel size description 1 3x1 or 1x3 커널 사용 CV_CHARR 3x3 Scharr 커널 사용, Scharr() 함수 사용과 같음 3, 5, 7 3x3, 5x5, 7x7 커널 사용
scale
: (Optional) 연산 결과에 추가적으로 곱할 값
delta
: (Optional) 연산 결과에 추가적으로 더할 값
borderType
: 가장자리 픽셀 확장 방식
\\
\\
케니 엣지 검출기
소벨 필터를 이용한 엣지 검출의 장단점
장점: 비교적 간단한 필터링 연산과 임계값 연산으로 엣지 위치를 검출할 수 있음
단점: 그래디언트 크기만을 사용하기 때문에 엣지 위치가 여러 개의 픽셀로 표현될 수 있음
J. Canny가 제안한 좋은 엣지 검출기의 조건
정확한 검출(Good detection): 엣지가 아닌 점을 엣지로 찾거나 또는 엣지를 검출하지 못하는 확률을 최소화
정확한 위치(Good localization): 실제 엣지의 중심 을 검출
단일 엣지(Single edge): 하나의 엣지는 하나의 점으로 표현
Idea : Gradient로 local maxima를 찾아서 이 한 픽셀을 엣지로 사용하겠다!
케니 엣지 검출 방법
가우시안 필터링
그래디언트 계산(크기 & 방향)
비최대 억제
이중 임계값을 이용한 히스테리시스 엣지 트래킹
가우시안 필터링
(Optional) 잡음 제거 목적 : GaussianBlur()
G σ = 1 2 π σ 2 e x p ( − x 2 + y 2 2 σ 2 ) G_{\sigma}=\frac{\displaystyle 1}{\displaystyle 2\pi \sigma^{2}}exp\bigg(-\frac{\displaystyle x^{2}+y^{2}}{\displaystyle2\sigma^{2}} \bigg) G σ = 2 π σ 2 1 e x p ( − 2 σ 2 x 2 + y 2 )
그래디언트 계산
주로 소벨 마스크 사용, 소벨 함수 사용하면 가우시안 필터링 생략 가능
그래디언트 크기(magnitude): 픽셀 값의 차이 정도, 변화량
∣ Δ f ∣ = f x 2 + f y 2 |\Delta f|= \sqrt{f_{x}^2+f_{y}^2} ∣ Δ f ∣ = f x 2 + f y 2
그래디언트 방향(phase): 픽셀 값이 가장 급격하게 증가하는 방향
그래디언트 방향을 4개 구역으로 단순화 해서,
1) 양옆, 2) 위아래, 3) (+)대각선, 4) (-)대각선 방향
으로 그래디언트의 위치를 찾음.
이미지에서 보면 중심 픽셀을 기준으로, 주변 8픽셀들을 관찰하는 것으로 볼 수 있음
다음 단계인 비최대 억제 에 활용
θ = t a n − 1 ( f y f x ) \theta= tan^{-1} \bigg(\frac{\displaystyle f_{y}}{\displaystyle f_{x}}\bigg) θ = t a n − 1 ( f x f y )
비최대 억제(Non-maximum suppresion)
하나의 엣지가 여러 개의 픽셀로 표현되는 현상을 없애기 위하여 그래디언트 크기가 국지적 최대(local maximum)인 픽셀만을 엣지 픽셀로 설정
그래디언트 방향에 위치한 두 개의 픽셀과 국지적 최대를 검사
애초에 그래디언트 방향을 알고 있기 때문에, 이와 수직인 엣지를 보존하려면 단순화를 위해 해당 위치에 정해진 양 옆 그래디언트 두 개의 픽셀만 선택해서 비교하면 됨
이중 임계값을 이용한 히스테리시스 엣지 트래킹
두 개의 임계값을 사용: T L o w , T H i g h T_{Low}, T_{High} T L o w , T H i g h
밝기 변화에 따라서 특정 임계값을 넘는 픽셀값이 다를 수 있어, 두개의 임계값을 사용하는 형태로 변형.
∣ ∣ ∇ f ∣ ∣ ≥ T H i g h ||\nabla f|| \ge T_{High} ∣ ∣ ∇ f ∣ ∣ ≥ T H i g h :
∣ ∣ ∇ f ∣ ∣ ≤ T L o w ||\nabla f|| \le T_{Low} ∣ ∣ ∇ f ∣ ∣ ≤ T L o w :
T L o w ≤ ∣ ∣ ∇ f ∣ ∣ ≤ T H i g h T_{Low} \le ||\nabla f|| \le T_{High} T L o w ≤ ∣ ∣ ∇ f ∣ ∣ ≤ T H i g h :
약한 엣지. 강한 엣지와 연결된 픽셀만 최종 엣지로 선정
케니 엣지 검출기 함수
void Canny ( InputArray image, OutputArray edges,
double threshold1, double threshold2,
int apertureSize= 3 , bool L2gradient= false ) ;
image
: 입력 영상
edges
: 엣지 영상
threshold1
: 하단 임계값
threshold2
: 상단 임계값, threshold1
:threshold2
=1:2 or 1:3 권장
apertureSize
: 소벨 연산을 위한 커널 크기
L2gradient
: L2 norm 사용 여부, false
일 시, L 1 n o r m L_{1} norm L 1 n o r m 사용
L 2 n o r m = ( ∂ I / ∂ x ) 2 + ( ∂ I / ∂ y ) 2 L_{2} norm=\sqrt{(\partial I/\partial x)^{2}+(\partial I/\partial y)^{2}} L 2 n o r m = ( ∂ I / ∂ x ) 2 + ( ∂ I / ∂ y ) 2
L 1 n o r m = ∣ ∂ I / ∂ x ∣ + ∣ ∂ I / ∂ y ∣ L_{1} norm=|\partial I/\partial x|+|\partial I/\partial y| L 1 n o r m = ∣ ∂ I / ∂ x ∣ + ∣ ∂ I / ∂ y ∣
\\
\\
References