opencv - 15일차
Image Gradients and Edge Detection
image gradient 란
directional change in the intensity or color in an image.
이와 같이 opencv에서 image gradient를 잘 감지하기 위한 몇가지 방법을 공부하겠다.
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('messi5.jpg', cv2.IMREAD_GRAYSCALE)
lap = cv2.Laplacian(img, cv2.CV_64F, ksize =3)
lap = np.uint8(np.absolute(lap))
sobelX = cv2.Sobel(img, cv2.CV_64F, 1,0)
sobelY = cv2.Sobel(img, cv2.CV_64F, 0,1)
sobelX = np.uint8(np.absolute(sobelX))
sobelY = np.uint8(np.absolute(sobelY))
titles = ['image', 'Laplacian', 'sobelX', 'sobelY' ]
images = [img, lap, sobelX, sobelY]
for i in range(4):
plt.subplot(2,2,i+1), plt.imshow(images[i], 'gray')
plt.title(titles[i])
plt.xticks([]), plt.yticks([])
plt.show()
Laplacian operator
라플라시안의 수학적 정의는 다음과 같다
라플라스 연산자는 위의 기호가 말해주듯이 Divergence of Gradient 이다.
Gradient 연산자
는 벡터함수로 정의하는 벡터장 내의 한 점에서 벡터함수의 값이 가장 급격히 변하는 주변의 위치와 크기를 알려주고,
Divergence 연산자
는 단위 단면적으로부터 퍼져 나가는 정도를 알려주기 때문에 Divergence 가 0이라면 퍼져 나가는 정도와 유입되는 정도가 동일하므로 벡터의 흐름이 균일한 상태를 의미한다. 그러므로 라플라스 연산자는 벡터장 내의 벡터의 흐름이 균일하지 못한 정도를 나타낸다고 생각하면 된다. 영상처리 분야에서 외곽선(Edge)을 검출할 때 라플라스 필터를 사용하는 것을 보더라도 이러한 해석이 틀리지 않다는 것을 뒷받침해준다. 외곽선은 주변의 다른 영역에 비해서 확연히 다른 색상과 형태로 되어 있기 때문에 라플라스 연산자를 사용하여 그 값이 큰 곳을 찾으면 외곽선이 될 것이다
출처: https://micropilot.tistory.com/2970 []
이미지의 edge detection을 하기 위해서는 흑백 이미지가 필요하므로 메시 이미지를 불러와서 cv2.IMREAD_GRAYSCALE 형태로 변환해준다.
cv2.Laplacian 함수의 첫번째 인자는 이미지, 두번째 인자는 데이터타입, 즉 cv2.CV64F 인데 이는 64bit float 형으로 불러온다는 의미이다. 세번째 인자는 커널 사이즈인데 3,3 사이즈로 지정한다.
그런 후에 모든 값에 절대값을 취해서 uint8 형태로 변환해준다.
Sobel operator
Sobel 연산자란
The Sobel–Feldman operator is based on convolving the image with a small, separable, and integer-valued filter in the horizontal and vertical directions and is therefore relatively inexpensive in terms of computations. On the other hand, the gradient approximation that it produces is relatively crude, in particular for high-frequency variations in the image. 즉 이미지를 x, y 방향대로 분리할 수 있는 필터와 convolution 시키는 것이다.
sobelX = cv2.Sobel(img, cv2.CV_64F, 1,0)
sobelY = cv2.Sobel(img, cv2.CV_64F, 0,1)
여기서 cv2.Sobel 함수의 첫번째 인자는 이미지, 두번째 인자는 데이터타입, X 의 경우는 세번째가 1 Y의 경으는 네번째가 1이 된다. 왜냐하면 각각의 어느 방향으로 변화를 잘 나타내는지 지정해줘야 하므로.
TISTORY
나를 표현하는 블로그를 만들어보세요.
www.tistory.com
마찬가지로
위의 이미지를 보면 각 특징이 드러난다.
SobelX 마스크를 적용하면 x 방향을 따라 갔을 때 이미지에 급격한 변화가 잘 나타나고,
SobelY 마스크를 적용하면 y 방향을 따라 갔을 때 이미지에 급격한 변화가 잘 나타난다.
sudoku 이미지를 적용하면 이들의 차이를 더 잘 볼 수 있다.
sobel x y 마스크를 합칠 수도 있다. 그러면 각각 방향대로 edge를 모두 잘 탐지할 수 있다.