Python/파이썬 OpenCV 공부

[파이썬 OpenCV] 영상의 미분과 소벨 필터, 샤를 필터 - cv2.Sobel, cv2.Scharr

AI 꿈나무 2020. 10. 8. 16:28
반응형

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

 

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

 

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

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

sunkyoo.github.io


1. 에지 검출과 미분

 에지 - edge

 에지는 영상에서 픽셀의 밝기 값이 급격하게 변하는 부분입니다.

 객체와 객체, 객체와 배경에 어떤 경계를 나타내는 용어입니다.

 경계부분에는 픽셀값이 크게 변경된다고 가정하고 에지를 구합니다.

 

 영상에 미분을 하는 이유는 에지를 검출하기 위함입니다.

 

 기본적인 에지 검출 방법

 에지 검출을 위해 픽셀값이 급격하게 변하는 부분을 찾아야합니다.

 미분은 변화율을 나타내는 척도입니다. 영상을 미분하여 에지를 검출할 수 있습니다.

 영상을 (x,y) 변수의 함수로 간주했을 때, 이 함수의 1차 미분 값이 크게 나타나는 부분을 검출합니다.

 

 검출한 미분값에 T 임계값을 설정해주는 것이 중요합니다.

 임계값보다 높으면 에지로 판단하는 기준이 됩니다.

 따라서 T값을 어떻게 설정하냐가 상당히 중요합니다. 

 

 1차 미분의 근사화

 미분은 전진 차분(Forward difference), 후진 차분(Backward difference), 중앙 차분(Centered difference) 세 가지 종류가 있습니다. 이 중 중앙 차분이 가장 정확하다고 알려져 있습니다. 영상에서 중앙차분을 이용할 때는 1/2를 안합니다.

 

 중앙차분을 마스크로 만들어 필터를 적용하면 영상의 미분 값을 구할 수 있습니다.

 x방향의 미분값과 y방향의 미분값을 정의.

 

2. 미분 마스크와 소벨 필터

 3X1 마스크는 노이즈에 취약한 단점을 극복하기 위해 평균 값을 이용하는 3X3 마스크가 제안되었습니다.

 하지만 평균값 필터보다는 가우시안 블러의 효과가 더 좋듯이 소벨필터는 3X3 마스크에 가중치를 적용합니다.

 

소벨필터

 

 소벨필터보다 3대 10대 3대 비율을 쓰는 샤를필터가 미분 효과는 더 좋다고 알려져 있지만 소벨필터의 1,2,1이 직관적으로 보이기 때문에 소벨필터를 주로 씁니다.

 

3. 소벨 필터를 이용한 미분 함수 - cv2.Sobel

OpenCV에서는 sobel 마스크를 이용하여 필터링을 적용해주는 cv2.Sobel 함수를 제공하고 있습니다.

cv2.Sobel(src, ddepth, dx, dy, dst=None, ksize=None, scale=None, delta=None, borderType=None) -> dst

• src: 입력 영상
• ddepth: 출력 영상 데이터 타입. -1이면 입력 영상과 같은 데이터 타입을 사용.
• dx: x 방향 미분 차수. 1차미분할지 2차미분 할지 결정
• dy: y 방향 미분 차수.
• dst: 출력 영상(행렬)
• ksize: 커널 크기. 기본값은 3.
• scale 연산 결과에 추가적으로 곱할 값. 기본값은 1.
• delta: 연산 결과에 추가적으로 더할 값. 기본값은 0.
• borderType: 가장자리 픽셀 확장 방식. 기본값은 cv2.BORDER_DEFAULT.

 

4. 샤를 필터를 이용한 미분 함수 - cv2.Scharr

cv2.Scharr(src, ddepth, dx, dy, dst=None, scale=None, delta=None, borderType=None) -> dst

• src: 입력 영상
• ddepth: 출력 영상 데이터 타입. -1이면 입력 영상과 같은 데이터 타입을 사용.
• dx: x 방향 미분 차수
• dy: y 방향 미분 차수.
• dst: 출력 영상(행렬)
• scale 연산 결과에 추가적으로 곱할 값. 기본값은 1
• delta: 연산 결과에 추가적으로 더할 값. 기본값은 0.
• borderType: 가장자리 픽셀 확장 방식. 기본값은 cv2.BORDER_DEFAULT

 

 소벨함수와 비슷합니다.

 

5. 소베 필터를 이용한 영상의 미분 예제

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

 

src = cv2.imread('lenna.bmp', cv2.IMREAD_GRAYSCALE)

if src is None:
    print('Image load failed!')
    sys.exit()

# dx와 dy를 합쳐서 출력해야합니다.
dx = cv2.Sobel(src, -1, 1, 0, delta=128) # delta 값을 지정해주지 않으면 미분이 - 부분은 0
dy = cv2.Sobel(src, -1, 0, 1, delta=128)

cv2.imshow('src', src)
cv2.imshow('dx', dx)
cv2.imshow('dy', dy)
cv2.waitKey()

cv2.destroyAllWindows()

 

x방향 미분

 

y방향 미분

 

 x방향 미분은 y방향 미분을 나타내지 못하고

 y방향 미분은 x방향 미분을 나타내지 못합니다.

 따라서 윤곽선 검출을 위해서는 두 미분을 합쳐서 이용해야 합니다.

 

반응형