{ "nbformat": 4, "nbformat_minor": 0, "metadata": { "colab": { "name": "Détection automatique de faces de dés.ipynb", "provenance": [], "collapsed_sections": [] }, "kernelspec": { "name": "python3", "display_name": "Python 3" } }, "cells": [ { "cell_type": "markdown", "metadata": { "id": "x5jcbhhz09QT", "colab_type": "text" }, "source": [ "# Reconnaissance automatique de faces de dés\n", "\n", "avec Python, Tensorflow et un réseau de neurones\n", "\n", "\\\n", "\n", "Pour créer des images à partir d'une vidéo / to create pitcures from a video : `ffmpeg -i mavideo.mp4 -vf fps=10 image_%d.jpg`" ] }, { "cell_type": "code", "metadata": { "id": "JZvB0xguzszw", "colab_type": "code", "colab": {} }, "source": [ "import numpy as np\n", "import os\n", "from matplotlib import pyplot as plt\n", "import cv2\n", "import random\n", "import pickle\n", "\n", "file_list = []\n", "class_list = []\n", "\n", "DATASETDIR = '/dataset_des/'\n", "DATADIR = '/dataset_des/data'\n", "\n", "# Catégories / categories\n", "CATEGORIES = []\n", "for dir in sorted(os.listdir(DATADIR)):\n", " CATEGORIES.append(dir)\n", "\n", "print(CATEGORIES)\n", "\n", "# Taille des images / size of the images\n", "IMG_SIZE = 50" ], "execution_count": 0, "outputs": [] }, { "cell_type": "code", "metadata": { "id": "ImA8jr87a0pX", "colab_type": "code", "colab": {} }, "source": [ "for category in CATEGORIES :\n", "\tpath = os.path.join(DATADIR, category)\n", "\tfor img in os.listdir(path):\n", "\t\timg_array = cv2.imread(os.path.join(path, img), cv2.IMREAD_GRAYSCALE)\n", "\n", "training_data = []\n", "\n", "def create_training_data():\n", "\tfor category in CATEGORIES :\n", "\t\tpath = os.path.join(DATADIR, category)\n", "\t\tclass_num = CATEGORIES.index(category)\n", "\t\tfor img in os.listdir(path):\n", "\t\t\ttry :\n", "\t\t\t\timg_array = cv2.imread(os.path.join(path, img), cv2.IMREAD_GRAYSCALE)\n", "\t\t\t\tnew_array = cv2.resize(img_array, (IMG_SIZE, IMG_SIZE))\n", "\t\t\t\ttraining_data.append([new_array, class_num])\n", "\t\t\texcept Exception as e:\n", "\t\t\t\tpass\n", "\n", "create_training_data()\n", "\n", "random.shuffle(training_data)\n", "\n", "X = []\n", "y = []\n", "\n", "for features, label in training_data:\n", "\tX.append(features)\n", "\ty.append(label)\n", "\n", "X = np.array(X).reshape(-1, IMG_SIZE, IMG_SIZE, 1)\n", "\n", "pickle_out = open(os.path.join(DATASETDIR, \"X.pickle\"), \"wb\")\n", "pickle.dump(X, pickle_out)\n", "pickle_out.close()\n", "\n", "pickle_out = open(os.path.join(DATASETDIR, \"y.pickle\"), \"wb\")\n", "pickle.dump(y, pickle_out)\n", "pickle_out.close()" ], "execution_count": 0, "outputs": [] }, { "cell_type": "code", "metadata": { "id": "dwH91HQrdwXE", "colab_type": "code", "colab": {} }, "source": [ "import tensorflow as tf \n", "from tensorflow.keras.models import Sequential\n", "from tensorflow.keras.layers import Dense, Dropout, Activation, Flatten, Conv2D, MaxPooling2D\n", "import pickle\n", "from keras.models import model_from_json\n", "from keras.models import load_model\n", "import matplotlib.pyplot as plt\n", "\n", "X = pickle.load(open(os.path.join(DATASETDIR, \"X.pickle\"), \"rb\"))\n", "y = pickle.load(open(os.path.join(DATASETDIR, \"y.pickle\"), \"rb\"))\n", "\n", "X = X/255.0\n", "\n", "# Construction du modèle / building the model\n", "model = Sequential()\n", "\n", "model.add(Conv2D(32, (3, 3), input_shape = X.shape[1:]))\n", "model.add(Activation(\"relu\"))\n", "model.add(MaxPooling2D(pool_size=(2,2)))\n", "\n", "model.add(Conv2D(64, (3, 3)))\n", "model.add(Activation(\"relu\"))\n", "model.add(MaxPooling2D(pool_size=(2,2)))\n", "\n", "model.add(Conv2D(64, (3, 3)))\n", "model.add(Activation(\"relu\"))\n", "model.add(MaxPooling2D(pool_size=(2,2)))\n", "model.add(Dropout(0.25))\n", "\n", "model.add(Flatten())\n", "model.add(Dense(128))\n", "model.add(Activation(\"relu\"))\n", "\n", "model.add(Dense(128))\n", "model.add(Activation(\"relu\"))\n", "\n", "model.add(Dense(len(CATEGORIES)))\n", "model.add(Activation(\"softmax\"))\n", "\n", "# Compilation du modèle / compiling the model\n", "model.compile(loss=\"sparse_categorical_crossentropy\",\n", "\t\t\t\toptimizer=\"adam\",\n", "\t\t\t\tmetrics=[\"accuracy\"])\n", "\n", "# Entrainement du modèle / training the model (80% - 20%)\n", "history = model.fit(X, y, batch_size=32, epochs=10, validation_split=0.2)\n", "\n", "# Sauvegarde du modèle / saving the model\n", "model_json = model.to_json()\n", "with open(os.path.join(DATASETDIR, \"model.json\"), \"w\") as json_file :\n", "\tjson_file.write(model_json)\n", "\n", "model.save_weights(os.path.join(DATASETDIR, \"model.h5\"))\n", "print(\"Saved model to disk\")\n", "\n", "model.save(os.path.join(DATASETDIR, \"model\"))\n", "\n", "print(history.history.keys())\n", "plt.figure(1)\n", "plt.plot(history.history['acc'])\n", "plt.plot(history.history['val_acc'])\n", "plt.title('model accuracy')\n", "plt.ylabel('accuracy')\n", "plt.xlabel('epoch')\n", "plt.legend(['train', 'validation'], loc='lower right')" ], "execution_count": 0, "outputs": [] }, { "cell_type": "code", "metadata": { "id": "HkHxgS_Xbkds", "colab_type": "code", "colab": {} }, "source": [ "import cv2\n", "import tensorflow as tf\n", "from keras.models import load_model\n", "import pickle\n", "from google.colab.patches import cv2_imshow\n", "import matplotlib.pyplot as plt\n", "import numpy as np\n", "\n", "model = tf.keras.models.load_model(os.path.join(DATASETDIR, \"model\"))" ], "execution_count": 0, "outputs": [] }, { "cell_type": "code", "metadata": { "id": "Ha3Rvg-_uNju", "colab_type": "code", "colab": {} }, "source": [ "def prepare(file):\n", " IMG_SIZE = 50\n", " img_array = cv2.imread(file, cv2.IMREAD_GRAYSCALE)\n", " img_array.astype('float32')\n", " img_array = img_array / 255\n", " new_array = cv2.resize(img_array, (IMG_SIZE, IMG_SIZE))\n", " return new_array.reshape(-1, IMG_SIZE, IMG_SIZE, 1)\n", "\n", "# Tests et résultats / tests and results\n", "image = os.path.join(DATASETDIR, \"tests/de_2.jpg\")\n", "\n", "prediction = model.predict([prepare(image)])\n", "prediction_list = list(prediction[0])\n", "\n", "for n in range(len(prediction_list)):\n", " print(f'{CATEGORIES[n]} : {prediction_list[n]*100:.2f} %')\n", "\n", "print('Valeur du dé : ', CATEGORIES[prediction_list.index(max(prediction_list))])\n", "\n", "fig = plt.figure()\n", "fig.set_figwidth(6)\n", "fig.set_figheight(3)\n", "\n", "plt.subplot(1,2,1)\n", "plt.imshow(cv2.imread(image))\n", "plt.gca().set_aspect('equal', adjustable='datalim')\n", "\n", "plt.subplot(1,2,2)\n", "pourcents = [n * 100 for n in prediction_list]\n", "plt.barh(CATEGORIES, pourcents, align='center', color='#2980b9')\n", "plt.xlim((0,100))\n", "for i, v in enumerate(pourcents):\n", " if v > 70:\n", " plt.text(v-20, i-0.1, f'{v:.1f} %', color='white', fontsize=8)\n", " else :\n", " plt.text(v+4, i-0.1, f'{v:.1f} %', color='#7f8c8d', fontsize=8)\n", "\n", "plt.tight_layout()\n", "plt.show()" ], "execution_count": 0, "outputs": [] } ] }