Python/파이썬 OpenCV 공부

[파이썬 OpenCV] 영상의 그래디언트와 에지 검출하기 -cv2.magnitude, cv2.phase

AI 꿈나무 2020. 10. 8. 19:52
반응형

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

 

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

 

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

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

sunkyoo.github.io


 

 

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

황선규 박사님의 를 공부한 내용을 정리해 보았습니다. 예제 코드 출처 :  황선규 박사님 github홈페이지 『OpenCV 4로 배우는 컴퓨터 비전과 머신 러닝』 예제 소스 코드는 아래 링크를 참고하세요

deep-learning-study.tistory.com

 이전 포스팅에서 소벨 필터로 x방향, y방향 미분 값을 구했습니다.

 이번에는 그래디언트를 이용해서 윤곽선을 검출해보겠습니다.

 

영상의 그래디언트 - Gradient

 그래디언트는 함수 f(x,y)를 x축과 y축으로 각각 편미분(partial derivative)하여 벡터 형태로 표현한 것입니다.

 x방향 미분과 y방향 미분을 따로 계산하고 벡터라는 것으로 묶은 것이 그래디언트입니다.

 x방향 미분 성분과 y방향 미분 성분을 행렬 형태로 표현하여 한꺼번에 표현했습니다.

 그래디언트의 크기와 방향은 다음 식으로 구할 수 있습니다.

 

그래디언트 크기

 

그래디언트 방향

 

 

 실제 영상에서 그래디언트 크기는 픽셀 값의 차이, 변화량을 의미합니다.

 그래디언트 방향은 픽셀 값이 가장 급격하게 증가하는 방향을 나타냅니다.

 

2D 백터의 크기 계산 함수 - cv2.magnitude

소벨 필터로 구한 x방향, y방향 미분 값을 cv2.magnitude에 입력값으로 설정하면 백터의 크기를 계산할 수 있습니다. 

cv2.magnitude(x, y, magnitude=None) -> magnitude

• x: 2D 벡터의 x 좌표 행렬. 실수형.
• y: 2D 벡터의 y 좌표 행렬. x와 같은 크기. 실수형
• magnitude: 2D 벡터의 크기 행렬. x와 같은 크기, 같은 타입.

2D 백터의 방향 계산 함수 - cv2.phase

 그래디언트의 방향을 계산할 수 있습니다.

cv2.phase(x, y, angle=None, angleInDegrees=None) -> angle

• x: 2D 벡터의 x 좌표 행렬. 실수형.
• y: 2D 벡터의 y 좌표 행렬. x와 같은 크기. 실수형.
• angle: 2D 벡터의 크기 행렬. x와 같은 크기, 같은 타입.
• angleInDegrees: True이면 각도 단위, False이면 래디언 단위

소벨 피터를 이용한 에지 검출 예제

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

 

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

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

sunkyoo.github.io

 

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

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



dx = cv2.Sobel(src, cv2.CV_32F, 1, 0) # float 형태의 미분값을 저장
dy = cv2.Sobel(src, cv2.CV_32F, 0, 1)


mag = cv2.magnitude(dx, dy) # 그래디언트 크기
mag = np.clip(mag, 0, 255).astype(np.uint8) # 255보다 커질 수 있으므로 saturate 연산

# 흰색과 검은색으로만 나타내는 윤곽선 생성
dst = np.zeros(src.shape[:2], np.uint8) # 0(검은색)으로 채워져 있는 영상 생성
dst[mag > 120] = 255 # 120은 임계값, 값을 적절하게 설정하면 내가 원하는 부분만 나타낼 수 있음

# dst = cv2.threshold(mag, 120, 255, cv2.THRESH_BINARY) # cv2 함수로 임계값 설정하기

cv2.imshow('src', src)
cv2.imshow('mag', mag)
cv2.imshow('dst', dst)
cv2.waitKey()

cv2.destroyAllWindows()

 

 

그래디언트 크기

 

임계값을 적용한 영상

 

 그래디언트 크기를 구하고 임계값 설정으로 에지를 얻게 되면 선이 너무 두껍다는 단점이 있습니다.

 

반응형