인공지능/컴퓨터 비전

OpenCV를 사용한 이미지 처리 - 블러링 (cv2.blur, cv2.GaussianBlur)

백관구 2022. 11. 21. 17:41
반응형

안녕하세요 :)

 

    지난 포스팅에서 OpenCV 패키지를 사용해 이미지 파일을 읽어 오는 방법과 이미지 처리 중 더하기(cv2.add, cv2.addWeighted)에 대해 알아봤습니다. 이번 포스팅에서는 이미지 처리 중 필터링 기법 중 하나인 블러링에 대해서 다뤄보겠습니다.

 

 

OpenCV를 사용한 이미지 처리

지난 포스팅은 프로젝트의 전반적인 주제인 이미지의 의미적 분할에 대해서 알아봤습니다. 이번 포스팅은 의미적 분할을 하기 위해 필요한 이미지를 어떻게 읽어오고, 그리고 적절하게 전처리

data-science-note.tistory.com

 


 

필터링

  • 이미지를 구성하고 있는 픽셀(pixel)들의 조합으로 이미지를 변형하는 방법
  • 이미지를 부드럽게(흐리게) 변형하는 블러링(blurring)과 선명하게(뚜렷하게) 변형하는 샤프닝(sharpening)이 대표적

 

블러링 (cv2.blur)

  • 평균 필터를 기반으로 이미지를 부드럽게(흐리게) 변형하는 기법
  • 필터 내 모든 픽셀에 동일한 가중치를 주어 단순 평균함
  • 잡음(noise) 제거의 전처리 용도로 주로 사용 됨

 

cv2.blur(src, ksize, borderType = 'BORDER_REFLECT_101')
- Parameters
    - src : 이미지 객체 행렬
    - ksize : 평균 필터 크기 (너비 방향 필터 크기, 높이 방향 필터 크기) → 홀수로 지정해야 함!
    - borderType : 이미지 가장자리를 처리하는 방식 (default : 'BORDER_REFLECT_101')
- Returns : 블러링 된 이미지 객체 행렬
- Return type : numpy.ndarray

 

※ borderType 종류

  • BORDER_CONSTANT : 주어진 특정 값(default : 0)으로 채움
  • BORDER_REPLICATE : 가장 가까운 픽셀 값을 가져 옴
  • BORDER_REFLECT : 이미지 가장자리를 포함한 대칭 방향의 인접한 픽셀 값을 가져 옴
  • BORDER_REFLECT_101 : 이미지 가장자리를 제외한 대칭 방향의 인접한 픽셀 값을 가져 옴

 

borderType 종류

 

    예시로 블러링의 결과를 살펴 보겠습니다. 필터(커널) 크기가 커질수록 이미지가 더 흐릿해지는 것을 확인할 수 있습니다.

# 블러링
blur9_img  = cv2.blur(base_img, (9, 9))
blur99_img = cv2.blur(base_img, (99, 99))

# 시각화
fig, subs = plt.subplots(ncols = 3, figsize = (20, 5))
for sub, img in zip(subs.flatten(), [base_img, blur9_img, blur99_img]): sub.imshow(img)
plt.show()

(왼쪽) 원본 이미지, (가운데) 필터 크기가 9인 블러링 이미지, (오른쪽) 필터 크기가 99인 블러링 이미지

 

반응형

 


 

가우시안 블러링 (cv2.GaussianBlur)

    앞에서 본 cv2.blur는 필터 내 모든 픽셀에 동일한 가중치를 주어 단순 평균을 한 블러링 기법입니다. 이 외에도 가우시안 필터를 적용하는 방안이 있습니다. 가우시안 필터는 필터 중앙에 큰 가중치를, 필터 가장자리로 갈수록 작은 가중치를 주기 때문에 원본 이미지의 형상을 좀 더 보존하면서 노이즈를 제거할 수 있다는 장점이 있습니다.

cv2.GaussianBlur(src, ksize, sigmaX, sigmaY, borderType = 'BORDER_REFLECT_101')
- Parameters
    - src : 이미지 객체 행렬
    - ksize : 필터 크기 (너비 방향 필터 크기, 높이 방향 필터 크기) → 홀수로 지정해야 함!
    - sigmaX, sigmaY : 가로축(X)과 세로축(Y)의 표준편차 (0을 입력하면 필터 크기에 의해 자동으로 결정 됨)
    - borderType : 이미지 가장자리를 처리하는 방식 (default : 'BORDER_REFLECT_101')
- Returns : 가우시안 블러링 된 이미지 객체 행렬
- Return type : numpy.ndarray

 

  • 가우시안 분포 (아래 그림 참고)
    • 평균($\mu$) : 필터 중앙의 가중치
    • 분산($/simga^2$) : 필터 가장자리 부근의 가중치
    • 분산이 작을수록 필터 중앙에 위치한 픽셀 값의 가중치가 커지고, 분산이 클수록 필터 가장자리 부근에 위치한 픽셀 값들이 가중치가 커짐

$$f(x|\mu,\sigma)=\frac{1}{\sqrt{2\pi}\sigma}exp\left(-\frac{\left(x-\mu\right)^2}{2\sigma^2}\right)$$

 

가우시안 분포

 

    예시로 블러링과 가우시안 블러링 효과의 차이를 확인해 보겠습니다. 동일한 필터 크기를 적용해도 가우시안 블러링 된 이미지가 단순 블러링을 적용했을 때보다 원본 이미지의 형상을 잘 유지하면서도 블러링의 효과는 가져오는 것을 볼 수 있습니다.

# 블러링
blur99_img = cv2.blur(base_img, (99, 99))
# 가우시안 블러링
gblur_img  = cv2.GaussianBlur(base_img, (99, 99), sigmaX = 0, sigmaY = 0)

# 시각화
fig, subs = plt.subplots(ncols = 3, figsize = (20, 5))
for sub, img in zip(subs.flatten(), [base_img, blur99_img, gblur_img]): sub.imshow(img)
plt.show()

(왼쪽) 원본 이미지, (가운데) 단순 블러링 이미지, (오른쪽) 가우시안 블러링 이미지

 


 

여기까지 블러링에 대해 살펴봤습니다. 다음은 필터링 기법 중 하나인 샤프닝에 대해 알아보도록 하겠습니다.

감사합니다 :>

반응형