NLP_자연언어처리, Colab

[Colab] Sobel Prewitt Laplacian LoC 연산

vhxpffltm 2020. 6. 1. 22:19

먼저 위의 4가지 연산은 영상 처리에서 사용되는 개념이고 연산들이다. 

 

Edge, 즉 경계선을 검출하는데 사용이 되며 영상에서의 edge란 영상의 밝기가 낮은 값에서 높은 값으로, 또는 이와 반대로 변하는 지점에 존재하는 부분을 의미한다.

edge는 영상안에 있는 객체의 경계(boundary)를 가리키는 것으로서, 모양(shape), 방향성(direction)을 탐지할 수 있는 등 여러 정보가 담겨있다. edge detection이란 에지에 해당하는 화소를 찾는 과정이다


한마디로 하자면, Edge는 어떤 객체와 배경 혹은 다른 객체와의 경계를 의미한다.

이런 Edge를 탐지하기 위해서는 밝기 값의 변화로 파악하는데 이 변화를 1차 미분과 2차 미분을 통해 확인한다.

1차 미분으로 Edge의 존재여부를, 2차 미분으로 밝기의 방향을 알 수 있다.

이제 위 4가지 검출에 대해 간단하게 알아보자

 

Sobel

Prewitt의 단점을 극복하여 수직, 수평, 대각선까지 검출이 가능하다. 잡음에 강하지만 연산속도가 느리다.

 

Prewitt

비교적 널리 사용되며 수직, 수평 Edge 검출에 사용된다. Sobel 마스크에 비해 Edge가 덜 부각되지만 그만큼 빠르다.

 

Laplacian

1차 미분으로 너무 많은 수직, 수평, 대각선의 Edge를 검출하면 결과가 달라질 수 있다.

2차 미분을 사용하며 모든 방향의 윤곽선을 검출하며 저주파 값들은 소거되고 고주파값들은 강조된다.

LoG

라플라시안 연산이 잡음에 민감하기에 잡음을 제거해주는 연산이다.

가우시안 스무딩을 적용하고 라플라시안 연산을 적용한다. 

 

 

그럼 위에서 간단하게 살펴본 연산들을 python 코드로 나타내면 아래와 같다. 16 x 16 이미지를 먼저 numpy를 통해 normalization 하고 각각의 연산을 적용하는 코드이다.

 

RGB 3채널에 대해 255,255,255 를 각각 가지고 있는것을 normalzation하여 적용한다. 

여기서는 openCV 등의 패키지를 사용하지 않는 코드이다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#각 함수들은 오픈소스로 적용
def Relu_threshold(input, threshold=3):
    for height in range(np.shape(input)[0]):
        for width in range(np.shape(input)[1]):
            if input[height, width] <= threshold:
                input[height, width] = 0
    output = input
    return output
#Relu 함수
def sobel_operator(input, threshold=1, axis=2):
    input_y = np.ndarray(shape=(np.shape(input)[1:]), dtype=np.float32)
    input_x = np.ndarray(shape=(np.shape(input)[1:]), dtype=np.float32)
    output = np.ndarray(shape=(np.shape(input)), dtype=np.float32)
    for _ in range(len(input)):
        input_y[:, :] = ndimage.sobel(input[_, :, :], 0)
        input_x[:, :] = ndimage.sobel(input[_, :, :], 1)
        if axis == 0:
            output[_, :, :] = input_y[:, :]
        elif axis == 1:
            output[_, :, :] = input_x[:, :]
        elif axis == 2:
            output[_, :, :] = np.sqrt(np.square(input_x[:, :]) + np.square(input_y[:, :]))
            output[_, :, :] = Relu_threshold(output[_, :, :], threshold=threshold)
    return output
#sobel_operator 함수
 
def prewitt_operator(input, threshold=1, axis=2):
    input_y = np.ndarray(shape=(np.shape(input)[1:]), dtype=np.float32)
    input_x = np.ndarray(shape=(np.shape(input)[1:]), dtype=np.float32)
    output = np.ndarray(shape=(np.shape(input)), dtype=np.float32)
    for _ in range(len(input)):
        input_y[:, :] = ndimage.prewitt(input[_, :, :], 0)
        input_x[:, :] = ndimage.prewitt(input[_, :, :], 1)
        if axis == 0:
            output[_, :, :] = input_y[:, :]
        elif axis == 1:
            output[_, :, :] = input_x[:, :]
        elif axis == 2:
            output[_, :, :] = np.sqrt(np.square(input_x[:, :]) + np.square(input_y[:, :]))
            output[_, :, :] = Relu_threshold(output[_, :, :], threshold=threshold)
    return output
#prewitt_operator 함수
 
def laplacian_operator(input):
    output = np.ndarray(shape=(np.shape(input)), dtype=np.float32)
    for _ in range(len(input)):
        output[_, :, :] = ndimage.laplace(input[_, :, :])
    return output
#라플라시안 operator 함수
 
def gaussian_laplace_operator(input):
    output = np.ndarray(shape=(np.shape(input)), dtype=np.float32)
    for _ in range(len(input)):
        output[_, :, :] = ndimage.gaussian_laplace(input[_, :, :], sigma=1)
    return output
#gaussian_laplace 함수
cs

 

Refernce

https://blog.naver.com/PostView.nhn?blogId=dic1224&logNo=80181167932&proxyReferer=https:%2F%2Fwww.google.com%2F

https://iskim3068.tistory.com/49

http://blog.daum.net/trts1004/12109067