텐서플로우를 사용한 색 인식 코드를( 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()
'Deep Learning & Machine Learning > 강좌&예제 코드' 카테고리의 다른 글
손글씨 숫자 인식하여 세븐 세그먼트에 출력하기 (0) | 2021.06.16 |
---|---|
텐서플로우 강좌 - 텍스트 분류(text classification) (0) | 2021.05.09 |
Tensorflow 예제 - tf.argmax 함수 사용법 (3) | 2020.08.01 |
TensorFlow 강좌 - Fashion MNIST 분류를 위해 뉴럴 네트워크 학습 시키기 (0) | 2019.12.01 |
Tensorflow 기초 강좌 - Tensor, Operation, Graph, Session에 대하여 (1) | 2019.11.09 |
시간날때마다 틈틈이 이것저것 해보며 블로그에 글을 남깁니다.
블로그의 문서는 종종 최신 버전으로 업데이트됩니다.
여유 시간이 날때 진행하는 거라 언제 진행될지는 알 수 없습니다.
영화,책, 생각등을 올리는 블로그도 운영하고 있습니다.
https://freewriting2024.tistory.com
제가 쓴 책도 한번 검토해보세요 ^^
그렇게 천천히 걸으면서도 그렇게 빨리 앞으로 나갈 수 있다는 건.
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!