파이썬 python/opencv

cv2 Trackbar를 이용해서 샤프닝 필터 구현하기(unsharpening)

Aytekin 2023. 5. 4. 21:05
728x90

아래 스크린샷과 코드 일부분은 황선규 박사님의 fastcampus opencv강의를 참조하여 unsharpening 필터링을 구현한 것입니다.


1. 샤프닝 필터란?

간단하게 이야기해서 이미지를 말 그대로 날카롭게 만들어주는 필터이다.

다시 말해 색이 변하는 부분을 더 두드러지게 하여 부드러운 이미지를 더 선명하게 보이게끔 만들어주는 작업이다.

 

2. 언샤프 마스크(Unsharp mask)필터링 원리

아래 4개의 그래프를 보면서 이해해보면 될 것 같다.

  1. 원래 이미지 값에 blur처리를 해준다. 변곡점(각도가 변하는 부분)이 이미지에서 경계값을 나타낸다고 이해한다면 2번째 그래프와 같이 부드러운 그래프가 그려진다.
  2. 원래 이미지 값에서 blur처리한 이미지 값을 뺀다.
  3. 3번 그래프 식을 정리

이런 계산과정을 거치면 이미지의 변곡점부분에서의 값의 변화가 더 두드러지게 되어 이미지가 더 선명해지는 효과를 볼 수 있다.

 

3. 언샤프 마스크 필터 공식 정리

2번 케이스가 알파(a)값이 1인 경우라고 보면 된다. 

알파(a)값이 1이 아니라 0.5, 1.5 등등 소수점으로 설정하게 되면 더 미세하고 정교한 샤프닝 필터를 적용할 수 있다.

 

4. alpha값, sigma값과 이미지의 샤프닝 정도와의 관계

  • sigma - 가우시안 블러에서의 시그마 값, 커질수록 블러되는 정도가 커지고 이미지결과는 더 선명해진다.
  • alpha - 언샤프닝 필터링 공식에서의 알파 값, 커질수록 이미지가 더 선명해진다.

첫번째로 시그마값이 커지면 이미지가 더 흐려지고 블러처리 되는 효과가 있다. 그러나 시그마값이 커지면 최종 이미지 결과는 더 선명해진다.

왜 그럴까?

위의 그래프에서 보면 시그마값이 커지면 이미지가 더 많이 흐려지게 되고 따라서 변곡점의 변화 정도가 더 커지게 된다. 따라서 이미지가 더 선명해지는 결과가 된다.

 

둘째로 알파값이 커지면 이미지가 더 선명해진다. 이것도 위의 식을 통해서 이해할 수 있다. 

 

즉, 이미지가 선명해지는 정도는 sigma값과 alpha값에 비례한다는 것을 알 수 있다.

 

5. Trackbar를 이용해서 이미지 선명도를 조절하는 기능 구현하기.

 opencv는 Trackbar라는 매서드를 제공해주는데 이 매서드에 대한 사용법은 다른 블로그에도 많이 있으니 여기서는 설명을 생략한다.

단, 알아보니 opencv의 Trackbar는 소수점까지 설정해주는 기능은 없으므로 여기서 약간의 잔머리가 필요했다.

 

sigma와 alpha 값에 각각 0.5씩 곱하여 선명도를 소수점으로 조절할 수 있도록 구현해보았다. 좀 더 세밀하게 조절하고 싶으면 0.5가 아니라 0.3, 0.2 등등으로 설정하면 될 것이다.

 

결과 이미지

원본이미지

예상대로 알파값과 시그마값이 커지면 이미지가 더 선명해지는 것을 확인할 수 있었다.

 

 


코드전문

import sys
import numpy as np
import cv2

# 슬라이드 바를 이용해서 alpha값을 조정하도록 하고 그 결과로 sharpening 정도를 조절하도록 구현해보기.

src = cv2.imread('rose.bmp', cv2.IMREAD_GRAYSCALE)

if src is None:
    print('Image load failed!')
    sys.exit()

cv2.namedWindow("TrackBar Windows")
cv2.createTrackbar("alpha","TrackBar Windows",0,10, lambda x: x)
cv2.createTrackbar("sigma","TrackBar Windows",0,5, lambda x: x)
cv2.setTrackbarPos("alpha","TrackBar Windows",0)
cv2.setTrackbarPos("sigma","TrackBar Windows",1)
cv2.setTrackbarMin("sigma","TrackBar Windows",1)

while cv2.waitKey(1) != ord('q'):
    alpha = cv2.getTrackbarPos('alpha','TrackBar Windows') * 0.5
    sigma = cv2.getTrackbarPos('sigma','TrackBar Windows') * 0.5

    blr = cv2.GaussianBlur(src, (0,0), sigma)
    dst = np.clip((1+alpha)*src - (alpha * blr), 0, 255).astype(np.uint8) # 2.*src - blr 이 수식이 sharpening해주는 부분
    cv2.imshow('src',src)
    cv2.putText(dst,'alpha : {}, sigma : {}'.format(alpha, sigma),(10,25),cv2.FONT_HERSHEY_SIMPLEX,1, 255, 2, cv2.LINE_AA)
    cv2.imshow("TrackBar Windows", dst)

cv2.destroyAllWindows()
728x90