본문 바로가기
Team Project/핸들랭(handlang)

Welcome to Codelabs!

by 알 수 없는 사용자 2019. 11. 18.

Google Codelab에서 tensorflow 3,4를 같이 분석해보는 시간을 가졌다.

 

Learn Tensorflow 3: Introduction to Convolutions

<Learn Tensorflow 3: Introduction to Convolutions>

https://codelabs.developers.google.com/codelabs/tensorflow-lab3-convolutions/index.html?index=..%2F..index#0

불러오는 중입니다...

.

tensorflow 3은 tensorflow 2의 연장선인데 tensorflow 2에서 아이템이 이미지의 중앙에 있는 28*28의 회색조 이미지만 처리할 수 있었다. 하지만 tensorflow 3에서는 조금 더 일반적인 이미지를 처리하기 위해서  convolution을 사용한다.

 

convolution은 이미지를 통과하고 처리하며 이미지에서 공통성을 나타내는 기능을 추출하는 필터입니다. 주어진 필터에 가중치들이 정해져있고 각 픽셀값에 필터의 가중치를 곱하여 더해서 새 픽셀 값을 계산할 수 있다.

 

filter = [ [-1, -2, -1], [0, 0, 0], [1, 2, 1]]

 

코드랩에서는 위 필터를 사용했다. training image로 세로선이 많은 계단 사진을 사용했기 때문에 직선을 추출해내기 위해서이다. 

 

위의 코드를 실행하면 이미지를 반복하면서 가장자리에 1 픽셀의 여백을 남겨두고 현재 픽셀의 각 인접 항목에 필터에 정의된 값을 곱한다. 결과에 가중치를 곱한 다음 결과가 0-255 범위에 있는지 확인한다. 마지막으로 변환된 이미지에 새로운 값을 로드한다. 이 과정은 필터에 따라 다르게 관찰될 수 있다.

 

filter = [-1,0,1,-2,0,2,-1,0,1] 를 사용하면 기본 이미지에서 매우 강력한 수직선들을 추출해낼 수 있다.

filter = [-1,-2,-1,0,0,0,1,2,1] 를 사용하면 기본 이미지에서 수평선을 추출해낼 수 있다.

 

풀링은 convolution을 사용할 뿐만 아니라 fiture 감지에 큰 도움이 된다. 풀링은 여러 가지 유형이 있지만 이번 실습에서는 MAX 풀링을 사용한다. 이 방법은 인접한 4개의 픽셀 중 MAX값을 대표값으로 하여, 새로운 이미지를 기존 이미지의 1/4크기로 얻는 것이다.

 

<colaboratory>

https://drive.google.com/open?id=1ih2YoYRr6DfkkZQqbiTa2DV5r2AIzK3B

불러오는 중입니다...

.

Learn Tensorflow 4: Convolutional Neural Networks (CNNs)

<Learn Tensorflow 4: Introduction to Convolutions>

https://codelabs.developers.google.com/codelabs/tensorflow-lab4-cnns/index.html?index=..%2F..index#7

불러오는 중입니다...

.

tensorflow 2의 코드를 다시 실행하고 정확도를 확인해본다. 그리고 나서 convolutional 레이어를 추가한 뒤 실행시켰을 때 데이터의 정확도가 높아진 것을 확인할 수 있다.

 

하지만 너무 많은 에포크 만큼 실행을 하면 overfitting 현상으로 인해 유효성 검사 결과가 저하될 수도 있다. 네트워크가 훈련 세트에서 데이터를 너무 잘 배울 때 '과잉 적합'이 발생하여 해당 데이터만 인식하는 것에 특이적이 되어 일반적인 상황에서 다른 데이터를 보는 데 덜 효과적이게 된다.

 

 

------------------------------------------------------------------------------------------------------------------------------------

 

추가적으로 openCV로 구현한 간단한 예제도 살펴보았다.

https://www.youtube.com/watch?v=zVuPIBW4Ri8&list=PLwfJJiO20qkDue05S5MNhgYNnClMVlagN&index=6

 

'''
2019.11.16
'''
import cv2 as cv
import numpy as np

hsv = 0
lower_blue1 = 0
upper_blue1 = 0
lower_blue2 = 0
upper_blue2 = 0
lower_bluethreshold = 0
upper_bluethreshold = 0


def nothing(x):
    pass


