[OpenCV] 영상 Filtering

최재혁·2022년 11월 1일
0

opencv-python

목록 보기
10/10

9. 영상 Filtering

공간 영역 filtering

공간 영역 필터링은 연산 대상 픽셀과 그 주변 픽셀들을 활용하여 새로운 픽셀 값을 얻는 방법
이때 주변 픽셀을 어느 범위까지 활용할지 그리고 연산은 어떻게 할지를 결정해야 한다. 이런 역할을 하는 것이 바로 커널(kernel)이며 윈도(window), 필터(filter), 마스크(mask)라고도 부른다. 아래 그림에서 가운데 있는 3 x 3 짜리 행렬이 바로 커널이다.

컨볼루션 연산은 공간 영역 필터링을 위한 핵심 연산 방법입니다. 아래와 같은 방식으로 kernel을 source 이미지에 연산을 하게되고, 한 픽셀 씩 kernel을 이동하여 연산하는 방식이다.

출처 : https://www.slipp.net/wiki/pages/viewpage.action?pageId=26641520

공간 영역 필터링을 통해 아래와 같은 영상처리 결과물을 얻을 수 있다.

영상 bluring, smoothing

영상 noise 제거

예제 코드

import cv2
from ipykernel import kernel_protocol_version
import numpy as np

lena_img = "D:/dev/wego-project/erp_udp/opencv-examples/img/lena512.bmp"
medical_img = "D:/dev/wego-project/erp_udp/opencv-examples/img/medical.jpeg"

# 영상 불러오기
lena_color = cv2.imread(lena_img,1)
medical_color = cv2.imread(medical_img,1)
gray = cv2.cvtColor(lena_color,cv2.COLOR_BGR2GRAY)

### filter 2d
# 필터 마스크 생성
kernel = np.ones((5,5),np.float32) /25
f2d = cv2.filter2D(lena_color,-1,kernel) # -1은 입력 영상과 동일한 데이터의 출력 영상 생성

### gaussian filtering 
gau_lena = cv2.GaussianBlur(lena_color,(5,5),0)
gau_comp = cv2.hconcat([lena_color,cv2.hconcat([f2d,gau_lena])])
cv2.imshow("compare gaussian filtering result",gau_comp)

### medain filtering
median_medical = cv2.medianBlur(medical_color,5)
gau_medical = cv2.GaussianBlur(medical_color,(5,5),0)
median_comp = cv2.hconcat([medical_color,cv2.hconcat([gau_medical,median_medical])])
cv2.imshow("compare medain filtering result", median_comp)

### bilateral filtering
bilateral_lena = cv2.bilateralFilter(lena_color,15,40,100)
gau_lena = cv2.GaussianBlur(lena_color,(5,5),0)
bilateral_comp = cv2.hconcat([lena_color,cv2.hconcat([gau_lena,bilateral_lena])])
cv2.imshow("compare bilateral filter result",bilateral_comp)

cv2.waitKey()
cv2.destroyAllWindows()

Average Filtering

💡 영상을 부드럽게 만들어주는 대표적인 필터. 영상 내의 가장자리가 무뎌지는 효과를 갖는다.주변 픽셀들의 평균값을 적용하면 픽셀 간 차이가 적어져 선명도가 떨어져 전체적으로 흐릿해진다.

아래는 평균 값 필터 마스크 3x3 , 5x5 를 나타낸 그림이다.
아래의 kernel을 cv2.filter2d의 인자로 넣어 filtering을 진행한다.

  • 커널 크기 별 결과 영상

    원본 영상

    3x3 kernel 적용 결과 영상

    5x5 kernel 적용 결과 영상

    커널의 크기가 커질 수록 더 많은 픽셀에 대하여 평균을 구하여 블러링이 강해짐을 보인다.

Gaussian Filtering

💡 평균값 필터 블러링의 단점은 필터링 대상 위치에서 가까이 있는 픽셀과 멀리 있는 픽셀이 모두 같은 가중치를 사용하여 평균을 계산합니다. 멀리 있는 픽셀의 영향을 많이 받아 필터 결과의 퀄리티가 낮아지게 됩니다. 이를 보안하기위해 가우시안 필터링을 사용한다.

아래와 같은 가우시안 분포를 사용하여 가까운 픽셀에는 큰 가중치를 멀리 있는 픽셀에는 작은 가중치를 부여하여 필터링을 진행한다.

cv2.GaussianBlur(src, ksize, sigmaX, dst=None, sigmaY=None, borderType=None)

  • src: 입력 영상. 각 채널 별로 처리됨.

  • dst: 출력 영상. src와 같은 크기, 같은 타입.

  • ksize: 가우시안 커널 크기. (0, 0)을 지정하면 sigma 값에 의해 자동으로 결정됨
    (ksize =8*sigma+1)

  • sigmaX: x방향 sigma.

  • sigmaY: y방향 sigma. 0이면 sigmaX와 같게 설정.

  • borderType: 가장자리 픽셀 확장 방식.

  • sigma 별 가우시안 필터 적용 결과

    sigma = 1

    sigma = 2

    sigma = 3

    시그마가 커질 수록 블러링의 강도가 세짐을 확인 할 수 있다.

Median Filtering

💡 아래와 같이 흑점과 흰점이 무작위로 나타나는 노이즈를 salt and pepper noise라고 한다. 이러한 노이즈를 제거하기 위해 픽셀의 중앙값을 사용하는 Median filter를 사용한다.

kernel을 사용하여 이미지와 컨볼루션 연산을 진행한 위의 filtering과는 다르게 아래의 그림처럼 주변 픽셀들의 값들을 정렬하여 그 중앙값(median)으로 픽셀 값을 대체한다.

  • noise영상 filtering 결과 왼쪽 원본, 가운데 gaussian filter 적용, 오른쪽 median filter 적용 결과 gaussian filter는 약간의 노이즈 제거 효과를 보이지만 median filter를 사용하면 효과적으로 노이즈 제거가 가능함을 볼 수 있다.

Bilateral Filtering

💡 가우시안 filtering을 하게 되면 영상의 엣지가 손상되는 단점이 있다. 이를 해결하기 위해 기준 픽셀과 이웃 픽셀과의 거리, 그리고 픽셀 값의 차이를 함께 고려하여 블러링 정도를 조절하는 방식을 사용하여 필터링을 진행하는 방식을 사용한다.

아래의 그림과 같이 하늘 부분은 엣지가 없으므로 가우시안 필터링을 그대로 진행하고 나머지 부분을 보게 되면 엣지 부분이면 가우시안 필터의 일부분만을 가져와 필터링을 진행하여 엣지를 보존하게 된다.

cv2.bilateralFilter(src, d, sigmaColor, sigmaSpace, dst=None, borderType=None)

  • src: 입력 영상. 8비트 또는 실수형, 1채널 또는 3채널.
  • d: 필터링에 사용될 이웃 픽셀의 거리(지름), 음수(-1)를 입력하면 sigmaSpace 값에 의해 자동 결정(권장)
  • sigmaColor: 색 공간에서 필터의 표준 편차
  • sigmaSpace: 좌표 공간에서 필터의 표준 편차
  • dst: 출력 영상. src와 같은 크기, 같은 타입.
  • borderType: 가장자리 픽셀 처리 방식

  • bilateral filter 적용 결과 비교 영상

    원본 영상

    왼쪽 : gaussian filtering 영상, 오른쪽 : bilateral filter 영상

    bilateral filter를 사용한 영상의 엣지가 보존됨을 볼 수있다.

profile
Autonomous driving vision

0개의 댓글