2 minute read

-


image filtering

  • filter2D(src, ddepth, kernel[, dst[, anchor[, delta[, borderType]]]])

    • src: 입력 이미지
    • ddepth: 이미지 깊이(자료형), -1일 경우 입력과 동일
    • kernel: 커널 행렬
  • 평균필터(mask) 생성

    kernel = np.ones((3,3),np.float32)/9

  • borderType=cv2.BORDER_CONSTANT

    padding 을 어떻게 결정할 것인지 : zero padding

적용해보기

import cv2
import numpy as np
import matplotlib.pyplot as plt

def my_first_filtering(src):
    kernel = np.ones((3,3),np.float32)/9    #평균필터

    return cv2.filter2D(src, -1,kernel, borderType=cv2.BORDER_CONSTANT)

src = np.array([[0,0,0,0,0],
                [15,16,0,0,0],
                [5,6,7,8,9],
                [0,1,2,3,4]], dtype=np.uint8)
dst = my_first_filtering(src)

print("Input:\n {}".format(src))
print("Output:\n {}".format(dst))

zero & repetition padding

  • zero padding

    주변 값을 0을 채움

  • repetition padding

    주변 값을 가장자리의 값을 복사하여 채움

    #up
    pad_img[:p_h,p_w:p_w+w] = src[0,:]
    #down
    pad_img[p_h+h:,p_w:p_w+w] = src[h-1,:]
    
    #left
    pad_img[:,:p_w] = pad_img[:,p_w+w-1:p_w+w]
    #right
    pad_img[:,p_w+w:] = pad_img[:,p_w+w-1:p_w+w]
    

    위와 같이 값을 복사하여 채워준다.

예시

import cv2
import numpy as np
import matplotlib.pyplot as plt

def my_padding(src,pad_shape, pad_type = 'zero' ):
    (h,w) = src.shape
    (p_h,p_w) = pad_shape
    pad_img = np.zeros((h+2*p_h,w+2*p_w))
    pad_img[p_h:h+p_h, p_w:w+p_w] = src

    if pad_type == 'repetition':
        print('repetition padding')
        #up
        pad_img[:p_h,p_w:p_w+w] = src[0,:]
        #down
        pad_img[p_h+h:,p_w:p_w+w] = src[h-1,:]

        #left
        pad_img[:,:p_w] = pad_img[:,p_w+w-1:p_w+w]
        #right
        pad_img[:,p_w+w:] = pad_img[:,p_w+w-1:p_w+w]
    else :
        #else is zero padding
        print('zero padding')
    return pad_img
if __name__=='__main__':
    src = cv2.imread('Lena.png',cv2.IMREAD_GRAYSCALE)

    #zero padding
    my_pad_img = my_padding(src,(20,20))

    #repetition padding
    # my_pad_img = my_padding(src,(20,20),'repetition')

    #데이터 타입 unit8로 변경
    my_pad_img = (my_pad_img+0.5).astype(np.uint8)
    cv2.imshow('original', src)
    cv2.imshow('my_pad_img', my_pad_img)
    cv2.waitKey()
    cv2.destroyAllWindows()


필터링을 하는 함수를 구현

import cv2
import numpy as np
import matplotlib.pyplot as plt
def my_padding(src,pad_shape, pad_type = 'zero' ):
    (h,w) = src.shape
    (p_h,p_w) = pad_shape
    pad_img = np.zeros((h+2*p_h,w+2*p_w))
    pad_img[p_h:h+p_h, p_w:w+p_w] = src

    if pad_type == 'repetition':
        print('repetition padding')
        #up
        pad_img[:p_h,p_w:p_w+w] = src[0,:]
        #down
        pad_img[p_h+h:,p_w:p_w+w] = src[h-1,:]

        #left
        pad_img[:,:p_w] = pad_img[:,p_w+w-1:p_w+w]
        #right
        pad_img[:,p_w+w:] = pad_img[:,p_w+w-1:p_w+w]
    else :
        #else is zero padding
        print('zero padding')
    return pad_img
def my_filtering(src,kernel):
    (h,w) = src.shape
    (k_h,k_w) = kernel.shape
    pad_img = my_padding(src,kernel)
    dst = np.zeros((h,w))   #output

    for m in range(h):
        for n in range(w):
            sum  =0
            for k in range(k_h):
                for l in range(k_w):
                    sum += kernel[k,l]*pad_img[m+k,n+l]
            dst[m,n] = sum
    dst = (dst+0.5).astype(np.uint8)
    return dst

    return pad_img
if __name__=='__main__':
    src = np.array([[0, 0, 0, 0, 0],
                    [15, 16, 0, 0, 0],
                    [5, 6, 7, 8, 9],
                    [0, 1, 2, 3, 4]], dtype=np.uint8)
    kernel = np.ones((3,3),np.float32)/9
    dst = my_filtering(src,kernel)

    print("Input:\n {}".format(src))
    print("Output:\n {}".format(dst))

과제

Separability of the Gaussian – 1D Gaussian filter vs. 2D Gaussian filter

  • 1D Gaussian과 2D Gaussian을 코드로 작성하고 실행 속도 비교

    – Gaussian filter를 만드는 코드를 작성하기

  • Gaussian filter의 크기와 sigma값을 변경해보고 결과 확인하기

  • 필요 함수

​ – np.mgrid: 격자 그리드(meshgrid)를 생성하는 함수

​ – np.sqrt: 로그 함수

– np.exp: 지수 함수 – np.full

  • 2D Gaussian

image

Tags:

Categories:

Updated: