Deep Learning/강좌&예제 코드

텐서플로우 색 인식 테스트 ( Tensorflow Color Recognition Test )

webnautes 2021. 2. 14. 21:31
반응형

텐서플로우를 사용한 색 인식 코드를( Color Recognition ) 테스트해본 결과입니다.

코드 출처 : https://github.com/dedo24397/ColorClassifier 



2018. 10. 14  최초작성

2021. 02. 14  최종작성 - Python 3.7, Tensorflow 2.4.0, OpenCV 4.4.0 에서 테스트 



 




1. 다음 세 가지 패키지를 설치합니다.

 

pip3 install --upgrade tensorflow

pip3 install opencv-contrib-python

pip3 install python-firebase



Python 3.7에서는 python-firebase 패키지를 다음처럼 설치해야 합니다. Python 3.8 이상에서는 테스트 못해봤습니다. 

 

pip install git+https://github.com/ozgur/python-firebase



다음과 같은 에러가 나기 때문입니다.

 

    from firebase import firebase

  File "C:\Users\webnautes\AppData\Local\Programs\Python\Python37\lib\site-packages\firebase\__init__.py", line 3

    from .async import process_pool

              ^

SyntaxError: invalid syntax

 

 

 

2. 순서대로 다음 세가지 코드를 실행시키면 데이터 가져오기와 훈련이 됩니다. 

  • getData.py

  • processData.py

  • train.py

 

학습시켜도 정확도가 80%를 넘지는 못합니다. 




3. predict.py 코드를 실행시키면 빨간색을 인식하여 red-ish를 출력합니다. 




4. color_recognition.py 코드를 실행 후  이미지에서 마우스로 클릭하면 해당 색 이름을 출력합니다.

유튜브 영상에서는 다음 이미지를 사용했습니다. 

 





getData.py

from firebase import firebase
import json



db = firebase.FirebaseApplication("https://color-classification.firebaseio.com", None)
jsonData = db.get("/colors", None)
data = []

for user in jsonData.keys():
    entry = {}
    entry['r'] = jsonData[user]['r']
    entry['g'] = jsonData[user]['g']
    entry['b'] = jsonData[user]['b']
    entry['label'] = jsonData[user]['label']
    data.append(entry)


json.dump({"data":data}, open("data.json", "w"))

 


processData.py

from firebase import firebase
import json
import numpy as np

data = json.load(open("data.json"))['data']
cols = []
lbls = []
labelsValues = [
    "red-ish",
    "green-ish",
    "blue-ish",
    "orange-ish",
    "yellow-ish",
    "pink-ish",
    "purple-ish",
    "brown-ish",
    "grey-ish"
]
for submission in data:
    color = []
    color.append(submission["r"] / 255)
    color.append(submission["g"] / 255)
    color.append(submission["b"] / 255)
    cols.append(color)
    lbls.append(labelsValues.index(submission["label"]))

colors = np.array(cols, dtype=np.float32)
labels = np.array(lbls, dtype=np.uint8)
np.savez_compressed("processedData", colors = colors, labels = labels)



train.py


import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

import tensorflow as tf
import numpy as np
from random import randint
import json

colors = None
labels = None
data_size = 0


# tf.enable_eager_execution()


with tf.device("/cpu:0"):
    with np.load("processedData.npz") as savedData:
        colors = np.array(savedData['colors'], dtype=np.float32)
        labels = tf.one_hot(savedData['labels'], 9, dtype=tf.uint8).numpy()
        data_size = len(savedData['colors'])


train_size = int(data_size*0.8)
test_size = validation_size = int((data_size - train_size)/2)

indexes = [randint(0, data_size-1) for i in range(train_size)]
colors_train = tf.constant([colors[i] for i in indexes])
labels_train = tf.constant([labels[i] for i in indexes])
test_indexes = []
for i in range(0, data_size):
    if not (i in indexes):
        test_indexes.append(i)
test_indexes = [test_indexes[randint(0, test_size-1)] for i in range(test_size)]
colors_test = tf.constant([colors[i] for i in test_indexes])
labels_test = tf.constant([labels[i] for i in test_indexes])
validation_indexes = []
for i in range(0, data_size):
    if not (i in test_indexes) and not (i in indexes):
        validation_indexes.append(i)
validation_indexes = [validation_indexes[randint(0, validation_size-1)]  for i in range(validation_size)]
colors_validation = tf.constant([colors[i] for i in validation_indexes])
labels_validation = tf.constant([labels[i] for i in validation_indexes])

np.savez_compressed("dataset", train_x = colors_train.numpy(), train_y = labels_train.numpy(), test_x = colors_test.numpy(),
        test_y = labels_test.numpy(), validation_x = colors_validation.numpy(), validation_y = labels_validation.numpy())

model = tf.keras.models.Sequential([
    tf.keras.layers.Dense(64, input_shape=(3,),activation=tf.nn.relu),
    tf.keras.layers.Dense(9, activation=tf.nn.softmax)
])

