[OpenCV] Unsharp 필터
이미지 처리에서 sharpening이라고 하는 즉 선명도를 증가시키는 방법이 몇 가지 있습니다. 가장 대표적인 방법으로 다음의 3가지를 뽑을 수 있고, 이 포스팅에선 unsharp filter를 사용하는 방법에 대해서 알아보겠다.
- Laplace operator
- Difference of Gaussians (DoG)
- Unsharp Filter
2020/10/18 - [OpenCV] - [OpenCV] Image Edge Enhancement: 라플라스 연산자 (Laplace Operator)-파이썬 코드 포함
2020/10/27 - [OpenCV] - [OpenCV] 이미지 경계선 강화: DoG - 파이썬 코드 포함
Theory
The unsharp filter is also used to enhance edges and other details on images. As one of spatial sharpening, the principle is pretty much similar to that of DoG, in a way that a smoothed image is subtracted from its original one, which produces a high-pass signal's edge image.
\begin{equation} g(x,y) = f(x,y) - f_{\mathrm{smoothed}}(x,y) \tag{1} \end{equation}
where $g(x,y)$ denotes the edge image. A better understanding can be made in a signal pattern as shown below.
The resultant sharpened image can then be obtained by adding the edge image to the original one:
$$ f_{\mathrm{sharpened}}(x,y) = f(x,y) + kg(x,y) \tag{2} $$
, where $k$ is a scaling constant, typically set from the range between 0.2 and 0.7. The sharpness of an image becomes enhanced as $k$ increases.
Python code
import os
import cv2
import numpy as np
import matplotlib.pyplot as plt
import imghdr
class UnsharpFilter:
def __init__(self,file):
# load a gif image
if imghdr.what(file) == 'gif':
gif = cv2.VideoCapture(file)
ret, self.originalImage = gif.read()
else:
self.originalImage = cv2.imread(file)
def UnsharpFiltering_by_OpenCV(self,weight):
self.src_gray = cv2.cvtColor(self.originalImage,cv2.COLOR_BGR2GRAY)
self.fsmoothed_cv = cv2.GaussianBlur(self.src_gray,(3,3),0)
self.g_cv = self.src_gray.astype(np.float32)-self.fsmoothed_cv.astype(np.float32)
self.fsharpend_cv = self.src_gray.astype(np.float32) + weight*self.g_cv.astype(np.float32)
def replicate_boundary(self,r_curr, c_curr,row,col):
r_temp = r_curr
c_temp = c_curr
if r_temp<0:
r_temp +=1
elif r_temp>=row:
r_temp -=1
if c_temp<0:
c_temp +=1
elif c_temp>=col:
c_temp -=1
return r_temp, c_temp
def get_GaussianBlurred(self,gkernel):
row, col = self.src_gray.shape
G = np.zeros((row,col))
for r in range(row):
for c in range(col):
for i in range(3):
for j in range(3):
r_temp, c_temp = self.replicate_boundary(r+i-1,c+j-1,row,col)
G[r,c] += self.src_gray[r_temp,c_temp]*gkernel[i,j]
return G
def UnsharpeFiltering_from_Scratches(self, weight):
xdir_gauss = cv2.getGaussianKernel(3, 1.)
gkernel1 = np.multiply(xdir_gauss.T, xdir_gauss)
self.fsmoothed_scratch = self.get_GaussianBlurred(gkernel1)
self.g_scratch = self.src_gray.astype(np.float32)-self.fsmoothed_scratch
self.fsharpened_scratch = self.src_gray.astype(np.float32) + weight*self.g_scratch
a. 원본 이미지 확인
path = os.getcwd()
file = ''.join(path+"/wdg1.gif")
UF = UnsharpFilter(file)
plt.imshow(UF.originalImage)
plt.title('Original Image',fontsize=15)
plt.xticks([]), plt.yticks([])
b. OpenCV로 Unsharped filter 적용
UF.UnsharpFiltering_by_OpenCV(0.3)
plt.figure(figsize=(17,6))
plt.subplot(131),plt.imshow(UF.fsharpend_cv, cmap='gray'),plt.title('Sharpened image',fontsize=15)
plt.xticks([]), plt.yticks([])
plt.subplot(132),plt.imshow(UF.g_cv,cmap='gray'),plt.title('UnsharpFiltered image',fontsize=15)
plt.xticks([]), plt.yticks([])
plt.subplot(133),plt.imshow(UF.fsmoothed_cv,cmap='gray'),plt.title('Smoothed image',fontsize=15)
plt.xticks([]), plt.yticks([])
c. from-scratch 코드로 적용
UF.UnsharpeFiltering_from_Scratches(0.7)
plt.figure(figsize=(17,6))
plt.subplot(131),plt.imshow(UF.fsharpened_scratch, cmap='gray'),plt.title('Sharpened image',fontsize=15)
plt.xticks([]), plt.yticks([])
plt.subplot(132),plt.imshow(UF.g_scratch,cmap='gray'),plt.title('UnsharpFiltered image',fontsize=15)
plt.xticks([]), plt.yticks([])
plt.subplot(133),plt.imshow(UF.fsmoothed_scratch,cmap='gray'),plt.title('Smoothed image',fontsize=15)
plt.xticks([]), plt.yticks([])
Wrapping it Up
We have studied three respresentative algorithms for edge enhancement: Laplace Operator, Difference of Gaussians, and Unsharp filter. Python implementations of these algorithms can be found in the links attached at the beginning of this post.
As a series of fundamental study of image processing algorithms, the following post will be covering image fusion and blending using image pyramid.
'Programming > Computer Vision' 카테고리의 다른 글
[OpenCV] K-Means를 이용한 Image Segmentation(이미지 분할) (0) | 2020.11.05 |
---|---|
[OpenCV] Image Edge Enhancement: 라플라스 연산자 (Laplace Operator)-파이썬 코드 포함 (0) | 2020.11.04 |
[OpenCV] 이미지 경계선 강화: DoG - 파이썬 코드 포함 (0) | 2020.11.04 |
[OpenCV] 이미지 노출 융합 (exposure fusion) 이란? (1) | 2020.11.01 |
[OpenCV] 이미지 blurring (smoothing) 처리 (0) | 2020.10.31 |
댓글