From 668e8ce61db8c4b6d289a8fa66fa4481905d3cc4 Mon Sep 17 00:00:00 2001 From: Michiel_VE <r0794174@student.thomasmore.be> Date: Sat, 1 Jun 2024 12:35:39 +0300 Subject: [PATCH] update what image is send --- Func/ClassifierModule.py | 15 +++--- Func/DrawImages.py | 20 +++++++ Func/Helpers.py | 5 +- Model/labels.txt | 4 +- main.py | 3 +- trainModel.ipynb | 114 +++++++++++++++++++++++---------------- trainModel.py | 4 +- 7 files changed, 106 insertions(+), 59 deletions(-) create mode 100644 Func/DrawImages.py diff --git a/Func/ClassifierModule.py b/Func/ClassifierModule.py index 9b784d8..672e119 100644 --- a/Func/ClassifierModule.py +++ b/Func/ClassifierModule.py @@ -1,6 +1,7 @@ import keras import numpy as np import cv2 +from cvzone.HandTrackingModule import HandDetector class Classifier: @@ -20,7 +21,8 @@ class Classifier: else: print("No Labels Found") - def getPrediction(self, img, draw=True, pos=(50, 50), scale=2, color=(0, 255, 0)): + def getPrediction(self, img): + cv2.imshow("imgFixed classifier", img) img_resized = cv2.resize(img, (224, 224)) image_array = np.asarray(img_resized) normalized_image_array = (image_array.astype(np.float32) / 127.0) - 1 @@ -30,30 +32,29 @@ class Classifier: prediction = self.model.predict(self.data) index_val = np.argmax(prediction) - if draw and self.labels_path: - label_text = str(self.list_labels[index_val]) - cv2.putText(img, label_text, pos, cv2.FONT_HERSHEY_COMPLEX, scale, color, 2) - return list(prediction[0]), index_val def main(): cap = cv2.VideoCapture(0) + detector = HandDetector(maxHands=1) mask_classifier = Classifier('Model/keras_model.h5', 'Model/labels.txt') while True: ret, frame = cap.read() + hands, img = detector.findHands(frame) + if not ret: print("Failed to capture frame") break - prediction = mask_classifier.getPrediction(frame) + prediction = mask_classifier.getPrediction(img) print("Prediction:", prediction) - cv2.imshow("Image", frame) + if cv2.waitKey(1) & 0xFF == ord('q'): break diff --git a/Func/DrawImages.py b/Func/DrawImages.py new file mode 100644 index 0000000..be948e2 --- /dev/null +++ b/Func/DrawImages.py @@ -0,0 +1,20 @@ +import matplotlib.pyplot as plt +import numpy as np + + +def plot_images(images, labels, class_indices): + num_images = len(images) + grid_size = int(np.ceil(np.sqrt(num_images))) + + plt.figure(figsize=(15, 15)) + for i in range(num_images): + plt.subplot(grid_size, grid_size, i + 1) + img = images[i] + plt.imshow(img) + + label = np.argmax(labels[i]) + label_name = list(class_indices.keys())[list(class_indices.values()).index(label)] + plt.title(label_name) + plt.axis('off') + plt.tight_layout() + plt.show() \ No newline at end of file diff --git a/Func/Helpers.py b/Func/Helpers.py index a096e33..d8c2026 100644 --- a/Func/Helpers.py +++ b/Func/Helpers.py @@ -21,7 +21,8 @@ def CalculateHeight(size, h, w, imgCropped, imgFixed): def GetPrediction(classifier, imgFixed): - prediction, index = classifier.getPrediction(imgFixed, draw=False) + cv2.imshow('imgFixed helper', imgFixed) + prediction, index = classifier.getPrediction(imgFixed) return prediction, index @@ -35,4 +36,4 @@ def GetLabels(path): letter = parts[1] letters.append(letter) - return letters + return letters \ No newline at end of file diff --git a/Model/labels.txt b/Model/labels.txt index 30b5960..5fbcfab 100644 --- a/Model/labels.txt +++ b/Model/labels.txt @@ -1,4 +1,6 @@ 0 A 1 B 2 C -3 D \ No newline at end of file +3 D +4 E +5 F \ No newline at end of file diff --git a/main.py b/main.py index 4a6a59a..418e488 100644 --- a/main.py +++ b/main.py @@ -45,6 +45,7 @@ while True: else: CalculateHeight(size, h, w, imgCropped, imgFixed) + cv2.imshow("imgFixed", imgFixed) prediction, index = GetPrediction(classifier, imgFixed) print('pred', prediction) @@ -52,7 +53,7 @@ while True: cv2.putText(imgOutput, letters[index], (x, y), cv2.FONT_HERSHEY_TRIPLEX, 2, (255, 0, 255), 2) - cv2.imshow("img", imgOutput) + cv2.imshow("img main", imgOutput) key = cv2.waitKey(1) if key == ord('p'): diff --git a/trainModel.ipynb b/trainModel.ipynb index 97c3462..e849f59 100644 --- a/trainModel.ipynb +++ b/trainModel.ipynb @@ -2,76 +2,80 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, + "execution_count": 51, "id": "62c6c5c3-d2ba-4e79-b533-828c3083e8ea", - "metadata": {}, + "metadata": { + "is_executing": true + }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ + "Num GPUs Available: 1\n", + "Physical devices cannot be modified after being initialized\n", "Found 1529 images belonging to 6 classes.\n", "Found 380 images belonging to 6 classes.\n", "Epoch 1/10\n", - "48/48 [==============================] - 29s 470ms/step - loss: 1.0985 - accuracy: 0.5284 - val_loss: 0.7411 - val_accuracy: 0.6868\n", + "24/24 [==============================] - 21s 851ms/step - loss: 1.1108 - accuracy: 0.5134 - val_loss: 0.8370 - val_accuracy: 0.6842\n", "Epoch 2/10\n", - "48/48 [==============================] - 20s 417ms/step - loss: 0.5369 - accuracy: 0.7757 - val_loss: 0.5103 - val_accuracy: 0.7921\n", + "24/24 [==============================] - 21s 862ms/step - loss: 0.6156 - accuracy: 0.7613 - val_loss: 0.4063 - val_accuracy: 0.8447\n", "Epoch 3/10\n", - "48/48 [==============================] - 20s 417ms/step - loss: 0.2837 - accuracy: 0.8875 - val_loss: 0.8421 - val_accuracy: 0.7105\n", + "24/24 [==============================] - 22s 915ms/step - loss: 0.2704 - accuracy: 0.9006 - val_loss: 0.2283 - val_accuracy: 0.9316\n", "Epoch 4/10\n", - "48/48 [==============================] - 20s 417ms/step - loss: 0.1952 - accuracy: 0.9228 - val_loss: 0.2502 - val_accuracy: 0.8947\n", + "24/24 [==============================] - 22s 909ms/step - loss: 0.1532 - accuracy: 0.9477 - val_loss: 0.1145 - val_accuracy: 0.9579\n", "Epoch 5/10\n", - "48/48 [==============================] - 20s 419ms/step - loss: 0.1007 - accuracy: 0.9647 - val_loss: 0.0922 - val_accuracy: 0.9632\n", + "24/24 [==============================] - 22s 905ms/step - loss: 0.1324 - accuracy: 0.9516 - val_loss: 0.2525 - val_accuracy: 0.9026\n", "Epoch 6/10\n", - "48/48 [==============================] - 19s 404ms/step - loss: 0.0690 - accuracy: 0.9719 - val_loss: 0.1608 - val_accuracy: 0.9316\n", + "24/24 [==============================] - 22s 912ms/step - loss: 0.0737 - accuracy: 0.9719 - val_loss: 0.0519 - val_accuracy: 0.9816\n", "Epoch 7/10\n", - "48/48 [==============================] - 19s 406ms/step - loss: 0.0707 - accuracy: 0.9745 - val_loss: 0.1129 - val_accuracy: 0.9500\n", + "24/24 [==============================] - 23s 952ms/step - loss: 0.0663 - accuracy: 0.9797 - val_loss: 0.0544 - val_accuracy: 0.9842\n", "Epoch 8/10\n", - "48/48 [==============================] - 19s 401ms/step - loss: 0.0674 - accuracy: 0.9791 - val_loss: 0.0428 - val_accuracy: 0.9868\n", + "24/24 [==============================] - 22s 918ms/step - loss: 0.0482 - accuracy: 0.9817 - val_loss: 0.0489 - val_accuracy: 0.9711\n", "Epoch 9/10\n", - "48/48 [==============================] - 19s 400ms/step - loss: 0.0260 - accuracy: 0.9922 - val_loss: 0.0619 - val_accuracy: 0.9711\n", + "24/24 [==============================] - 22s 928ms/step - loss: 0.0240 - accuracy: 0.9908 - val_loss: 0.0337 - val_accuracy: 0.9868\n", "Epoch 10/10\n", - "48/48 [==============================] - 20s 404ms/step - loss: 0.0142 - accuracy: 0.9961 - val_loss: 0.0146 - val_accuracy: 0.9947\n", - "12/12 [==============================] - 4s 329ms/step - loss: 0.0094 - accuracy: 0.9974\n", - "Test loss: 0.009386303834617138, Test accuracy: 0.9973683953285217\n", - "Model: \"sequential\"\n", + "24/24 [==============================] - 22s 911ms/step - loss: 0.0224 - accuracy: 0.9922 - val_loss: 0.0411 - val_accuracy: 0.9895\n", + "6/6 [==============================] - 4s 717ms/step - loss: 0.0078 - accuracy: 1.0000\n", + "Test loss: 0.007844111882150173, Test accuracy: 1.0\n", + "Model: \"sequential_32\"\n", "_________________________________________________________________\n", " Layer (type) Output Shape Param # \n", "=================================================================\n", - " conv2d (Conv2D) (None, 222, 222, 32) 896 \n", + " conv2d_128 (Conv2D) (None, 222, 222, 32) 896 \n", " \n", - " max_pooling2d (MaxPooling2D (None, 111, 111, 32) 0 \n", - " ) \n", + " max_pooling2d_128 (MaxPooli (None, 111, 111, 32) 0 \n", + " ng2D) \n", " \n", - " conv2d_1 (Conv2D) (None, 109, 109, 64) 18496 \n", + " conv2d_129 (Conv2D) (None, 109, 109, 64) 18496 \n", " \n", - " max_pooling2d_1 (MaxPooling (None, 54, 54, 64) 0 \n", - " 2D) \n", + " max_pooling2d_129 (MaxPooli (None, 54, 54, 64) 0 \n", + " ng2D) \n", " \n", - " conv2d_2 (Conv2D) (None, 52, 52, 128) 73856 \n", + " conv2d_130 (Conv2D) (None, 52, 52, 128) 73856 \n", " \n", - " max_pooling2d_2 (MaxPooling (None, 26, 26, 128) 0 \n", - " 2D) \n", + " max_pooling2d_130 (MaxPooli (None, 26, 26, 128) 0 \n", + " ng2D) \n", " \n", - " conv2d_3 (Conv2D) (None, 24, 24, 256) 295168 \n", + " conv2d_131 (Conv2D) (None, 24, 24, 256) 295168 \n", " \n", - " max_pooling2d_3 (MaxPooling (None, 12, 12, 256) 0 \n", - " 2D) \n", + " max_pooling2d_131 (MaxPooli (None, 12, 12, 256) 0 \n", + " ng2D) \n", " \n", - " flatten (Flatten) (None, 36864) 0 \n", + " flatten_32 (Flatten) (None, 36864) 0 \n", " \n", - " dense (Dense) (None, 256) 9437440 \n", + " dense_96 (Dense) (None, 256) 9437440 \n", " \n", - " dense_1 (Dense) (None, 128) 32896 \n", + " dense_97 (Dense) (None, 128) 32896 \n", " \n", - " dense_2 (Dense) (None, 6) 774 \n", + " dense_98 (Dense) (None, 6) 774 \n", " \n", "=================================================================\n", "Total params: 9,859,526\n", "Trainable params: 9,859,526\n", "Non-trainable params: 0\n", "_________________________________________________________________\n", - "It took: 3.55 minutes\n" + "It took: 3.74 minutes\n" ] } ], @@ -84,21 +88,30 @@ "from tensorflow.keras.callbacks import EarlyStopping\n", "from tensorflow.keras.optimizers import Adam\n", "import tensorflow as tf\n", - "from keras import layers, models\n", "\n", "from Func.getSubFolders import count_sub_folders\n", "\n", + "\n", "path = 'Data'\n", "output = 'Model/keras_model.h5'\n", "start_time = time.time()\n", "\n", - "# runtime error\n", - "# physical_devices = tf.config.experimental.list_physical_devices('GPU')\n", - "# print(\"Num GPUs Available: \", len(physical_devices))\n", - "# if len(physical_devices) > 0:\n", - "# tf.config.experimental.set_memory_growth(physical_devices[0], True)\n", - "# else:\n", - "# print(\"No GPU available. Using CPU.\")\n", + "physical_devices = tf.config.list_physical_devices('GPU')\n", + "print(\"Num GPUs Available: \", len(physical_devices))\n", + "if len(physical_devices) > 0:\n", + " try:\n", + " # Set memory growth to true\n", + " for device in physical_devices:\n", + " tf.config.experimental.set_memory_growth(device, True)\n", + " \n", + " # Optionally, you can set a memory limit if necessary\n", + " # tf.config.set_logical_device_configuration(\n", + " # physical_devices[0],\n", + " # [tf.config.LogicalDeviceConfiguration(memory_limit=4096)]) # Set to 4GB\n", + " except RuntimeError as e:\n", + " print(e)\n", + "else:\n", + " print(\"No GPU available. Using CPU.\")\n", "\n", "\n", "# Step 1: Load and Preprocess Images\n", @@ -113,26 +126,35 @@ "\n", "test_datagen = ImageDataGenerator(rescale=1. / 255)\n", "\n", + "\n", "# Step 2: Label the Data\n", "train_set = datagen.flow_from_directory(\n", " path,\n", - " target_size=(224, 224),\n", - " batch_size=32,\n", + " target_size=(300, 300),\n", + " batch_size=64,\n", " class_mode='categorical',\n", " subset='training'\n", ")\n", "\n", "test_set = datagen.flow_from_directory(\n", " path,\n", - " target_size=(224, 224),\n", - " batch_size=32,\n", + " target_size=(300, 300),\n", + " batch_size=64,\n", " class_mode='categorical',\n", " subset='validation'\n", ")\n", "\n", + "# draw Images\n", + "# images, labels = next(test_set)\n", + "\n", + "# class_indices = test_set.class_indices\n", + "# plot_images(images, labels, class_indices)\n", + "\n", + "\n", + "\n", "# Step 4: Build the Model\n", "model = Sequential()\n", - "model.add(Conv2D(32, (3, 3), input_shape=(224, 224, 3), activation='relu'))\n", + "model.add(Conv2D(32, (3, 3), input_shape=(300, 300, 3), activation='relu'))\n", "model.add(MaxPooling2D(pool_size=(2, 2)))\n", "\n", "model.add(Conv2D(64, (3, 3), activation='relu'))\n", @@ -214,7 +236,7 @@ { "cell_type": "code", "execution_count": null, - "id": "67803a21-51f7-4bec-98fc-4efa8f75bab9", + "id": "ec102c63-b7d9-4f22-9f3e-a6bd12995a4f", "metadata": {}, "outputs": [], "source": [] diff --git a/trainModel.py b/trainModel.py index 9e81941..860f0b3 100644 --- a/trainModel.py +++ b/trainModel.py @@ -37,7 +37,7 @@ train_set = datagen.flow_from_directory( test_set = datagen.flow_from_directory( path, - target_size=(224, 224), + target_size=(300, 300), batch_size=32, class_mode='categorical', subset='validation' @@ -45,7 +45,7 @@ test_set = datagen.flow_from_directory( # Step 4: Build the Model model = Sequential() -model.add(Conv2D(32, (3, 3), input_shape=(224, 224, 3), activation='relu')) +model.add(Conv2D(32, (3, 3), input_shape=(300, 300, 3), activation='relu')) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Conv2D(64, (3, 3), activation='relu')) -- GitLab