model.compile(optimizer='adam',
              loss='categorical_crossentropy',
              metrics=['accuracy'])

print("Training:")
model.fit(colors_train, tf.cast(labels_train, tf.float32), epochs=15, batch_size=32)
print("Training ended. Validating:")
model.fit(colors_validation, tf.cast(labels_validation, tf.float32), epochs=15, batch_size=32)
json.dump({'model':model.to_json()}, open("model.json", "w"))
model.save_weights("model_weights.h5")

 

predict.py

import tensorflow as tf
import numpy as np
import json


labelsValues = [
    "red-ish",
    "green-ish",
    "blue-ish",
    "orange-ish",
    "yellow-ish",
    "pink-ish",
    "purple-ish",
    "brown-ish",
    "grey-ish"
]


# tf.enable_eager_execution()


#LOADING MODEL
model = tf.keras.models.model_from_json(json.load(open("model.json"))["model"], custom_objects={})
model.load_weights("model_weights.h5")
print("Loaded model from disk")

r = 254 / 255
g = 0 / 255
b = 2 / 255
# 254 0 2 orange-ish
# 12 255 2 red-ish
t = np.argmax(model.predict(tf.constant([[r, g, b]], dtype=tf.float32)))
print(labelsValues[t])



color_recognition.py

import cv2 as cv
import tensorflow as tf
import numpy as np
import json

hsv = 0
lower_blue1 = 0
upper_blue1 = 0
lower_blue2 = 0
upper_blue2 = 0
lower_blue3 = 0
upper_blue3 = 0


labelsValues = [
    "red-ish",
    "green-ish",
    "blue-ish",
    "orange-ish",
    "yellow-ish",
    "pink-ish",
    "purple-ish",
    "brown-ish",
    "grey-ish"
]



def mouse_callback(event, x, y, flags, param):
    global hsv, lower_blue1, upper_blue1, lower_blue2, upper_blue2, lower_blue3, upper_blue3

    # 마우스 왼쪽 버튼 누를시 위치에 있는 픽셀값을 읽어와서 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]

        # HSV 색공간에서 마우스 클릭으로 얻은 픽셀값과 유사한 필셀값의 범위를 정합니다.
        if hsv[0] < 10:
            print("case1")
            lower_blue1 = np.array([hsv[0]-10+180, 30, 30])
            upper_blue1 = np.array([180, 255, 255])
            lower_blue2 = np.array([0, 30, 30])
            upper_blue2 = np.array([hsv[0], 255, 255])
            lower_blue3 = np.array([hsv[0], 30, 30])
            upper_blue3 = 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], 0, 0])
            upper_blue1 = np.array([180, 255, 255])
            lower_blue2 = np.array([0, 0, 0])
            upper_blue2 = np.array([hsv[0]+10-180, 255, 255])
            lower_blue3 = np.array([hsv[0]-10, 0, 0])
            upper_blue3 = np.array([hsv[0], 255, 255])
            #     print(i, 180, 0, i+10-180)
            #     print(i-10, i)
        else:
            print("case3")
            lower_blue1 = np.array([hsv[0], 30, 30])
            upper_blue1 = np.array([hsv[0]+10, 255, 255])
            lower_blue2 = np.array([hsv[0]-10, 30, 30])
            upper_blue2 = np.array([hsv[0], 255, 255])
            lower_blue3 = np.array([hsv[0]-10, 30, 30])
            upper_blue3 = 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("@3", lower_blue3, "~", upper_blue3)



        r = color[2]/ 255
        g = color[1]/ 255
        b = color[0]/ 255

        print(r, g, b)


        result = np.argmax(model.predict(tf.constant([[r, g, b]], dtype=tf.float32)))
        print(labelsValues[result])



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



#tf.enable_eager_execution()

#LOADING MODEL
model = tf.keras.models.model_from_json(json.load(open("model.json"))["model"], custom_objects={})
model.load_weights("model_weights.h5")
print("Loaded model from disk")



while(True):
    img_color = cv.imread('0.jpg')
    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_mask3 = cv.inRange(img_hsv, lower_blue3, upper_blue3)
    img_mask = img_mask1 | img_mask2 | img_mask3


    # 마스크 이미지로 원본 이미지에서 범위값에 해당되는 영상 부분을 획득합니다.
    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()
반응형

천천히 하지만 꾸준히 공부한 내용을 블로그에 공유하는 것이 제 취미생활입니다.
블로그를 시작하게 된 계기는 내가 알게된 내용을 정리하려고 였는데 이왕이면 다른 사람에게도 공유하자였지요.

블로그 내용을 진행해보다가 문제 발생시 지나치지 말고 댓글로 알려주세요. 그래야 다음에 해당 글을 읽는 분에게 도움이 됩니다.



글이 많이 유익하셨다면 토스아이디로 후원해주세요. 토스아이디



제가 쓴 책도 한번 검토해보세요 ^^