When will you grow up?

python으로 시작하는 OpenCV (3) 본문

02. Study/Computer Vision(openframworks&opencv)

python으로 시작하는 OpenCV (3)

미카이 2020. 2. 6. 00:41

저번에 이에서 필터를 계속해서 알아보자.

 

sobel fileter

sobel filter는 3*3 이미지 필터를 사용하여 중심을 기준으로 각 방향의 앞뒤의 값을 비교해 변화량을 검출하는 알고리즘인데, 이미지 경사도의 계산방법이다.

 

예제를 통해 한번 알아보자.

import cv2

import numpy as np

import matplotlib.pyplot as plt

 

origin_img = cv2.imread('image.jpg'0# gray scale

 

# Sobel filter

dx = cv2.Sobel(origin_img, cv2.CV_32F, 10)

dy = cv2.Sobel(origin_img, cv2.CV_32F, 01)

 

#visualization

plt.figure(figsize=(8,3))

plt.subplot(131)

plt.axis('off')

plt.title('origin_img')

plt.imshow(origin_img, cmap='gray')

plt.subplot(132)

plt.axis('off')

plt.imshow(dx, cmap='gray')

plt.title(r'$\frac{dI}{dx}$')

plt.subplot(133)

plt.axis('off')

plt.title(r'$\frac{dI}{dy}$')

plt.imshow(dy, cmap='gray')

plt.tight_layout()

plt.show()

 

Colored by Color Scripter


cs

위 코드의 결과를 보면 아래와 같은 결과가 나온다.

sobel filter result

  dx            dy

-1 0 1     -1 -2 -1

-2 0 2      0  0  0

-1 0 1      1  2  1

내용의 잠깐하게 살펴보면, cv2.Sobel 함수는 지정된 크기의 선형 필터를 사용해 이미지 경사도의 근삿값을 계산하는데, 사용될 필터와, 이미지의 데이터 타입이 계산돼야 할 미분 값을 지정할 수 있고, 행렬의 곱형태가 아닌 각 위치의 값들끼리 곱하고 모두 더한 값입니다.

 

 

 

Gabor filter

가버 필터는 코사인파로 변화된 2D 가우시안 커널을 갖는 선형 필터인데, 외곽선을 검출하는 기능을 가지고 있고, 쉽게 생각하면 사인,코사인 함수로 모듈화된 가우시안 필터라고 생각할 수 있다. (여기서는 필터, 커널 같은 용어로 사용할 것이다.)

 

예제를 한번 알아보자.

import cv2

import numpy as np

import matplotlib.pyplot as plt

import math

 

origin_img = cv2.imread('image.jpg'0).astype(np.float32) # gray scale

origin_img = origin_img / 255

 

# Garbor filter form

kernel = cv2.getGaborKernel((21,21), 511010, cv2.CV_32F)

kernel /= math.sqrt((kernel * kernel).sum())

 

filtered = cv2.filter2D(origin_img, -1, kernel)

 

plt.figure(figsize=(8,3))

plt.subplot(131)

plt.axis('off')

plt.title('origin_img')

plt.imshow(origin_img, cmap='gray')

plt.subplot(132)

plt.axis('off')

plt.imshow(kernel, cmap='gray')

plt.title('kernel')

plt.subplot(133)

plt.axis('off')

plt.title('filtered')

plt.imshow(filtered, cmap='gray')

plt.tight_layout()

plt.show()

Colored by Color Scripter


cs

 

결과는 아래와 같다.

gabor filter result

수식은 위키피디아에서 확인 가능하다 : 클릭

예제를 간단하게 살펴보면, cv2.getGaborKernel() 함수는 [커널크기,가우시안 표준편차, 파형 방향, 파형 길이, 공간 비율, 위상] 형태를 매개변수로 받고, 이미지의 방향을 아는 경우 에지를 검출하는 데 유용한 필터이다.

 

 

 

 

discreate Fourier transform (DFT)

이산 푸리에 변환은말 그대로 이산적인 입력 신호에 대한 푸리에 변환으로 보통 신호처리 쪽에서 많이 사용되지만, 이미지를 공간 표현에서 주파수 표현으로 변환하고, 다시 역으로 변환하는 방법에도 이용한다.

 

예제를 한번 알아보자.

 

import cv2

import numpy as np

import matplotlib.pyplot as plt

 

 

 

origin_img = cv2.imread('image.jpg'0).astype(np.float32) # gray scale

origin_img = origin_img / 255

 

# DFT

fft = cv2.dft(origin_img, flags=cv2.DFT_COMPLEX_OUTPUT)

 

# spectrum visualization

shifted = np.fft.fftshift(fft, axes=[0,1])

magnitude = cv2.magnitude(shifted[:,:,0], shifted[:,:,1])

magnitude = np.log(magnitude)

 

plt.figure(figsize=(8,2))

plt.subplot(131)

plt.axis('off')

plt.title('origin_img')

plt.imshow(origin_img, cmap='gray')

plt.subplot(132)

plt.axis('off')

plt.title('magnitude')

plt.imshow(magnitude, cmap='gray')

plt.tight_layout()

Colored by Color Scripter


cs

 

결과는 다음과 같다.

DFT result

이번에도 코드를 간단히 살펴보면, cv2.dft2() 함수는 이산 푸리에 변환을 연산하는 함수 출력이 실수인지 복소수인지를 결정하기 위해 두가지 플래그 선택이 가능하다 (cv2.DFT_REAL_OUTPUT, cv2.DFT_COMPLEX_OUTPUT) / 만약 주파수 스펙트럼에서 공간 표현으로 변환하려면, restore = cv2.idft(fft, flags=cv2.DFT_SCALE | cv2.DFT_REAL_OUTPUT) 를 사용하면되는데, idft 함수는 고속 푸리에 변환 알고리즘을 사용한다. 그리고 np.fft.fftshift 함수는 주파수가 0에 해당하는 진폭 배열의 중심으로 이동하도록 스펙트럼을 이동시켜 해석이 간단해질 수 있다.

 

 

 

image threshold

이미지 임계 처리를 통해 다양한 작업을 할 수 있는데, 이번 예제에서는 흑백 이미지를 이진 이미지로 변환하는 방ㅂ버이다.

 

예제를 한번 알아보자.

import cv2

import numpy as np

import matplotlib.pyplot as plt

 

origin_img = cv2.imread('image.jpg'0# gray scale

#origin_img = origin_img / 255

 

# basic threshold

threshold, mask = cv2.threshold(origin_img, 2001, cv2.THRESH_BINARY)

print('값: ', threshold)

 

# adapt threshold

adapt_mask = cv2.adaptiveThreshold(origin_img, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY_INV, 1110)

 

# visualization

plt.figure(figsize=(10,3))

plt.subplot(131)

plt.axis('off')

plt.title('origin_img')

plt.imshow(origin_img, cmap='gray')

plt.subplot(132)

plt.axis('off')

plt.title('binary threshold')

plt.imshow(mask, cmap='gray')

plt.subplot(133)

plt.axis('off')

plt.title('adaptive threshold')

plt.imshow(adapt_mask, cmap='gray')

plt.tight_layout()

plt.show()

Colored by Color Scripter


cs

결과

threshold result

예제코드를 간단하게 살펴보자,

threshold 처리는 크게 모든 픽셀에 동일한 임계값을 적용할 수 있는 local방식이 있고, 픽셀에 따라 적용하는 threshold값이 다른 adapt 방식이 있다.

cv2.threshold() 함수는 모든 픽셀에 동일한 임계값을 적용하는데, 임계값 type이 cv2.THRESH_BINARY, cv2.THRESH_BINARY_INV 등 있다. 자세한건 document를 보자. 

반면에 cv2.adaptiveThreshold() 함수는 각 픽셀은 주변 픽셀 값에 따라 독자적인 임계값을 가지는데, cv2.ADAPTIVE_THRESH_MEAN_C 방식은 주변 픽셀의 평균에 사용자가 지정한 편향 값 (위 코드는 10)을 뺀 값을 픽셀 단위의 임계값으로 사용했다.

 

 

refer : openCV를 이용한 컴퓨터 비전학습, opencv document

Comments