본문 바로가기
AI-driven Methodology/CV (Computer Vision)

[Computer Vision] Image Filtering

by goatlab 2021. 12. 10.
728x90
반응형
SMALL

이미지 필터링 (Image Filtering)

 


이미지의 가장자리를 흐리게 하거나 선명하게 하거나 감지하는 등 다양한 용도로 사용할 수 있다. 여기에는 2D kernel 행렬로 이미지의 convolution을 수행하는 작업이 포함된다. convolution에는 입력 이미지 위로 kernel을 슬라이딩하고 요소별 곱셈을 수행한 다음 덧셈을 수행하는 작업이 포함된다.

 

이미지 필터링 (image filtering)은 필터 (filter) 또는 커널 (kernel) 또는 윈도우 (window)라고 하는 정방 행렬을 정의하고 이 커널을 이동시키면서 같은 이미지 영역과 곱하여 그 결과값을 이미지의 해당 위치의 값으로 하는 새로운 이미지를 만드는 연산이다. 기호 로 표기한다.

 

filter2D()


"filter2D()" 는 OpenCV에서 제공하는 함수로 사전 정의된 사용자 정의 kernel과 이미지의 convolution을 수행하는 데 도움된다. 이 기능에는 src , ddepth 및 kernel의 세 가지 매개변수가 필요하다.

 

filter2D(src, ddepth, kernel[, dst[, anchor[, delta[, borderType]]]])
◦ src는 입력 이미지

◦ ddepth는 출력 이미지의 깊이. 기본값을 -1로 유지하면 입력 및 출력 이미지의 깊이가 동일하게 유지

◦ kernel은 사용자 정의 컨볼루션 행렬

 

다음 코드는 평균을 구하는 커널 적용한 예다. 커널 크기가 커지면서 이미지가 점점 더 흐려지는 것을 볼 수 있다.

 

import cv2
from skimage.data import astronaut

img = astronaut()
img = cv2.resize(img, dsize=(150, 150))

plt.figure(figsize=(8, 3))
for i, k in enumerate([2, 6, 11]):
    kernel = np.ones((k, k)) / k**2
    filtering = cv2.filter2D(img, -1, kernel)
    plt.subplot(1, 3, i + 1)
    plt.imshow(filtering)
    plt.title("커널 사이즈 {}".format(k))
    plt.axis("off")

plt.show()

 

Blurring


smoothening이라고도 하는 이미지 blurring은 모든 이미지 처리 응용 프로그램에서 필수적인 단계이다. blurring 처리는 일반적으로 object edge 주변의 noise를 줄이는 데 도움이 되므로 edge detection를 처리할 때 전처리 단계이다. 주로 Median Blurring, Gaussian Blurring 및 Bilateral Filtering의 세 가지 유형의 흐림 기술이 사용된다.

 

  • 평균 블러
  • 중앙값 블러
  • 가우시안 블러
  • 양방향 블러

 

Simple Blurring


basic blurring은 단순히 이미지의 pixel 값을 평균화하는 것이다. 예를 들어, 1로 구성된 맞춤형 3*3 kernel을 구성하고 9로 나눌 수 있다. 이 kernel과 이미지의 convolution은 blurring effect를 유발한다.

OpenCV는 이미지를 흐리게 처리하는 ' blur() ' 라는 함수도 제공한다 . 이 함수에서 kernel 크기만 언급하면 자체적으로 kernel matrix를 생성하고 blur를 수행한다.

 

blur(src, ksize)
  • src : 원본 이미지
  • ksize : 커널 크기
blur = cv2.blur(img, (5, 5))
boxfilter = cv2.boxFilter(img, -1, (5, 5))

plt.subplot(1, 2, 1)
plt.imshow(img)
plt.title("원본 이미지")
plt.axis('off')
plt.subplot(1, 2, 2)
plt.imshow(blur)
plt.title("blur 함수 적용")
plt.axis('off')

plt.tight_layout()
plt.show()

 

Gaussian Blurring


이 blurring 기술은 Gaussian filter를 사용한다. 모든 값을 상수로 직접 평균하는 대신 가중 평균이 여기에서 발생한다. kernel 중심에서 이미지 pixel의 거리는 가중 평균과 관련된 해당 가중치를 결정한다. 중앙에 가까운 pixel은 멀리 있는 pixel에 비해 더 많은 가중치를 갖는다.

OpenCV는 기본적으로 src , ksize , sigmaX 및 sigmaY 의 네 가지 인수가 필요한 ' GaussianBlur() ' 함수를 제공한다. 가우시안 블러는 가우시안 함수 GG를 커널로 사용한다. 가우시안 커널은 중앙 위치 (x,y)(x,y)와 커널 위치 (x+u,y+v)의 거리 차이 (u,v)가 클수록 가중치가 작아진다.

 

◦ src는 입력 이미지

◦ ksize는 가우스 커널의 크기

◦ sigmaX는 수평 방향에서 가우스 커널의 표준 편차. 기본값은 0

◦ sigmaY는 수직 방향에서 가우스 커널의 표준 편차. 기본값은 0
gauss1d = cv2.getGaussianKernel(100, 15)
gauss2d = gauss1d @ gauss1d.T

plt.figure(figsize=(8, 4))

plt.subplot(121)
plt.plot(gauss1d)
plt.grid(False)
plt.title("1차원 가우스 커널")

plt.subplot(122)
plt.imshow(gauss2d, cmap=mpl.cm.bone_r)
plt.grid(False)
plt.title("2차원 가우스 커널")

plt.tight_layout()
plt.show()

 

Median Blurring

 

이러한 종류의 blurring에는 원본 이미지의 pixel 값을 blurring kernel로 덮인 영역에 있는 pixel의 중앙값으로 교체하는 작업이 포함된다. 사용된 함수는 ' medianBlur() '이다. 입력 이미지와 중앙값 filter의 kernel 크기만 인수로 필요하다.

 

medianBlur(src, ksize)
# 점 잡음 적용
img_noise = img.copy()

np.random.seed(0)
N = 500
idx1 = np.random.randint(img.shape[0], size=N)
idx2 = np.random.randint(img.shape[1], size=N)
img_noise[idx1, idx2] = 255

# 중앙값 블러로 잡음 제거
img_denoise = cv2.medianBlur(img_noise, 3)

plt.subplot(1, 2, 1)
plt.imshow(img_noise)
plt.title("점 잡음이 있는 이미지")
plt.axis('off')

plt.subplot(1, 2, 2)
plt.imshow(img_denoise)
plt.title("중앙값 블러를 적용한 이미지")
plt.axis('off')
plt.show()

 

Bilateral Filtering


날카로운 edge와 관련된 정보를 보존해야 하는 경우 전체 이미지를 blurring 하는 것은 좋은 선택이 아니다. 이 경우 양방향 filtering이 유용하다. 주변 pixel 값의 유사성을 기반으로 이미지를 선택적으로 흐리게 처리한다. 이 filter는 Gaussian filter의 속성을 포함한다. 즉, kernel 중심으로부터의 거리와 이미지 주변에 존재하는 pixel 강도를 기반으로 filtering한다. 따라서, 이미지의 edge 구조를 유지하는 데 도움이 된다.

OpenCV는 양방향 필터 기능을 제공한다. 기본적으로 4개의 인수 (src , d , sigmaColor , sigmaSpace)가 있다.

◦ src는 입력 이미지

◦ d는 filtering하는 동안 pixel 이웃에 대해 고려할 직경 값

◦ sigmaSpace는 kernel의 공간 분포를 결정 (Gaussian filter와 유사)

◦ sigmaColor는 허용될 수 있는 pixel 강도 간의 차이에 대한 임계값을 결정한다.
img_denoise1 = cv2.GaussianBlur(img_noise, (9, 9), 2)
img_denoise2 = cv2.bilateralFilter(img_noise, 9, 75, 75)

plt.subplot(1, 2, 1)
plt.imshow(img_denoise1)
plt.title("가우시안 필터링을 적용한 이미지")
plt.axis('off')

plt.subplot(1, 2, 2)
plt.imshow(img_denoise2)
plt.title("양방향 필터링을 적용한 이미지")
plt.axis('off')

plt.show()
728x90
반응형
LIST