def mouse_callback(event, x, y, flags, param):
    global hsv, lower_blue1, upper_blue1, lower_blue2, upper_blue2, lower_bluethreshold, upper_bluethreshold, threshold

    # 마우스 왼쪽 버튼 누를시 위치에 있는 픽셀값을 읽어와서 HSV로 변환합니다.
    if event == cv.EVENT_LBUTTONDOWN:
        print(img_color[y, x])
        color = img_color[y, x]

        one_pixel = np.uint8([[color]])
        hsv = cv.cvtColor(one_pixel, cv.COLOR_BGR2HSV)
        hsv = hsv[0][0]

        threshold = cv.getTrackbarPos('threshold', 'img_result')
        # HSV 색공간에서 마우스 클릭으로 얻은 픽셀값과 유사한 필셀값의 범위를 정합니다.
        if hsv[0] < 10:
            print("case1")
            lower_blue1 = np.array([hsv[0] - 10 + 180, threshold, threshold])
            upper_blue1 = np.array([180, 255, 255])
            lower_blue2 = np.array([0, threshold, threshold])
            upper_blue2 = np.array([hsv[0], 255, 255])
            lower_bluethreshold = np.array([hsv[0], threshold, threshold])
            upper_bluethreshold = np.array([hsv[0] + 10, 255, 255])
            #     print(i-10+180, 180, 0, i)
            #     print(i, i+10)

        elif hsv[0] > 170:
            print("case2")
            lower_blue1 = np.array([hsv[0], threshold, threshold])
            upper_blue1 = np.array([180, 255, 255])
            lower_blue2 = np.array([0, threshold, threshold])
            upper_blue2 = np.array([hsv[0] + 10 - 180, 255, 255])
            lower_bluethreshold = np.array([hsv[0] - 10, threshold, threshold])
            upper_bluethreshold = np.array([hsv[0], 255, 255])
            #     print(i, 180, 0, i+10-180)
            #     print(i-10, i)
        else:
            print("casethreshold")
            lower_blue1 = np.array([hsv[0], threshold, threshold])
            upper_blue1 = np.array([hsv[0] + 20, 255, 255])
            lower_blue2 = np.array([hsv[0] - 20, threshold, threshold])
            upper_blue2 = np.array([hsv[0], 255, 255])
            lower_bluethreshold = np.array([hsv[0] - 10, threshold, threshold])
            upper_bluethreshold = np.array([hsv[0], 255, 255])
            #     print(i, i+10)
            #     print(i-10, i)

        print(hsv[0])
        print("@1", lower_blue1, "~", upper_blue1)
        print("@2", lower_blue2, "~", upper_blue2)
        print("@threshold", lower_bluethreshold, "~", upper_bluethreshold)

cv.namedWindow('img_color')
cv.setMouseCallback('img_color', mouse_callback)

cv.namedWindow('img_result')
cv.createTrackbar('threshold', 'img_result', 0, 255, nothing)
cv.setTrackbarPos('threshold', 'img_result', 60)
cap = cv.VideoCapture(0)

while (True):
    # img_color = cv.imread('2.jpg')
    ret, img_color = cap.read()
    height, width = img_color.shape[:2]
    img_color = cv.resize(img_color, (width, height), interpolation=cv.INTER_AREA)

    # 원본 영상을 HSV 영상으로 변환합니다.
    img_hsv = cv.cvtColor(img_color, cv.COLOR_BGR2HSV)

    # 범위 값으로 HSV 이미지에서 마스크를 생성합니다.
    img_mask1 = cv.inRange(img_hsv, lower_blue1, upper_blue1)
    img_mask2 = cv.inRange(img_hsv, lower_blue2, upper_blue2)
    img_maskthreshold = cv.inRange(img_hsv, lower_bluethreshold, upper_bluethreshold)
    img_mask = img_mask1 | img_mask2 | img_maskthreshold

    kernel = np.ones((11, 11), np.uint8)
    img_mask = cv.morphologyEx(img_mask, cv.MORPH_OPEN, kernel)
    img_mask = cv.morphologyEx(img_mask, cv.MORPH_CLOSE, kernel)

    # 마스크 이미지로 원본 이미지에서 범위값에 해당되는 영상 부분을 획득합니다.
    img_result = cv.bitwise_and(img_color, img_color, mask=img_mask)

    cv.imshow('img_color', img_color)
    cv.imshow('img_mask', img_mask)
    cv.imshow('img_result', img_result)

    # ESC 키누르면 종료
    if cv.waitKey(1) & 0xFF == 27:
        break

cv.destroyAllWindows()

댓글