본문 바로가기
Programming/Computer Vision

[OpenCV] 이미지 경계선 강화: Unsharp 필터 - 파이썬 코드 포함

by a voyager 2020. 11. 4.
728x90
반응형

[OpenCV] Unsharp 필터 

이미지 처리에서 sharpening이라고 하는 즉 선명도를 증가시키는 방법이 몇 가지 있습니다. 가장 대표적인  방법으로 다음의 3가지를 뽑을 수 있고, 이 포스팅에선 unsharp filter를 사용하는 방법에 대해서 알아보겠다.

 

  1. Laplace operator 
  2. Difference of Gaussians (DoG)
  3. 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.

 

unsharped 필터 적용 원리

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.

 

728x90
반응형

댓글