0. 필터 처리

영상 처리에서는 필요한 값만 얻기 위한 필터가 사용된다. 필터를 활용하면 영상을 흐릿하게 하거나 선명하게 해서 edge(경계)를 검출하는 등 객체 인식도 할 수 있다. 영상 처리는 기존에 있던 pixel 값에 연산을 적용해서 새로운 pixel을 얻는 작업이다. 이 때, 연산을 수행할 pixel과 그 주변의 pixel을 활용하는 방법을 공간 영역 필터라고 한다. 공간 영역 필터에서 주변 pixel의 범위와 결과 산출을 위해 kernel이라는 n x n 행렬을 사용한다. 커널 행렬 값과 그에 대응하는 pixel 값을 곱해서 모두 합한 값이 결과 pixel값으로 출력되고, 이것을 처음부터 끝까지 반복한 것을 Convolution이라 한다. 커널의 값에 따라 블러링, 에지 탐지 등을 수행한다.

블러링 기법이란 영상에 초점이 맞지 않는 것처럼 흐릿하게 보이도록 하는 것을 의미한다. 이웃한 픽셀의 평균으로 설정되며 영상을 부드럽게 하는 효과를 낼 수 있다.

 

1. 평균 블러링

블러링을 적용하는 가장 간편한 방법은 이웃한 픽셀의 평균으로 설정되도록 하는 평균 블러링이다. 3 x 3 평균 블러링 커널은 다음과 같다. 


모든 블러링 커널 행렬의 전체 원소 합은 1이 되도록 만들어지기 때문에, 총 원소 합인 9로 나누어 정규화가 적용된다.

 

import cv2
import numpy as np

img = cv2.imread('image.jpg')

kernel_3 = np.ones((3,3), np.float32) / 9
kernel_5 = np.ones((5,5), np.float32) / 25

kernel_3_output = cv2.filter2D(img, -1, kernel_3)
kernel_5_output = cv2.filter2D(img, -1, kernel_5)

cv2.imshow('Img', img) # 기본 이미지
cv2.imshow('Kernel_3', kernel_3_output) # 3*3 블러링 이미지
cv2.imshow('kernel_5', kernel_5_output) # 5*5 블러링 이미지

cv2.waitKey()
cv2.destroyAllWindows()

img / kernel_3 / kernel_5 순

cv2.filter2D()는 Convolution 연산을 하는 함수로 (이미지, 출력 영상 dtype, 커널 행렬,[결과 영상, 커널 기준점, 필터 적용된 결과의 추가 값, 경계 pixel 보정 방법])이 인자로 구성되며, 출력 영상 dtype을 -1로 설정하면 입력 영상과 동일한 dtype으로 적용된다. 블러링 수치가 커질수록 희미하게 출력되는데, kerner_3_output보다 kerenel_5_output이 희미하게 출력됨을 확인할 수 있다. 평균 블러를 위해 blur라는 함수로 Kernel의 크기만 지정하면 자동으로 평균 Kernel이 생성되어 블러링을 적용할 수도 있으며, 3x3 행렬이라면 output = cv2.blur(img, (3, 3))으로 나타낼 수 있다.

 

2. 가우시안 블러링

가우시안 분포를 갖는 커널로 블러링을 적용한 것을 가우시안 블러링이라 한다. 가우시안 분포 함수가 종 형태를 이루는 것처럼, 커널의 가운데 값이 가장 크고 중앙에서 멀어질수록 값이 작아지게 된다. 3 x 3 가우시안 커널은 다음과 같다.

 

import cv2
import numpy as np

img = cv2.imread('image.jpg')

# 가우시안 커널 직접 생성
kernel1 = (1/16) * np.array([[1, 2, 1], [2, 4, 2], [1, 2, 1]])
blur1 = cv2.filter2D(img, -1, kernel1)

# cv2.getGaussianKernel()을 통해 가우시안 커널 생성
kernel2 = cv2.getGaussianKernel(3,0)
blur2 = cv2.filter2D(img, -1, kernel2*kernel2.T)

# cv2.GaussianBlur()를 통해 커널 생성부터 블러링까지 한 번에 처리
blur3 = cv2.GaussianBlur(img, (3,3), 0)

cv2.imshow('Image', img)
cv2.imshow('kernel1', blur1)
#blur2, blur3의 출력은 blur1 출력과 동일
# cv2.imshow('kernel2', blur2)
# cv2.imshow('kernel3', blur3)

cv2.waitKey()
cv2.destroyAllWindows()

Gaussian 3x3 출력

가우시안 블러링을 적용하는 cv2.GaussianBlur()는  (입력 영상, 커널 크기, x 방향 표준편차, [Y방향 표준편차, 경계 보정 방법])의 인자로 구성되며, 가우시안 커널을 생성하는 cv2.getGaussianKernel()은 (커널 크기, 표준편차)로 구성된다. cv2.getGaussianKernel()의 return 값은 1차원 배열이므로, cv2.filter2D() 함수에 적용하기 위해서는 커널과 커널의 전치 행렬을 곱한 값을 인자로 사용해야 한다.

 

3. 모션 블러

이미지가 특정 방향으로 움직이는 것 처럼 보이기 위한 모션 블러 효과를 적용할 수 있다. 모션 블러는 수평으로 처리할 때 3 x 3 커널은 다음과 같다.

 

import cv2
import numpy as np

img = cv2.imread('image.jpg')
row, col = img.shape[:2]

# motion blur
size = 25
motion = np.zeros((size,size))
motion[int((size-1)/2), :] = np.ones(size)
motion = motion / size

motion_output = cv2.filter2D(img, -1, motion)
cv2.imshow('motion', motion_output)

cv2.waitKey()
cv2.destroyAllWindows()

728x90
반응형
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 라이프코리아트위터 공유하기
  • shared
  • 카카오스토리 공유하기