본문 바로가기
Developer/OpenCV

OpenCV - 라플라스 필터를 활용한 Edge 검출 및 Blur 영역 탐색

by Doony 2021. 4. 2.

이번 포스팅에서는, 빗방울이나 blur 처리되어 흐릿하게 표현된 부분들의 비율을 계산하는 방법에 대해 포스팅해보겠습니다.
아래와 같이 특정 이미지들에서 일부가 오염되었을 경우, 오염된 부분들을 찾는 방법입니다.


흐릿하게 표현된, blur처리된 부분의 특징

blur 처리를 하기 위해 컨볼루트 필터를 쓰다보면, 값들의 평균 등을 이용해서 픽셀 간 차이를 낮추는 과정을 거치는데요. 반대로 생각해보면, 흐릿하게 표현된 부분을 찾을 때는 픽셀 간 차이가 낮은 구간을 탐색하면 됩니다.

픽셀 간 차이가 낮은 구간?

바로 생각나는 것은 Variance, 즉 분산입니다. 박스필터를 convolute 시키면서, 해당 구간의 픽셀 값 간의 분산을 구할 수 있다면, 커널 영역 별로 blur 처리된 부분을 탐색할 수 있다고 판단했습니다.


분산은 제곱의 평균에서 평균의 제곱을 빼면 구할 수 있는데요. openCV에서 제곱의 평균 값을 구해주는 필터가 있습니다.
상세 내용은 여기 에서 확인할 수 있습니다.


작동 순서

작동 순서는 다음과 같습니다.

  1. 그레이스케일로 변환
  2. 라플라시안 필터 적용으로 엣지 검출
  3. boxFilter 활용, 검출된 엣지에서 각 영역의 분산 계산하여, 특정 기준치 이상이면 흐릿한 부분이라고 판단

상세 코드

라플라시안 필터는 2차 미분을 통해, 픽셀값 간의 기울기와 방향성을 구함으로써 엣지를 탐색하는 방법입니다.
아래 코드 중 사실 분산 식과 다소 맞지 않는 부분들이 있는데... 어차피 스케일링 역할만 하는 부분이라, 결과적으로는 threshold만 조절하면 되는 것 같아서 단순하게 표현했습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import cv2
import numpy as np
 
# 이미지 불러오기
src = cv2.imread("./raindrop.jpg", cv2.IMREAD_COLOR)
 
# 그레이스케일로 변환
gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
 
# 라플라시안 필터 적용
laplacian = cv2.Laplacian(gray, cv2.CV_8U, ksize=5)
 
# 라플라시안 필터 적용된 이미지에서, 각 값들의 제곱을 구함
dst = cv2.sqrBoxFilter(laplacian, ddepth=-1, ksize=(5,5), normalize=True)
 
# 분산을 구함 = 제곱의 평균 - 평균의 제곱
= (dst - (laplacian*laplacian))
 
# blurred 처리되었다고 판단할 기준값 설정
 
threshold = 350
z[z<threshold] = 0
z[z>=threshold] = 1
 
# counting 0 and 1 (0 is blurred, 1 is ok
blurred = z[z==0].shape[0]
normal = z[z==1].shape[0]
 
# blurred 처리된 영역의 비율 계산
confidence = normal / (blurred+normal)
 
print("confidence: " + str(confidence))
 
 
cv2.imshow("original", src)
cv2.imshow("laplacian", laplacian)
cv2.imshow("variance", z)
cv2.waitKey()
cv2.destroyAllWindows()
cs

결과는 다음과 같습니다. 순서대로 원본 이미지, 라플라스 필터 적용 이미지, blur 영역 찾은 이미지입니다.

댓글