├── .ipynb_checkpoints ├── Untitled-checkpoint.ipynb └── model-checkpoint.ipynb ├── Demo.gif ├── Gesture_Recognize_sign.py ├── Image_capturing.py ├── Image_preprocessing.py ├── LICENSE ├── README.md ├── model.ipynb ├── new_model6.h5 └── sample.jpg /.ipynb_checkpoints/Untitled-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [], 3 | "metadata": {}, 4 | "nbformat": 4, 5 | "nbformat_minor": 2 6 | } 7 | -------------------------------------------------------------------------------- /.ipynb_checkpoints/model-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 19, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "import numpy as np\n", 10 | "from keras.layers import Conv2D, Dense, Flatten, Dropout, MaxPooling2D\n", 11 | "from keras.models import Sequential, save_model\n", 12 | "from keras.utils import np_utils\n", 13 | "from keras.callbacks import ModelCheckpoint\n", 14 | "from sklearn.model_selection import train_test_split\n", 15 | "from sklearn.utils import shuffle\n", 16 | "import os\n", 17 | "import cv2" 18 | ] 19 | }, 20 | { 21 | "cell_type": "code", 22 | "execution_count": 20, 23 | "metadata": {}, 24 | "outputs": [], 25 | "source": [ 26 | "path = '/Sign_Language_Recognition/preprocessed_new/'" 27 | ] 28 | }, 29 | { 30 | "cell_type": "code", 31 | "execution_count": 21, 32 | "metadata": {}, 33 | "outputs": [], 34 | "source": [ 35 | "gestures = os.listdir(path)" 36 | ] 37 | }, 38 | { 39 | "cell_type": "code", 40 | "execution_count": 22, 41 | "metadata": {}, 42 | "outputs": [], 43 | "source": [ 44 | "dict_labels = {\n", 45 | " 'A': 1,\n", 46 | " 'B': 2,\n", 47 | " 'C':3,\n", 48 | " 'D':4,\n", 49 | " 'E':5,\n", 50 | " 'F':6,\n", 51 | " 'G':7,\n", 52 | " 'H':8,\n", 53 | " 'I':9,\n", 54 | " 'K':10,\n", 55 | " 'L':11,\n", 56 | " 'M':12,\n", 57 | " 'N':13,\n", 58 | " 'O':14,\n", 59 | " 'P':15,\n", 60 | " 'Q':16,\n", 61 | " 'R':17,\n", 62 | " 'S':18,\n", 63 | " 'T':19,\n", 64 | " 'U':20,\n", 65 | " 'V':21,\n", 66 | " 'W':22,\n", 67 | " 'X':23,\n", 68 | " 'Y':24,\n", 69 | " \n", 70 | "}" 71 | ] 72 | }, 73 | { 74 | "cell_type": "code", 75 | "execution_count": 23, 76 | "metadata": {}, 77 | "outputs": [ 78 | { 79 | "name": "stdout", 80 | "output_type": "stream", 81 | "text": [ 82 | "['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y']\n" 83 | ] 84 | } 85 | ], 86 | "source": [ 87 | "print(list(dict_labels.keys()))" 88 | ] 89 | }, 90 | { 91 | "cell_type": "code", 92 | "execution_count": 24, 93 | "metadata": {}, 94 | "outputs": [], 95 | "source": [ 96 | "x, y = [], []\n", 97 | "for ix in gestures:\n", 98 | " images = os.listdir(path + ix)\n", 99 | " for cx in images:\n", 100 | " img_path = path + ix + '/' + cx\n", 101 | " img = cv2.imread(img_path, 0)\n", 102 | " img = img.reshape((50,50,1))\n", 103 | " img = img/255.0\n", 104 | " x.append(img)\n", 105 | " y.append(dict_labels[ix])" 106 | ] 107 | }, 108 | { 109 | "cell_type": "code", 110 | "execution_count": 25, 111 | "metadata": {}, 112 | "outputs": [], 113 | "source": [ 114 | "X = np.array(x)\n", 115 | "Y = np.array(y)\n", 116 | "Y = np_utils.to_categorical(Y)\n" 117 | ] 118 | }, 119 | { 120 | "cell_type": "code", 121 | "execution_count": 29, 122 | "metadata": {}, 123 | "outputs": [], 124 | "source": [ 125 | "import seaborn as sns\n", 126 | "import matplotlib.pyplot as plt" 127 | ] 128 | }, 129 | { 130 | "cell_type": "code", 131 | "execution_count": 30, 132 | "metadata": {}, 133 | "outputs": [ 134 | { 135 | "data": { 136 | "text/plain": [ 137 | "" 138 | ] 139 | }, 140 | "execution_count": 30, 141 | "metadata": {}, 142 | "output_type": "execute_result" 143 | }, 144 | { 145 | "data": { 146 | "image/png": "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\n", 147 | "text/plain": [ 148 | "
" 149 | ] 150 | }, 151 | "metadata": { 152 | "needs_background": "light" 153 | }, 154 | "output_type": "display_data" 155 | } 156 | ], 157 | "source": [ 158 | "plt.figure(figsize = (18,8))\n", 159 | "sns.countplot(x=list(dict_labels.keys()))" 160 | ] 161 | }, 162 | { 163 | "cell_type": "code", 164 | "execution_count": null, 165 | "metadata": {}, 166 | "outputs": [], 167 | "source": [] 168 | }, 169 | { 170 | "cell_type": "code", 171 | "execution_count": null, 172 | "metadata": {}, 173 | "outputs": [], 174 | "source": [] 175 | }, 176 | { 177 | "cell_type": "code", 178 | "execution_count": 33, 179 | "metadata": {}, 180 | "outputs": [ 181 | { 182 | "data": { 183 | "text/plain": [ 184 | "(28800, 25)" 185 | ] 186 | }, 187 | "execution_count": 33, 188 | "metadata": {}, 189 | "output_type": "execute_result" 190 | } 191 | ], 192 | "source": [ 193 | "Y.shape" 194 | ] 195 | }, 196 | { 197 | "cell_type": "code", 198 | "execution_count": 34, 199 | "metadata": {}, 200 | "outputs": [], 201 | "source": [ 202 | "categories = Y.shape[1]" 203 | ] 204 | }, 205 | { 206 | "cell_type": "code", 207 | "execution_count": 35, 208 | "metadata": {}, 209 | "outputs": [], 210 | "source": [ 211 | "X, Y = shuffle(X, Y, random_state=0)" 212 | ] 213 | }, 214 | { 215 | "cell_type": "code", 216 | "execution_count": 36, 217 | "metadata": {}, 218 | "outputs": [ 219 | { 220 | "data": { 221 | "text/plain": [ 222 | "(28800, 50, 50, 1)" 223 | ] 224 | }, 225 | "execution_count": 36, 226 | "metadata": {}, 227 | "output_type": "execute_result" 228 | } 229 | ], 230 | "source": [ 231 | "X.shape" 232 | ] 233 | }, 234 | { 235 | "cell_type": "code", 236 | "execution_count": 95, 237 | "metadata": {}, 238 | "outputs": [], 239 | "source": [ 240 | "X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.3)" 241 | ] 242 | }, 243 | { 244 | "cell_type": "code", 245 | "execution_count": 96, 246 | "metadata": {}, 247 | "outputs": [ 248 | { 249 | "name": "stdout", 250 | "output_type": "stream", 251 | "text": [ 252 | "(20160, 50, 50, 1) (8640, 50, 50, 1)\n", 253 | "(20160, 25) (8640, 25)\n" 254 | ] 255 | } 256 | ], 257 | "source": [ 258 | "print(X_train.shape, X_test.shape)\n", 259 | "print(Y_train.shape, Y_test.shape)" 260 | ] 261 | }, 262 | { 263 | "cell_type": "code", 264 | "execution_count": 97, 265 | "metadata": {}, 266 | "outputs": [ 267 | { 268 | "name": "stdout", 269 | "output_type": "stream", 270 | "text": [ 271 | "_________________________________________________________________\n", 272 | "Layer (type) Output Shape Param # \n", 273 | "=================================================================\n", 274 | "conv2d_13 (Conv2D) (None, 48, 48, 64) 640 \n", 275 | "_________________________________________________________________\n", 276 | "max_pooling2d_11 (MaxPooling (None, 24, 24, 64) 0 \n", 277 | "_________________________________________________________________\n", 278 | "conv2d_14 (Conv2D) (None, 22, 22, 64) 36928 \n", 279 | "_________________________________________________________________\n", 280 | "max_pooling2d_12 (MaxPooling (None, 11, 11, 64) 0 \n", 281 | "_________________________________________________________________\n", 282 | "conv2d_15 (Conv2D) (None, 9, 9, 64) 36928 \n", 283 | "_________________________________________________________________\n", 284 | "max_pooling2d_13 (MaxPooling (None, 4, 4, 64) 0 \n", 285 | "_________________________________________________________________\n", 286 | "flatten_5 (Flatten) (None, 1024) 0 \n", 287 | "_________________________________________________________________\n", 288 | "dense_8 (Dense) (None, 128) 131200 \n", 289 | "_________________________________________________________________\n", 290 | "dropout_5 (Dropout) (None, 128) 0 \n", 291 | "_________________________________________________________________\n", 292 | "dense_9 (Dense) (None, 25) 3225 \n", 293 | "=================================================================\n", 294 | "Total params: 208,921\n", 295 | "Trainable params: 208,921\n", 296 | "Non-trainable params: 0\n", 297 | "_________________________________________________________________\n" 298 | ] 299 | } 300 | ], 301 | "source": [ 302 | "model = Sequential()\n", 303 | "model.add(Conv2D(64, kernel_size=(3,3), activation = 'relu', input_shape=(50,50 ,1) ))\n", 304 | "model.add(MaxPooling2D(pool_size = (2, 2)))\n", 305 | "\n", 306 | "model.add(Conv2D(64, kernel_size = (3, 3), activation = 'relu'))\n", 307 | "model.add(MaxPooling2D(pool_size = (2, 2)))\n", 308 | "\n", 309 | "model.add(Conv2D(64, kernel_size = (3, 3), activation = 'relu'))\n", 310 | "model.add(MaxPooling2D(pool_size = (2, 2)))\n", 311 | "\n", 312 | "model.add(Flatten())\n", 313 | "model.add(Dense(128, activation = 'relu'))\n", 314 | "model.add(Dropout(0.20))\n", 315 | "model.add(Dense(categories, activation = 'softmax'))\n", 316 | "\n", 317 | "model.summary()" 318 | ] 319 | }, 320 | { 321 | "cell_type": "code", 322 | "execution_count": 98, 323 | "metadata": {}, 324 | "outputs": [], 325 | "source": [ 326 | "model.compile(optimizer='Adam', metrics=['accuracy'], loss='categorical_crossentropy')" 327 | ] 328 | }, 329 | { 330 | "cell_type": "code", 331 | "execution_count": 99, 332 | "metadata": {}, 333 | "outputs": [ 334 | { 335 | "name": "stdout", 336 | "output_type": "stream", 337 | "text": [ 338 | "Train on 20160 samples, validate on 8640 samples\n", 339 | "Epoch 1/50\n", 340 | "20160/20160 [==============================] - 28s 1ms/step - loss: 0.7853 - acc: 0.7698 - val_loss: 0.1140 - val_acc: 0.9664\n", 341 | "Epoch 2/50\n", 342 | "20160/20160 [==============================] - 26s 1ms/step - loss: 0.1139 - acc: 0.9658 - val_loss: 0.0481 - val_acc: 0.9873\n", 343 | "Epoch 3/50\n", 344 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0671 - acc: 0.9788 - val_loss: 0.0381 - val_acc: 0.9891\n", 345 | "Epoch 4/50\n", 346 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0467 - acc: 0.9854 - val_loss: 0.0245 - val_acc: 0.9936\n", 347 | "Epoch 5/50\n", 348 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0292 - acc: 0.9911 - val_loss: 0.0291 - val_acc: 0.9926\n", 349 | "Epoch 6/50\n", 350 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0291 - acc: 0.9910 - val_loss: 0.0155 - val_acc: 0.9953\n", 351 | "Epoch 7/50\n", 352 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0248 - acc: 0.9919 - val_loss: 0.0130 - val_acc: 0.9957\n", 353 | "Epoch 8/50\n", 354 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0231 - acc: 0.9920 - val_loss: 0.0138 - val_acc: 0.9962\n", 355 | "Epoch 9/50\n", 356 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0149 - acc: 0.9951 - val_loss: 0.0116 - val_acc: 0.9966\n", 357 | "Epoch 10/50\n", 358 | "20160/20160 [==============================] - 28s 1ms/step - loss: 0.0160 - acc: 0.9942 - val_loss: 0.0140 - val_acc: 0.9961\n", 359 | "Epoch 11/50\n", 360 | "20160/20160 [==============================] - 28s 1ms/step - loss: 0.0122 - acc: 0.9959 - val_loss: 0.0118 - val_acc: 0.9968\n", 361 | "Epoch 12/50\n", 362 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0116 - acc: 0.9962 - val_loss: 0.0121 - val_acc: 0.9966\n", 363 | "Epoch 13/50\n", 364 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0105 - acc: 0.9965 - val_loss: 0.0109 - val_acc: 0.9970\n", 365 | "Epoch 14/50\n", 366 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0095 - acc: 0.9966 - val_loss: 0.0110 - val_acc: 0.9968\n", 367 | "Epoch 15/50\n", 368 | "20160/20160 [==============================] - 26s 1ms/step - loss: 0.0108 - acc: 0.9959 - val_loss: 0.0132 - val_acc: 0.9962\n", 369 | "Epoch 16/50\n", 370 | "20160/20160 [==============================] - 26s 1ms/step - loss: 0.0103 - acc: 0.9967 - val_loss: 0.0067 - val_acc: 0.9980\n", 371 | "Epoch 17/50\n", 372 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0087 - acc: 0.9975 - val_loss: 0.0086 - val_acc: 0.9971\n", 373 | "Epoch 18/50\n", 374 | "20160/20160 [==============================] - 26s 1ms/step - loss: 0.0053 - acc: 0.9981 - val_loss: 0.0100 - val_acc: 0.9976\n", 375 | "Epoch 19/50\n", 376 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0066 - acc: 0.9978 - val_loss: 0.0061 - val_acc: 0.9983\n", 377 | "Epoch 20/50\n", 378 | "20160/20160 [==============================] - 26s 1ms/step - loss: 0.0092 - acc: 0.9966 - val_loss: 0.0106 - val_acc: 0.9966\n", 379 | "Epoch 21/50\n", 380 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0073 - acc: 0.9977 - val_loss: 0.0149 - val_acc: 0.9957\n", 381 | "Epoch 22/50\n", 382 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0062 - acc: 0.9982 - val_loss: 0.0087 - val_acc: 0.9977\n", 383 | "Epoch 23/50\n", 384 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0032 - acc: 0.9989 - val_loss: 0.0074 - val_acc: 0.9977\n", 385 | "Epoch 24/50\n", 386 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0059 - acc: 0.9980 - val_loss: 0.0087 - val_acc: 0.9969\n", 387 | "Epoch 25/50\n", 388 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0087 - acc: 0.9971 - val_loss: 0.0134 - val_acc: 0.9963\n", 389 | "Epoch 26/50\n", 390 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0065 - acc: 0.9981 - val_loss: 0.0090 - val_acc: 0.9972\n", 391 | "Epoch 27/50\n", 392 | "20160/20160 [==============================] - 26s 1ms/step - loss: 0.0030 - acc: 0.9988 - val_loss: 0.0139 - val_acc: 0.9968\n", 393 | "Epoch 28/50\n", 394 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0075 - acc: 0.9976 - val_loss: 0.0086 - val_acc: 0.9976\n", 395 | "Epoch 29/50\n", 396 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0042 - acc: 0.9986 - val_loss: 0.0090 - val_acc: 0.9978\n", 397 | "Epoch 30/50\n", 398 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0049 - acc: 0.9984 - val_loss: 0.0184 - val_acc: 0.9959\n", 399 | "Epoch 31/50\n", 400 | "20160/20160 [==============================] - 26s 1ms/step - loss: 0.0089 - acc: 0.9970 - val_loss: 0.0061 - val_acc: 0.9983\n", 401 | "Epoch 32/50\n", 402 | "20160/20160 [==============================] - 26s 1ms/step - loss: 0.0027 - acc: 0.9992 - val_loss: 0.0058 - val_acc: 0.9981\n", 403 | "Epoch 33/50\n", 404 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0026 - acc: 0.9991 - val_loss: 0.0090 - val_acc: 0.9976\n", 405 | "Epoch 34/50\n", 406 | "20160/20160 [==============================] - 26s 1ms/step - loss: 0.0029 - acc: 0.9990 - val_loss: 0.0107 - val_acc: 0.9976\n", 407 | "Epoch 35/50\n", 408 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0048 - acc: 0.9985 - val_loss: 0.0102 - val_acc: 0.9973\n", 409 | "Epoch 36/50\n", 410 | "20160/20160 [==============================] - 26s 1ms/step - loss: 0.0029 - acc: 0.9990 - val_loss: 0.0096 - val_acc: 0.9980\n", 411 | "Epoch 37/50\n", 412 | "20160/20160 [==============================] - 26s 1ms/step - loss: 0.0043 - acc: 0.9986 - val_loss: 0.0061 - val_acc: 0.9987\n", 413 | "Epoch 38/50\n", 414 | "20160/20160 [==============================] - 26s 1ms/step - loss: 0.0018 - acc: 0.9995 - val_loss: 0.0062 - val_acc: 0.9986\n", 415 | "Epoch 39/50\n", 416 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0024 - acc: 0.9992 - val_loss: 0.0059 - val_acc: 0.9986\n", 417 | "Epoch 40/50\n", 418 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0055 - acc: 0.9981 - val_loss: 0.0073 - val_acc: 0.9973\n", 419 | "Epoch 41/50\n", 420 | "20160/20160 [==============================] - 28s 1ms/step - loss: 0.0055 - acc: 0.9980 - val_loss: 0.0113 - val_acc: 0.9971\n", 421 | "Epoch 42/50\n", 422 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0021 - acc: 0.9995 - val_loss: 0.0073 - val_acc: 0.9983\n", 423 | "Epoch 43/50\n", 424 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0066 - acc: 0.9977 - val_loss: 0.0139 - val_acc: 0.9970\n", 425 | "Epoch 44/50\n", 426 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0031 - acc: 0.9989 - val_loss: 0.0096 - val_acc: 0.9980\n", 427 | "Epoch 45/50\n", 428 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0024 - acc: 0.9990 - val_loss: 0.0111 - val_acc: 0.9980\n", 429 | "Epoch 46/50\n", 430 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0029 - acc: 0.9991 - val_loss: 0.0052 - val_acc: 0.9986\n", 431 | "Epoch 47/50\n", 432 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0034 - acc: 0.9988 - val_loss: 0.0268 - val_acc: 0.9921\n", 433 | "Epoch 48/50\n", 434 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0055 - acc: 0.9978 - val_loss: 0.0141 - val_acc: 0.9971\n", 435 | "Epoch 49/50\n", 436 | "20160/20160 [==============================] - 26s 1ms/step - loss: 0.0030 - acc: 0.9993 - val_loss: 0.0124 - val_acc: 0.9972\n", 437 | "Epoch 50/50\n", 438 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0024 - acc: 0.9991 - val_loss: 0.0064 - val_acc: 0.9983\n" 439 | ] 440 | } 441 | ], 442 | "source": [ 443 | "history = model.fit(X_train, Y_train, batch_size=128, epochs=50, validation_data=[X_test, Y_test])" 444 | ] 445 | }, 446 | { 447 | "cell_type": "code", 448 | "execution_count": 100, 449 | "metadata": {}, 450 | "outputs": [], 451 | "source": [ 452 | "import matplotlib.pyplot as plt\n", 453 | "%matplotlib inline" 454 | ] 455 | }, 456 | { 457 | "cell_type": "code", 458 | "execution_count": 101, 459 | "metadata": {}, 460 | "outputs": [ 461 | { 462 | "data": { 463 | "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYsAAAEWCAYAAACXGLsWAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4zLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvIxREBQAAIABJREFUeJzt3XmcXFWZ//HPU0vvnd6zkM7ShMUgYJBMQAFFHBVQWdRxEHFwm8w46A9/Iyr4cxmZYYZ5OeM2ozLOTBQVwQiijOKwGXABhQQCJAHMAiSdkKTTne70UtVdy/P7495OKt3V6UroSiXd3/frVa+qu9a5lc597jnPveeYuyMiInIgkVIXQEREjnwKFiIiMi4FCxERGZeChYiIjEvBQkRExqVgISIi41KwEBGRcSlYyJRnZg+a2W4zKy91WUSOVAoWMqWZ2XzgHMCBiw7j98YO13eJTAQFC5nq/gL4PfBd4MrhmWZWaWb/amYvmlmPmf3WzCrDZWeb2cNm1m1mW8zs/eH8B83swzn7eL+Z/TZn2s3sKjNbD6wP530t3MceM1tlZufkrB81s8+Y2UYz6w2XzzGzb5jZv+YehJn9j5l9vBg/kAgoWIj8BXBL+HqLmc0I5/8LcDrwWqAR+BSQNbO5wC+BfwNagEXA6oP4vkuAM4CTwunHwn00Aj8EfmxmFeGyvwXeA1wITAM+CAwANwPvMbMIgJk1A28Ebj2YAxc5GAoWMmWZ2dnAPGC5u68CNgKXhyfhDwJXu/tWd8+4+8PuPgi8F7jf3W9195S7d7r7wQSLf3L3LndPALj7D8J9pN39X4Fy4MRw3Q8Dn3X35zzwZLjuo0APQYAAuAx40N13vMyfRGRMChYylV0J3Ovuu8LpH4bzmoEKguAx0pwx5hdqS+6EmX3CzJ4Jm7q6gbrw+8f7rpuBK8LPVwDffxllEhmXkmwyJYX5h3cDUTPbHs4uB+qBWUASWAA8OWLTLcCSMXbbD1TlTM/Ms87ebp7D/MSnCWoIa909a2a7Acv5rgXAmjz7+QGwxsxeBSwEfjpGmUQmhGoWMlVdAmQIcgeLwtdC4DcEeYxlwJfN7Jgw0fya8NbaW4A/NbN3m1nMzJrMbFG4z9XAO8ysysyOAz40ThlqgTTQAcTM7PMEuYlh/wX8vZkdb4FTzawJwN3bCfId3wfuGG7WEikWBQuZqq4EvuPum919+/AL+HeCvMS1wNMEJ+Qu4J+BiLtvJkg4fyKcvxp4VbjPrwBDwA6CZqJbxinDPQTJ8j8CLxLUZnKbqb4MLAfuBfYA/w1U5iy/GTgFNUHJYWAa/Ejk6GRmryNojprv7tlSl0cmN9UsRI5CZhYHrgb+S4FCDgcFC5GjjJktBLoJEvFfLXFxZIpQM5SIiIxLNQsRERnXpHnOorm52efPn1/qYoiIHFVWrVq1y91bxltv0gSL+fPns3LlylIXQ0TkqGJmLxaynpqhRERkXAoWIiIyLgULEREZl4KFiIiMS8FCRETGVbRgYWbLzGynmeXrXpmwF82vm9kGM3vKzF6ds+xKM1sfvq7Mt72IiBw+xaxZfBc4/wDLLwCOD19LgW8BmFkj8AWCoSeXAF8ws4YillNERMZRtOcs3P3XZjb/AKtcDHzPg/5Gfm9m9WY2CzgXuM/duwDM7D6CoKPxhUWKoLNvkPU7+4hGjIgZsYgRDV+xiBGLRohFjHg0QjwaTJdFI1TEI5jZ+F8AZLJO1p14dOzr01Qmy449SV7qSbKtO8HOPYPEo0ZlWZTKshiV8ShVZcFrdn0lLbXlBX9/LndnS1eCJ7bsZntPklfNqWfRnHoq4tGD2k8m66QyWdJZJ5XOknHHPdh/1iHrjhOMZFUei1ARj1IRjxKNHHyZO/sGeXprD8lUhrJYhLJoNHiPBf8WtRUx5jRWjb+jl6GUD+XNZv+++9vDeWPNH8XMlhLUSpg7d25xSikTL5uFXc8BBvVzoSz/H7m7MzCUoat/iM7+IQYG05THItTQR81QF1VDHZQPdlCe7ic66xSYtQjiFQUVIZ3J0jeYZk8izZ5kij2JFHuSKbr6U+zsTdLRO8jO8LWrd5D+oTSz6ippbahkdn3w3tpQFb5XUlcZP+CJy93ZPZDixc5+tnUn2bFn32v7niQ79wyScef46bWcOLOGE2bUcsKMWo5tqaY8FmUonWVrd4IXO/vZ3DXAi7v62LG7l7SVURaLUD584ghfrQ1VnDSrllfMnEZ1eQyGBmDTCujejFuUnf0Z1u0YYM1LfWzsTJLwMnZ7LV3U0uXT6KaG7DgND9GIUVsRY1pFnGmVwXttRYxM1vf+rv2JQWLJTqqGOmmx3RwT7eGY2B5mRXqYYd00WTfV2X6GskYyY6SJECHKTKK0eARn9G/aD6zwFp6PzqO37gSYfhItM1s5tqWGxqqyvYFuONhFI8auvkFWb+nmyS3drN3SSW1iC8fZNppsDyt8Fpsi82ibM4czjm3izGMbWTSnnl29Q2zs6GPDzj42dvSxfcdLpHdtIjuUIJ0NAsMww6myQRrZQ4P10mS9NNBLk+1huzfyj+nLSVIOQCxiVMSjVJdHaW2oYl5jFfOaqpnXVMXcpipm1VXwfEc/T7b38FR7N0+197C1e+TYVk4Te5hv22mLbGdW4zQ+8YnPFvS3f6iK2pFgWLP4ubufnGfZLwgGr/9tOP0A8CngPKDc3f8hnP85YCAczH5Mixcv9in9BHc2C9kUxMoLWz+VhP6dkE1DJDb6lU3DUB8M9cNg377PmSGIVQTfE6sIXvEKiFdCZSNU1MHIk6Y7dG6A5x+C53+Dv/AbbKBz7+JEWSPdZcewIzqDdm+hM1VGdGgPZak9VHsfdfQzzQZooI8W66bCUnkPKU2MHdUn0jf9NGLzzqThxLPptCY27hpg064+nu/oZ9Oufp7f1U9X/xAA5QxxeuSPnBN5mnMiTzPXdgBgZkQIDsXMyFqMrkgT27yRF1L1bE43st0b2UYTnT6NwbIGqutamNVYy+yGSmbVVdKTSLGls5feXe3Y7hdpTG1njnUQtzQ9Xs2AVWNV9cSrGyivaQp+i84XsT3bmEEns6yTWdbFzEgPcR+ijCEqSFHOEGWWAeCFyBwej5zCY5zMH3whHZlqBlNZhjJZahngvOgTvKPicc7MPkG5Jwv+c3KMVFkdQ/E63KI44VVzsBDHSRFjiDKSHicRvgayUao9QTPdNHoXtZkeIozuQX0gUkNPtIndkXr6IrVUxIzqGFTGnMqoUx7JUhbx/a7Ss1kPrt4zGcp6X6ByaPfe/XV4Hc9m57CDRgY9ziD7Xkkvo9qSHGdbOSm+ndbsNqJkRpWp05pYk5nNs9k5vOAzaaGH+ZHttNl22iI7qKe34N8vazEGyxoYLKtnWu9GdtWdzC9P/grdVkcynSGZytCbTLOla4DNXQO81BP825SR4uLo72iglxgZmqqizKqNMas2xozqGNWDO4j3PE9ZzwvEUvvK09dwEjVXP1Jw+XKZ2Sp3XzzueiUMFv8BPOjut4bTzxE0QZ0LnOvuf5VvvbFMimCRSkKyB5LdwXuiO2c637yeffMG94BnIVYJ1c1Q1QhVzVDVBJX1kNgNfTugdwfetx1L9hTlENJE6YvUMRCvZ6isAS+roXnPOmpTHQDssGYezpzE7zILGfIYc6yDObaT1kgH8yO7mMkuYmRIWRnJ2DRS8Vqy5dOgoh6vqCdR3kx/vJneeCM90SZ6og10peL4S0/S0LmatuRaTmHj3oDS5xW0ewtbvIXO+EwGa+YQaZjLvMgujt3zKDN3ryKWTZK1GImZi/EZJ1NZFh/dVJBOwp6XYE873rMVS3TlPf5eq6bTp9GVrabB+phtuygjvd86jmEc+P+dR2IkyqfTFWthlzUQK6+hsqqK6upaamuqqaqqDq652x+DFx+BVD9gMPMUfN5rGdzxR8o2/4ZINkV3tIkVtoQfD5zGejuWM9vqeP1xjZy9oJ6Z1VHIZiA1AAOd+179u4L3xG7IV1b34IIilYD0YPD7pAchnYCyaqiZCTXToXYm1MwIXns/Tw8uLl6uvp2wYy3sWEt6+xpSL60hMtCFZQaJDL+ywUWBWxRvaCMy/RXQfAK0nBi8VzfDrj/CjnWwcx2Z7Wug4zmi4XaD1ccQaVpAvOU4aFoADW1QXpO/PPGq4P9bdTOUT9t30fTM/8DtHwpq0VfcAQ3zRm2aTGXYuX4lDfd8jNqe50bvOxIPLuJqpgflaFyw/3v9XIjGD+lnPBqCxVuBjxIMUXkG8HV3XxImuFcBw3dHPQ6cPpzDGMtRFyx6t8NTy2HtnbBna3DCzwweeJt4VXDlXlEHFfXBe2U9qXgtz3ZH2LQ7TVM0QUuklzr2UJvppnyom+hQD0OxaeyONLI1M431/VVsSdWxizqGPEbcMlRGgyu6ivDKLhKNkY5Wk45XkYlV4/FqvKyaSLyMctKU+VBwhUuKMh8ilknCwC4s0UU82UV5qpuaTDc13s965rKuYhFb6hYTaWxjZn0ls6ZVMLOukhnTypkxrYKW2vKgPTuTDk5CBTYnjZTJOlt39bBz/UpSmx9jeqqdlvR2qhNbiXZvDk+qoeYTYMF5cOwbYP5ZUF5b+BcNDUDvS8G/3fCJNedEm+7vJFLVSKRhLtTPC04Q9fOhrhWiZTDUOzr4u8O02VA3G6qnQ6TA+08yKdj6ODz/a3jh17D5DzBtFix8Oyy8CGYvhkiE3mSKaMSoKps0XcKNL5sN/l9FYoWfTDPp4N91ooIaBAH91j8PLuauuB1mnpJTxgz87muw4h+hsgHe/jU49vVhLT9e+N/BISp5sDCzWwlqCc0EYxJ/AYgDuPtNFjTw/jtB8noA+IC7rwy3/SDwmXBXN7j7d8b7viMiWOx+ATbcD9Naw2g/D2Jl+5anEvDsL+DJW2Hjr4KawOzTYcbJwdX/iCBAefheUQ8V00Y1MbXvHuD7j7zIbY9toSeRYnZ9JX2DaXoS+ZtpANqaq1k8r4HF8xs4fV4jrQ2VlMcKT1QejOGcQ1VZtCj7P4QCwUAXdL8I1S1QP6fUJSqObAYsMro5UEpr5zPwg3fCYC9cdgu0vQ66NsGdH4Etvw8C+9u+CtVNh7VYJQ8Wh1tJg0UmBY/8Ozz4z0E1fJhFgxNS44LgpL/+vqC5aForvOrP4VXvgebjC/oKD++0yLrz+OZuvvO757ln7XbMjPNfOZP3nzWfxfMaMDP6BtO81J1ga3eCl3qCZO0JM2o4fV4jLbUF5jREZOL1tAcBo2sTLP4QPP69oAZx4Zfg1HeXJMArWBwuWx6F//k47FwLr3gbnPdZSO6Bro3QuRG6NuKdG0n1bKdr5tnsWnApidmvJRaNEo9GiEaMjt5BNncNsGX3AO1dib2fe5PpvQm+keoq47xnyVze95p5zK6foKqyiBTfQBfcdjlsfgTaXg+XfDNoniyRQoPFFGq8nGCJbnjgi7DyOzDtGLjsh/CKt+5bPvcMAPYkU/ztj57k/hd2wG7gGYA/5N1lWTQS3IrZWMWprXXUV8WJmAV35hgYwfvMugreduoxVJYd3H3hInIEqGqE9/00uDlh3llFz0lMFAWLg5HNwo6nYdND8PC/wcAuOPNv4A3X5U2ObtjZx9Lvr2Rz5wD/78KFvHpePalM+CBPZt8DPc015cxprGRGbQWRQ3hgR0SOMvEKaDun1KU4KAoWB+IOHc/tu8vkhd+GtxIS3GHy3uVwzGl5N71n7XY+sfxJKuIRbvnwGZxx7OFNWomITCQFiwO55V3B3U0AdXPhxLcGdzC0nRM0PeWRzTpfuf+P/NuvNvCq1jpuet/pzKpTTkFEjm4KFmPZ+UwQKJYshddcBQ3zx92kJ5Hi47c9wYrnOviz01v5+0tOPuj+ZkREjkQKFmN5+vbgXvXXfTJ4OGccO/YkuXLZo2zY2cffX3IyV5wx98h4tkBEZAIoWOTjDmtuD25rKyBQbOro433//SjdA0N89wNLOPv45sNQSBGRw+fouGfrcNv2ePA09snvHHfVJ7d0866bHiGZynDr0jMVKERkUlLNIp+n7wj671n49gOu9tAfO/jID1bRVFPG9z54Bm3N1YepgCIih5eCxUjZDKz9CRz3pqCLjjH89ImtXPPjJzl+Ri03f+BPmD7t0Dq+ExE5GihYjLT5kaA30ZPfMeYqyx/bwqfueIoz2hr5zysXM63i0LoGFhE5WihYjPT07UFX4CdekHdxZ98g1/98Ha85tonvfOBPdGusiEwJSnDnyqRg3c/gxAuDAVzy+NoD60mkMnqGQkSmFAWLXJsehETXmHdBbdjZxy1/2MzlS+Zy3PQxRssSEZmEFCxyPX17MPDQcW/Mu/jGXz5LZTzK1X9a2BgUIiKThYLFsFQCnv15MFpVbPQAQY9s7OT+Z3bwkXMX0FyjAYREZGpRsBi2/l4Y6svbBJXNOv949zMcU1fBh85uK0HhRERKS8Fi2NO3Q/X0oFfZEe56chtPb+3hk+efqKS2iExJChYQDIP6x3vglZdCZP9gkExl+NI9z3Hy7Glc/KrZJSqgiEhpKVgAPPsLyAzCKe8atWjZ755na3eCz1y4UKPYiciUpWABsOaOYHCj1j/Zb3Zn3yDfXLGRP104ndcuUAeBIjJ1KVj0d8KmFUH3HiPGnxh+AO/aCxaWqHAiIkcGdfcRjcGb/wEWjH624oFndvKWV87QA3giMuUpWFTUwZkfybtoYChNU7WeqRARUTPUASRTWSrLdKusiIiCxRjcnUQqQ0VMP5GIiM6EYxhMZwGoUM1CRETBYizJVAaAipiChYiIgsUYkqmwZqHuPUREFCzGkghrFpVl+olERHQmHIOaoURE9lGwGMPeYKEEt4iIgsVYEqpZiIjsVdRgYWbnm9lzZrbBzK7Ns3yemT1gZk+Z2YNm1pqzLGNmq8PXXcUsZz6DexPciqciIkXr7sPMosA3gDcB7cBjZnaXu6/LWe1fgO+5+81mdh7wT8D7wmUJd19UrPKNZ1+CWzULEZFiXjYvATa4+yZ3HwJuAy4esc5JwAPh5xV5lpeMEtwiIvsUM1jMBrbkTLeH83I9CQwPen0pUGtmTeF0hZmtNLPfm9kl+b7AzJaG66zs6OiYyLKrZiEikqOYwSLfsHI+Yvoa4PVm9gTwemArkA6XzXX3xcDlwFfNbMGonbl/290Xu/vilpaWCSx6zkN5qlmIiBS1i/J2YE7OdCuwLXcFd98GvAPAzGqAd7p7T84y3H2TmT0InAZsLGJ597Pv1lkluEVEinkmfAw43szazKwMuAzY764mM2s2s+EyXAcsC+c3mFn58DrAWUBuYrzokqkMZlAWVbAQESnamdDd08BHgXuAZ4Dl7r7WzK43s4vC1c4FnjOzPwIzgBvC+QuBlWb2JEHi+8YRd1EVXTKVoSIWxSxfa5qIyNRS1JHy3P1u4O4R8z6f8/l24PY82z0MnFLMso0nkcoouS0iElIbyxiSqawGPhIRCelsOIZEKqN+oUREQgoWYxgMcxYiIqJgMaZkKquchYhISMFiDIlURp0IioiEdDYcQ1LNUCIieylYjEEJbhGRfRQsxjCYyqpmISISUrAYQ/BQnn4eERFQsBiTchYiIvsoWOTh7iTV3YeIyF4KFnkMZbJkHSriChYiIqBgkdfwwEfl6htKRARQsMgrqSFVRUT2o2CRx95R8pTgFhEBFCzySqhmISKyHwWLPIZzFuobSkQkoLNhHmqGEhHZn4JFHsPNUOobSkQkoGCRx6BqFiIi+1GwyEMJbhGR/SlY5KEEt4jI/nQ2zGPvQ3nq7kNEBFCwyGtvglvBQkQEULDIS31DiYjsT2fDPJKpDBXxCGZW6qKIiBwRFCzyCIKFmqBERIYpWOSRGMoouS0ikkPBIo9kOquahYhIDgWLPNQMJSKyv4KChZndYWZvNbMpEVyGE9wiIhIo9Iz4LeByYL2Z3WhmryhimUoumcqoXygRkRwFBQt3v9/d3wu8GngBuM/MHjazD5hZvJgFLIVEKqN+oUREchTc1mJmTcD7gQ8DTwBfIwge9xWlZCWUTGXVDCUikqPQnMVPgN8AVcDb3f0id/+Ru38MqDnAdueb2XNmtsHMrs2zfJ6ZPWBmT5nZg2bWmrPsSjNbH76uPPhDO3SJISW4RURyxQpc79/d/Vf5Frj74nzzzSwKfAN4E9AOPGZmd7n7upzV/gX4nrvfbGbnAf8EvM/MGoEvAIsBB1aF2+4usLwvy2BawUJEJFehbS0Lzax+eMLMGszsb8bZZgmwwd03ufsQcBtw8Yh1TgIeCD+vyFn+FuA+d+8KA8R9wPkFlvVlS6ayeihPRCRHocHiL929e3giPIH/5TjbzAa25Ey3h/NyPQm8M/x8KVAb5kYK2RYzW2pmK81sZUdHR0EHUoiEbp0VEdlPoWfEiOX0qhc2MZWNs02+Xvh8xPQ1wOvN7Ang9cBWIF3gtrj7t919sbsvbmlpGac4hUllsmSyrltnRURyFJqzuAdYbmY3EZy0/xr433G2aQfm5Ey3AttyV3D3bcA7AMysBninu/eYWTtw7ohtHyywrC+LhlQVERmt0JrFp4FfAR8BriLIM3xqnG0eA443szYzKwMuA+7KXcHMmnOeCr8OWBZ+vgd4c5gbaQDeHM4ruuFR8sqVsxAR2augmoW7Zwme4v5WoTt297SZfZTgJB8Flrn7WjO7Hljp7ncR1B7+ycwc+DVBIMLdu8zs7wkCDsD17t5V6He/HMmhYOAjJbhFRPYpKFiY2fEEt7WeBFQMz3f3Yw+0nbvfDdw9Yt7ncz7fDtw+xrbL2FfTOGyS6eEhVZXgFhEZVugZ8TsEtYo08Abge8D3i1WoUhpuhlLNQkRkn0KDRaW7PwCYu7/o7n8HnFe8YpVOYmi4ZqFgISIyrNC7oZJhInp9mIfYCkwvXrFKJ5kOchZqhhIR2afQM+LHCfqF+j/A6cAVwGHtr+lwUc1CRGS0cWsW4QN473b3TwJ9wAeKXqoSGkwrWIiIjDRuzcLdM8DpuU9wT2bDNQsluEVE9ik0Z/EE8DMz+zHQPzzT3X9SlFKV0PDdUKpZiIjsU2iwaAQ62f8OKAcmX7BQgltEZJRCn+Ce1HmKXHsT3OpIUERkr0Kf4P4O+Xt9/eCEl6jEkukMZbEIkciUSNGIiBSk0Gaon+d8riAYe2LbGOse1ZJDGSW3RURGKLQZ6o7caTO7Fbi/KCUqsWQqq3yFiMgIh3pWPB6YO5EFOVIkUqpZiIiMVGjOopf9cxbbCca4mHSSqYxumxURGaHQZqjaYhfkSJFMZzXwkYjICAU1Q5nZpWZWlzNdb2aXFK9YpRMkuJWzEBHJVehZ8Qvu3jM84e7dwBeKU6TSSqbVDCUiMlKhwSLfeoXedntUSejWWRGRUQoNFivN7MtmtsDMjjWzrwCrilmwUlHNQkRktEKDxceAIeBHwHIgAVxVrEKVUvCchYKFiEiuQu+G6geuLXJZjgjJoYweyhMRGaHQu6HuM7P6nOkGM7uneMUqHTVDiYiMVugldHN4BxQA7r6bSTgGdzqTJZVxJbhFREYoNFhkzWxv9x5mNp88vdAe7TSWhYhIfoXe/vr/gN+a2UPh9OuApcUpUuloSFURkfwKTXD/r5ktJggQq4GfEdwRNakMD6mq7j5ERPZXaEeCHwauBloJgsWZwCPsP8zqUW8wrZqFiEg+hTbOXw38CfCiu78BOA3oKFqpSiQxNJyzULAQEclVaLBIunsSwMzK3f1Z4MTiFas0kmHNQgluEZH9FZrgbg+fs/gpcJ+Z7WYSDquqBLeISH6FJrgvDT/+nZmtAOqA/y1aqUpkOMGtZigRkf0ddM+x7v7Q+GsdnRIKFiIiealxPsdgSg/liYjko7Nijn0JbtUsRERyFTVYmNn5ZvacmW0ws1G91prZXDNbYWZPmNlTZnZhOH++mSXMbHX4uqmY5RymBLeISH5FG+3OzKLAN4A3Ae3AY2Z2l7uvy1nts8Byd/+WmZ0E3A3MD5dtdPdFxSpfPsmUnrMQEcmnmDWLJcAGd9/k7kPAbcDFI9ZxYFr4uY4S346bSGUoi0aIRqyUxRAROeIUM1jMBrbkTLeH83L9HXCFmbUT1Co+lrOsLWyeesjMzsn3BWa21MxWmtnKjo6X/0B5MpWhXMltEZFRinlmzHd5PrJb8/cA33X3VuBC4PtmFgFeAua6+2nA3wI/NLNpI7bF3b/t7ovdfXFLS8vLLnAylVG+QkQkj2IGi3ZgTs50K6ObmT5EMKY37v4IUEEw0NKgu3eG81cBG4ETilhWIAgWyleIiIxWzGDxGHC8mbWZWRlwGXDXiHU2A28EMLOFBMGiw8xawgQ5ZnYscDywqYhlBYIEt56xEBEZrWh3Q7l72sw+CtwDRIFl7r7WzK4HVrr7XcAngP80s/9L0ET1fnd3M3sdcL2ZpYEM8Nfu3lWssg5LqBlKRCSvogULAHe/myBxnTvv8zmf1wFn5dnuDuCOYpYtnyDBrWAhIjKS2lxyKMEtIpKfgkUO5SxERPLTmTGHchYiIvkpWOTQrbMiIvkpWORQsBARyU/BIkeQs1CwEBEZScEilMk6QxkluEVE8tGZMTQ8/rYS3CIioylYhJIaf1tEZEwKFqGEahYiImNSsAgNj5Kn8SxEREbTmTGkZigRkbEpWISU4BYRGZuCRWi4GUo1CxGR0RQsQkpwi4iMTcEitC9noZ9ERGQknRlDCSW4RUTGpGARGlSwEBEZk4JFaF+CWz+JiMhIOjOG1AwlIjI2BYtQMpUhFjHiUf0kIiIj6cwY0pCqIiJjU7AIJVNZyhUsRETyUrAIDaYySm6LiIxBZ8eQmqFERMamYBFKpjK6E0pEZAwKFiHVLERExqZgEQoS3Po5RETy0dkxlFTNQkRkTAoWIeUsRETGpmARSqayunVWRGQMOjuGlOAWERmbgkVIzVAiImNTsACyWWcwnVWwEBEZQ1GDhZmdb2bPmdkGM7s2z/K5ZrbCzJ4ws6fM7MKcZdeF2z1nZm8pZjkH08NjWShYiIjkEyvWjs0sCnwDeBPQDjxmZne5+7qc1T4LLHf3b5nZScDdwPzw82XAK4FjgPvN7AR3zxSjrMNjWVQqwS0y5aRSKdrb20mlWFpAAAALdUlEQVQmk6UuSlFVVFTQ2tpKPB4/pO2LFiyAJcAGd98EYGa3ARcDucHCgWnh5zpgW/j5YuA2dx8EnjezDeH+HilGQZMa+Ehkympvb6e2tpb58+djZqUuTlG4O52dnbS3t9PW1nZI+yjmpfRsYEvOdHs4L9ffAVeYWTtBreJjB7EtZrbUzFaa2cqOjo5DLqiChcjUlUwmaWpqmrSBAsDMaGpqelm1p2IGi3y/vI+Yfg/wXXdvBS4Evm9mkQK3xd2/7e6L3X1xS0vLIRdUQ6qKTG2TOVAMe7nHWMxmqHZgTs50K/uamYZ9CDgfwN0fMbMKoLnAbSdMMjWc4FbOQkQkn2KeHR8DjjezNjMrI0hY3zVinc3AGwHMbCFQAXSE611mZuVm1gYcDzxarIIm9ya4VbMQkcOru7ubb37zmwe93YUXXkh3d3cRSpRf0YKFu6eBjwL3AM8Q3PW01syuN7OLwtU+AfylmT0J3Aq83wNrgeUEyfD/Ba4q1p1QoJyFiJTOWMEikznwKe/uu++mvr6+WMUapZjNULj73QSJ69x5n8/5vA44a4xtbwBuKGb5hilnISIAX/yftazbtmdC93nSMdP4wttfOebya6+9lo0bN7Jo0SLi8Tg1NTXMmjWL1atXs27dOi655BK2bNlCMpnk6quvZunSpQDMnz+flStX0tfXxwUXXMDZZ5/Nww8/zOzZs/nZz35GZWXlhB6HGunZl7NQM5SIHG433ngjCxYsYPXq1XzpS1/i0Ucf5YYbbmDduuApg2XLlrFq1SpWrlzJ17/+dTo7O0ftY/369Vx11VWsXbuW+vp67rjjjgkvZ1FrFkeLfc1Qip0iU9mBagCHy5IlS/Z7FuLrX/86d955JwBbtmxh/fr1NDU17bdNW1sbixYtAuD000/nhRdemPByKViQEyzKVLMQkdKqrq7e+/nBBx/k/vvv55FHHqGqqopzzz0377MS5eXlez9Ho1ESicSEl0uX0uQEi5iChYgcXrW1tfT29uZd1tPTQ0NDA1VVVTz77LP8/ve/P8yl20c1C4IEdzRixKOT/8EcETmyNDU1cdZZZ3HyySdTWVnJjBkz9i47//zzuemmmzj11FM58cQTOfPMM0tWTgULwlHyYpEp8RSniBx5fvjDH+adX15ezi9/+cu8y4bzEs3NzaxZs2bv/GuuuWbCywdqhgKCmoVumxURGZuCBRolT0RkPAoWwGAqq9tmRUQOQGdIgmaoSt02KyIyJgULwmYo3TYrIjImBQtUsxARGY+CBcGts+WqWYhICRxqF+UAX/3qVxkYGJjgEuWnYMHw3VD6KUTk8DtagoUeyiMIFupxVkT45bWw/emJ3efMU+CCG8dcnNtF+Zve9CamT5/O8uXLGRwc5NJLL+WLX/wi/f39vPvd76a9vZ1MJsPnPvc5duzYwbZt23jDG95Ac3MzK1asmNhyj6BggZ6zEJHSufHGG1mzZg2rV6/m3nvv5fbbb+fRRx/F3bnooov49a9/TUdHB8cccwy/+MUvgKDPqLq6Or785S+zYsUKmpubi15OBQuU4BaR0AFqAIfDvffey7333stpp50GQF9fH+vXr+ecc87hmmuu4dOf/jRve9vbOOeccw572aZ8sHD3vX1DiYiUkrtz3XXX8Vd/9Vejlq1atYq7776b6667jje/+c18/vOfz7OH4pnyZ8jBdDBKnsayEJFSyO2i/C1veQvLli2jr68PgK1bt7Jz5062bdtGVVUVV1xxBddccw2PP/74qG2LbcrXLDSWhYiUUm4X5RdccAGXX345r3nNawCoqanhBz/4ARs2bOCTn/wkkUiEeDzOt771LQCWLl3KBRdcwKxZs4qe4DZ3L+oXHC6LFy/2lStXHvR2PYkUn7nzad69eA6vP6GlCCUTkSPZM888w8KFC0tdjMMi37Ga2Sp3XzzetlO+ZlFXGecbl7+61MUQETmiTfmchYiIjE/BQkSmvMnSHH8gL/cYFSxEZEqrqKigs7NzUgcMd6ezs5OKiopD3seUz1mIyNTW2tpKe3s7HR0dpS5KUVVUVNDa2nrI2ytYiMiUFo/HaWtrK3UxjnhqhhIRkXEpWIiIyLgULEREZFyT5gluM+sAXnwZu2gGdk1QcY4mOu6pRcc9tRRy3PPcfdzuKyZNsHi5zGxlIY+8TzY67qlFxz21TORxqxlKRETGpWAhIiLjUrDY59ulLkCJ6LinFh331DJhx62chYiIjEs1CxERGZeChYiIjGvKBwszO9/MnjOzDWZ2banLU0xmtszMdprZmpx5jWZ2n5mtD98bSlnGiWZmc8xshZk9Y2ZrzezqcP5kP+4KM3vUzJ4Mj/uL4fw2M/tDeNw/MrOyUpe1GMwsamZPmNnPw+mpctwvmNnTZrbazFaG8ybkb31KBwsziwLfAC4ATgLeY2YnlbZURfVd4PwR864FHnD344EHwunJJA18wt0XAmcCV4X/xpP9uAeB89z9VcAi4HwzOxP4Z+Ar4XHvBj5UwjIW09XAMznTU+W4Ad7g7otynq+YkL/1KR0sgCXABnff5O5DwG3AxSUuU9G4+6+BrhGzLwZuDj/fDFxyWAtVZO7+krs/Hn7uJTiBzGbyH7e7e184GQ9fDpwH3B7On3THDWBmrcBbgf8Kp40pcNwHMCF/61M9WMwGtuRMt4fzppIZ7v4SBCdWYHqJy1M0ZjYfOA34A1PguMOmmNXATuA+YCPQ7e7pcJXJ+vf+VeBTQDacbmJqHDcEFwT3mtkqM1sazpuQv/WpPp6F5Zmne4knITOrAe4APu7ue4KLzcnN3TPAIjOrB+4EFuZb7fCWqrjM7G3ATndfZWbnDs/Os+qkOu4cZ7n7NjObDtxnZs9O1I6nes2iHZiTM90KbCtRWUplh5nNAgjfd5a4PBPOzOIEgeIWd/9JOHvSH/cwd+8GHiTI2dSb2fBF4mT8ez8LuMjMXiBoVj6PoKYx2Y8bAHffFr7vJLhAWMIE/a1P9WDxGHB8eKdEGXAZcFeJy3S43QVcGX6+EvhZCcsy4cL26v8GnnH3L+csmuzH3RLWKDCzSuBPCfI1K4B3hatNuuN29+vcvdXd5xP8f/6Vu7+XSX7cAGZWbWa1w5+BNwNrmKC/9Sn/BLeZXUhw5REFlrn7DSUuUtGY2a3AuQTdFu8AvgD8FFgOzAU2A3/m7iOT4EctMzsb+A3wNPvasD9DkLeYzMd9KkEyM0pwUbjc3a83s2MJrrgbgSeAK9x9sHQlLZ6wGeoad3/bVDju8BjvDCdjwA/d/QYza2IC/tanfLAQEZHxTfVmKBERKYCChYiIjEvBQkRExqVgISIi41KwEBGRcSlYiBwBzOzc4R5SRY5EChYiIjIuBQuRg2BmV4TjRKw2s/8IO+vrM7N/NbPHzewBM2sJ111kZr83s6fM7M7hcQTM7Dgzuz8ca+JxM1sQ7r7GzG43s2fN7BabCh1YyVFDwUKkQGa2EPhzgs7aFgEZ4L1ANfC4u78aeIjgyXiA7wGfdvdTCZ4gH55/C/CNcKyJ1wIvhfNPAz5OMLbKsQT9HIkcEaZ6r7MiB+ONwOnAY+FFfyVBp2xZ4EfhOj8AfmJmdUC9uz8Uzr8Z+HHYd89sd78TwN2TAOH+HnX39nB6NTAf+G3xD0tkfAoWIoUz4GZ3v26/mWafG7HegfrQOVDTUm5fRRn0/1OOIGqGEincA8C7wrEChsc2nkfw/2i4R9PLgd+6ew+w28zOCee/D3jI3fcA7WZ2SbiPcjOrOqxHIXIIdOUiUiB3X2dmnyUYiSwCpICrgH7glWa2CughyGtA0B30TWEw2AR8IJz/PuA/zOz6cB9/dhgPQ+SQqNdZkZfJzPrcvabU5RApJjVDiYjIuFSzEBGRcalmISIi41KwEBGRcSlYiIjIuBQsRERkXAoWIiIyrv8P61qTCi92D/MAAAAASUVORK5CYII=\n", 464 | "text/plain": [ 465 | "
" 466 | ] 467 | }, 468 | "metadata": { 469 | "needs_background": "light" 470 | }, 471 | "output_type": "display_data" 472 | } 473 | ], 474 | "source": [ 475 | "plt.plot(history.history['acc'])\n", 476 | "plt.plot(history.history['val_acc'])\n", 477 | "plt.title(\"Accuracy\")\n", 478 | "plt.xlabel('epoch')\n", 479 | "plt.ylabel('accuracy')\n", 480 | "plt.legend(['train','test'])\n", 481 | "plt.show()" 482 | ] 483 | }, 484 | { 485 | "cell_type": "code", 486 | "execution_count": 102, 487 | "metadata": {}, 488 | "outputs": [], 489 | "source": [ 490 | "model.save('./new_model6.h5')" 491 | ] 492 | }, 493 | { 494 | "cell_type": "code", 495 | "execution_count": 31, 496 | "metadata": {}, 497 | "outputs": [], 498 | "source": [ 499 | "from keras.models import load_model\n" 500 | ] 501 | }, 502 | { 503 | "cell_type": "code", 504 | "execution_count": 32, 505 | "metadata": {}, 506 | "outputs": [], 507 | "source": [ 508 | "m = load_model('./new_model6.h5')" 509 | ] 510 | }, 511 | { 512 | "cell_type": "code", 513 | "execution_count": 33, 514 | "metadata": {}, 515 | "outputs": [], 516 | "source": [ 517 | "test_data = os.listdir('./test_data/')" 518 | ] 519 | }, 520 | { 521 | "cell_type": "code", 522 | "execution_count": 34, 523 | "metadata": {}, 524 | "outputs": [], 525 | "source": [ 526 | "x, y = [], []\n", 527 | "for ix in test_data:\n", 528 | " images = os.listdir('./test_data/' + ix)\n", 529 | " for cx in range(1,201):\n", 530 | " img_path = './test_data/' + ix + '/' + str(cx) + '.jpg'\n", 531 | " img = cv2.imread(img_path, 0)\n", 532 | " img = img.reshape((50,50,1))\n", 533 | " img = img/255.0\n", 534 | " x.append(img)\n", 535 | " y.append(dict_labels[ix])" 536 | ] 537 | }, 538 | { 539 | "cell_type": "code", 540 | "execution_count": 35, 541 | "metadata": {}, 542 | "outputs": [], 543 | "source": [ 544 | "X_t = np.array(x)\n", 545 | "y_t = np.array(y)\n", 546 | "Y_t = np_utils.to_categorical(y_t)" 547 | ] 548 | }, 549 | { 550 | "cell_type": "code", 551 | "execution_count": 36, 552 | "metadata": {}, 553 | "outputs": [ 554 | { 555 | "data": { 556 | "text/plain": [ 557 | "(4800, 50, 50, 1)" 558 | ] 559 | }, 560 | "execution_count": 36, 561 | "metadata": {}, 562 | "output_type": "execute_result" 563 | } 564 | ], 565 | "source": [ 566 | "X_t.shape" 567 | ] 568 | }, 569 | { 570 | "cell_type": "code", 571 | "execution_count": 37, 572 | "metadata": {}, 573 | "outputs": [], 574 | "source": [ 575 | "y_pred = m.predict(X_t)" 576 | ] 577 | }, 578 | { 579 | "cell_type": "code", 580 | "execution_count": 38, 581 | "metadata": {}, 582 | "outputs": [], 583 | "source": [ 584 | "from sklearn.metrics import accuracy_score" 585 | ] 586 | }, 587 | { 588 | "cell_type": "code", 589 | "execution_count": 39, 590 | "metadata": {}, 591 | "outputs": [ 592 | { 593 | "data": { 594 | "text/plain": [ 595 | "0.7985416666666667" 596 | ] 597 | }, 598 | "execution_count": 39, 599 | "metadata": {}, 600 | "output_type": "execute_result" 601 | } 602 | ], 603 | "source": [ 604 | "accuracy_score(Y_t, y_pred.round())" 605 | ] 606 | }, 607 | { 608 | "cell_type": "code", 609 | "execution_count": 40, 610 | "metadata": {}, 611 | "outputs": [], 612 | "source": [ 613 | "from sklearn.metrics import classification_report, confusion_matrix" 614 | ] 615 | }, 616 | { 617 | "cell_type": "code", 618 | "execution_count": 41, 619 | "metadata": {}, 620 | "outputs": [ 621 | { 622 | "name": "stdout", 623 | "output_type": "stream", 624 | "text": [ 625 | " precision recall f1-score support\n", 626 | "\n", 627 | " 0 0.00 0.00 0.00 0\n", 628 | " 1 1.00 0.99 1.00 202\n", 629 | " 2 0.99 0.88 0.93 226\n", 630 | " 3 0.91 1.00 0.95 181\n", 631 | " 4 0.94 0.68 0.79 275\n", 632 | " 5 1.00 0.69 0.82 290\n", 633 | " 6 0.79 0.71 0.75 223\n", 634 | " 7 0.61 0.46 0.52 265\n", 635 | " 8 0.28 0.56 0.38 102\n", 636 | " 9 0.94 0.99 0.97 191\n", 637 | " 10 0.80 0.92 0.85 172\n", 638 | " 11 0.83 1.00 0.91 167\n", 639 | " 12 0.84 0.54 0.66 311\n", 640 | " 13 0.96 0.58 0.72 333\n", 641 | " 14 1.00 1.00 1.00 201\n", 642 | " 15 1.00 0.90 0.95 223\n", 643 | " 16 0.89 0.84 0.86 211\n", 644 | " 17 0.51 0.89 0.65 113\n", 645 | " 18 0.10 0.95 0.18 21\n", 646 | " 19 0.04 1.00 0.07 7\n", 647 | " 20 1.00 1.00 1.00 200\n", 648 | " 21 1.00 0.83 0.90 242\n", 649 | " 22 0.77 0.94 0.85 162\n", 650 | " 23 1.00 0.74 0.85 269\n", 651 | " 24 0.96 0.99 0.98 195\n", 652 | "\n", 653 | "avg / total 0.89 0.80 0.83 4782\n", 654 | "\n" 655 | ] 656 | }, 657 | { 658 | "name": "stderr", 659 | "output_type": "stream", 660 | "text": [ 661 | "c:\\users\\asus\\appdata\\local\\programs\\python\\python36\\lib\\site-packages\\sklearn\\metrics\\classification.py:1135: UndefinedMetricWarning: Precision and F-score are ill-defined and being set to 0.0 in labels with no predicted samples.\n", 662 | " 'precision', 'predicted', average, warn_for)\n", 663 | "c:\\users\\asus\\appdata\\local\\programs\\python\\python36\\lib\\site-packages\\sklearn\\metrics\\classification.py:1137: UndefinedMetricWarning: Recall and F-score are ill-defined and being set to 0.0 in labels with no true samples.\n", 664 | " 'recall', 'true', average, warn_for)\n" 665 | ] 666 | } 667 | ], 668 | "source": [ 669 | "print(classification_report(y_pred.round(), Y_t))" 670 | ] 671 | }, 672 | { 673 | "cell_type": "code", 674 | "execution_count": null, 675 | "metadata": {}, 676 | "outputs": [], 677 | "source": [] 678 | } 679 | ], 680 | "metadata": { 681 | "kernelspec": { 682 | "display_name": "Python 3", 683 | "language": "python", 684 | "name": "python3" 685 | }, 686 | "language_info": { 687 | "codemirror_mode": { 688 | "name": "ipython", 689 | "version": 3 690 | }, 691 | "file_extension": ".py", 692 | "mimetype": "text/x-python", 693 | "name": "python", 694 | "nbconvert_exporter": "python", 695 | "pygments_lexer": "ipython3", 696 | "version": "3.6.5" 697 | } 698 | }, 699 | "nbformat": 4, 700 | "nbformat_minor": 2 701 | } 702 | -------------------------------------------------------------------------------- /Demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sid-1998/Sign-Language-Recognition/fd8307b861dc07492de4f35a305576cfcec7e6cb/Demo.gif -------------------------------------------------------------------------------- /Gesture_Recognize_sign.py: -------------------------------------------------------------------------------- 1 | 2 | # coding: utf-8 3 | 4 | # In[2]: 5 | 6 | 7 | import cv2 8 | import numpy as np 9 | from keras.models import load_model 10 | 11 | 12 | # In[3]: 13 | 14 | 15 | model = load_model('./new_model6.h5') 16 | 17 | 18 | # In[4]: 19 | 20 | 21 | gestures = { 22 | 1:'A', 23 | 2:'B', 24 | 3:'C', 25 | 4:'D', 26 | 5:'E', 27 | 6:'F', 28 | 7:'G', 29 | 8:'H', 30 | 9:'I', 31 | 10:'K', 32 | 11:'L', 33 | 12:'M', 34 | 13:'N', 35 | 14:'O', 36 | 15:'P', 37 | 16:'Q', 38 | 17:'R', 39 | 18:'S', 40 | 19:'T', 41 | 20:'U', 42 | 21:'V', 43 | 22:'W', 44 | 23:'X', 45 | 24:'Y', 46 | } 47 | 48 | 49 | # In[10]: 50 | 51 | 52 | def predict(gesture): 53 | img = cv2.resize(gesture, (50,50)) 54 | img = img.reshape(1,50,50,1) 55 | img = img/255.0 56 | prd = model.predict(img) 57 | index = prd.argmax() 58 | return gestures[index] 59 | 60 | 61 | # In[15]: 62 | 63 | 64 | vc = cv2.VideoCapture(0) 65 | rval, frame = vc.read() 66 | old_text = '' 67 | pred_text = '' 68 | count_frames = 0 69 | total_str = '' 70 | flag = False 71 | 72 | 73 | # In[16]: 74 | 75 | 76 | while True: 77 | 78 | if frame is not None: 79 | 80 | frame = cv2.flip(frame, 1) 81 | frame = cv2.resize( frame, (400,400) ) 82 | 83 | cv2.rectangle(frame, (300,300), (100,100), (0,255,0), 2) 84 | 85 | crop_img = frame[100:300, 100:300] 86 | grey = cv2.cvtColor(crop_img, cv2.COLOR_BGR2GRAY) 87 | 88 | thresh = cv2.threshold(grey,210,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)[1] 89 | 90 | 91 | blackboard = np.zeros(frame.shape, dtype=np.uint8) 92 | cv2.putText(blackboard, "Predicted text - ", (30, 40), cv2.FONT_HERSHEY_TRIPLEX, 1, (255, 255, 0)) 93 | if count_frames > 20 and pred_text != "": 94 | total_str += pred_text 95 | count_frames = 0 96 | 97 | if flag == True: 98 | old_text = pred_text 99 | pred_text = predict(thresh) 100 | 101 | if old_text == pred_text: 102 | count_frames += 1 103 | else: 104 | count_frames = 0 105 | cv2.putText(blackboard, total_str, (30, 80), cv2.FONT_HERSHEY_TRIPLEX, 1, (255, 255, 127)) 106 | res = np.hstack((frame, blackboard)) 107 | 108 | cv2.imshow("image", res) 109 | cv2.imshow("hand", thresh) 110 | 111 | rval, frame = vc.read() 112 | keypress = cv2.waitKey(1) 113 | if keypress == ord('c'): 114 | flag = True 115 | if keypress == ord('q'): 116 | break 117 | 118 | vc.release() 119 | cv2.destroyAllWindows() 120 | cv2.waitKey(1) 121 | 122 | 123 | # In[17]: 124 | 125 | 126 | vc.release() 127 | 128 | -------------------------------------------------------------------------------- /Image_capturing.py: -------------------------------------------------------------------------------- 1 | 2 | # coding: utf-8 3 | 4 | # In[11]: 5 | 6 | 7 | import cv2 8 | import numpy as np 9 | 10 | vc = cv2.VideoCapture(0) 11 | pic_no = 0 12 | total_pic = 1200 13 | flag_capturing = False 14 | path = './dataset/Y' 15 | while(vc.isOpened()): 16 | # read image 17 | rval, frame = vc.read() 18 | frame = cv2.flip(frame, 1) 19 | 20 | # get hand data from the rectangle sub window on the screen 21 | cv2.rectangle(frame, (300,300), (100,100), (0,255,0),0) 22 | 23 | cv2.imshow("image", frame) 24 | 25 | crop_img = frame[100:300, 100:300] 26 | 27 | if flag_capturing: 28 | 29 | pic_no += 1 30 | save_img = cv2.resize( crop_img, (50,50) ) 31 | save_img = np.array(save_img) 32 | cv2.imwrite(path + "/" + str(pic_no) + ".jpg", save_img) 33 | 34 | 35 | keypress = cv2.waitKey(1) 36 | 37 | if pic_no == total_pic: 38 | flag_capturing = False 39 | break 40 | 41 | if keypress == ord('q'): 42 | break 43 | elif keypress == ord('c'): 44 | flag_capturing = True 45 | 46 | vc.release() 47 | cv2.destroyAllWindows() 48 | cv2.waitKey(1) 49 | 50 | -------------------------------------------------------------------------------- /Image_preprocessing.py: -------------------------------------------------------------------------------- 1 | 2 | # coding: utf-8 3 | 4 | # In[15]: 5 | 6 | 7 | import os 8 | import numpy as np 9 | import cv2 10 | import matplotlib.pyplot as plt 11 | 12 | 13 | # In[16]: 14 | 15 | 16 | path = './dataset/' 17 | path2 = './preprocessed/' 18 | 19 | 20 | # In[17]: 21 | 22 | 23 | gestures = os.listdir(path) 24 | 25 | 26 | # In[18]: 27 | 28 | 29 | print(gestures) 30 | 31 | 32 | # In[19]: 33 | 34 | 35 | for ix in gestures: 36 | images = os.listdir(path + ix) 37 | os.mkdir(path2 + ix) 38 | for cx in images: 39 | img_path = path + ix +'/' + cx 40 | img = cv2.imread(img_path) 41 | grey = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 42 | thresh = cv2.threshold(grey, 127, 255, cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)[1] 43 | save_img = cv2.resize(thresh, (50,50)) 44 | cv2.imwrite(path2 + ix + '/' + cx, save_img) 45 | 46 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Siddharth Pahuja 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Sign-Language-Recognition 2 | 3 | The CNN is trained on a custom dataset containing alphabets A-Y (excluding J) of American Sign Language. 4 | 5 | ## Usage 6 | 7 | ### To run the pretrained model 8 | 9 | Run: 10 | 11 | ``` 12 | python Gesture_recognize_sign.py 13 | ``` 14 | 15 | This will start the webcam.Press C then place your hand inside the green box while performing a gesture 16 | and you will get the letter to which the respective gesture corresponds. Press Q to quit. 17 | 18 | ### To train your own model 19 | 20 | Set up the path in the Image_capturing.py file 21 | 22 | Run: 23 | 24 | ``` 25 | python Image_capturing.py 26 | ``` 27 | 28 | Place your hand in the green box and press C to start capturing the data. 29 | 30 | Now set up the paths in Image_preprocessing.py file to preprocess the dataset. 31 | 32 | Then Run: 33 | 34 | ``` 35 | python Image_preprocessing.py 36 | ``` 37 | 38 | After preprocessing set up the path in model.py file to get the preprocessed data for training. 39 | 40 | Then Run: 41 | 42 | ``` 43 | python model.py 44 | ``` 45 | 46 | This will create model-.h5 files. Choose the appropriate file for Gesture_recognize_sign.py 47 | 48 | Then Run: 49 | 50 | ``` 51 | python Gesture_recognize_sign.py 52 | ``` 53 | 54 | ## Demo 55 | 56 | ![Demo]( ./Demo.gif ) 57 | -------------------------------------------------------------------------------- /model.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": {}, 7 | "outputs": [ 8 | { 9 | "name": "stderr", 10 | "output_type": "stream", 11 | "text": [ 12 | "Using TensorFlow backend.\n" 13 | ] 14 | } 15 | ], 16 | "source": [ 17 | "import numpy as np\n", 18 | "from keras.layers import Conv2D, Dense, Flatten, Dropout, MaxPooling2D\n", 19 | "from keras.models import Sequential, save_model\n", 20 | "from keras.utils import np_utils\n", 21 | "from keras.callbacks import ModelCheckpoint\n", 22 | "from sklearn.model_selection import train_test_split\n", 23 | "from sklearn.utils import shuffle\n", 24 | "import os\n", 25 | "import cv2" 26 | ] 27 | }, 28 | { 29 | "cell_type": "code", 30 | "execution_count": 2, 31 | "metadata": {}, 32 | "outputs": [], 33 | "source": [ 34 | "path = '/Sign_Language_Recognition/preprocessed_new/'" 35 | ] 36 | }, 37 | { 38 | "cell_type": "code", 39 | "execution_count": 3, 40 | "metadata": {}, 41 | "outputs": [], 42 | "source": [ 43 | "gestures = os.listdir(path)" 44 | ] 45 | }, 46 | { 47 | "cell_type": "code", 48 | "execution_count": 4, 49 | "metadata": {}, 50 | "outputs": [], 51 | "source": [ 52 | "dict_labels = {\n", 53 | " 'A': 1,\n", 54 | " 'B': 2,\n", 55 | " 'C':3,\n", 56 | " 'D':4,\n", 57 | " 'E':5,\n", 58 | " 'F':6,\n", 59 | " 'G':7,\n", 60 | " 'H':8,\n", 61 | " 'I':9,\n", 62 | " 'K':10,\n", 63 | " 'L':11,\n", 64 | " 'M':12,\n", 65 | " 'N':13,\n", 66 | " 'O':14,\n", 67 | " 'P':15,\n", 68 | " 'Q':16,\n", 69 | " 'R':17,\n", 70 | " 'S':18,\n", 71 | " 'T':19,\n", 72 | " 'U':20,\n", 73 | " 'V':21,\n", 74 | " 'W':22,\n", 75 | " 'X':23,\n", 76 | " 'Y':24,\n", 77 | " \n", 78 | "}" 79 | ] 80 | }, 81 | { 82 | "cell_type": "code", 83 | "execution_count": 5, 84 | "metadata": {}, 85 | "outputs": [ 86 | { 87 | "name": "stdout", 88 | "output_type": "stream", 89 | "text": [ 90 | "['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y']\n" 91 | ] 92 | } 93 | ], 94 | "source": [ 95 | "print(list(dict_labels.keys()))" 96 | ] 97 | }, 98 | { 99 | "cell_type": "code", 100 | "execution_count": 6, 101 | "metadata": {}, 102 | "outputs": [], 103 | "source": [ 104 | "x, y = [], []\n", 105 | "for ix in gestures:\n", 106 | " images = os.listdir(path + ix)\n", 107 | " for cx in images:\n", 108 | " img_path = path + ix + '/' + cx\n", 109 | " img = cv2.imread(img_path, 0)\n", 110 | " img = img.reshape((50,50,1))\n", 111 | " img = img/255.0\n", 112 | " x.append(img)\n", 113 | " y.append(dict_labels[ix])" 114 | ] 115 | }, 116 | { 117 | "cell_type": "code", 118 | "execution_count": 7, 119 | "metadata": {}, 120 | "outputs": [ 121 | { 122 | "data": { 123 | "text/plain": [ 124 | "(28800, 25)" 125 | ] 126 | }, 127 | "execution_count": 7, 128 | "metadata": {}, 129 | "output_type": "execute_result" 130 | } 131 | ], 132 | "source": [ 133 | "X = np.array(x)\n", 134 | "Y = np.array(y)\n", 135 | "Y = np_utils.to_categorical(Y)\n", 136 | "Y.shape" 137 | ] 138 | }, 139 | { 140 | "cell_type": "code", 141 | "execution_count": 29, 142 | "metadata": {}, 143 | "outputs": [], 144 | "source": [ 145 | "import seaborn as sns\n", 146 | "import matplotlib.pyplot as plt" 147 | ] 148 | }, 149 | { 150 | "cell_type": "code", 151 | "execution_count": 30, 152 | "metadata": {}, 153 | "outputs": [ 154 | { 155 | "data": { 156 | "text/plain": [ 157 | "" 158 | ] 159 | }, 160 | "execution_count": 30, 161 | "metadata": {}, 162 | "output_type": "execute_result" 163 | }, 164 | { 165 | "data": { 166 | "image/png": "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\n", 167 | "text/plain": [ 168 | "
" 169 | ] 170 | }, 171 | "metadata": { 172 | "needs_background": "light" 173 | }, 174 | "output_type": "display_data" 175 | } 176 | ], 177 | "source": [ 178 | "plt.figure(figsize = (18,8))\n", 179 | "sns.countplot(x=list(dict_labels.keys()))" 180 | ] 181 | }, 182 | { 183 | "cell_type": "code", 184 | "execution_count": 33, 185 | "metadata": {}, 186 | "outputs": [ 187 | { 188 | "data": { 189 | "text/plain": [ 190 | "(28800, 25)" 191 | ] 192 | }, 193 | "execution_count": 33, 194 | "metadata": {}, 195 | "output_type": "execute_result" 196 | } 197 | ], 198 | "source": [ 199 | "Y.shape" 200 | ] 201 | }, 202 | { 203 | "cell_type": "code", 204 | "execution_count": 34, 205 | "metadata": {}, 206 | "outputs": [], 207 | "source": [ 208 | "categories = Y.shape[1]" 209 | ] 210 | }, 211 | { 212 | "cell_type": "code", 213 | "execution_count": 35, 214 | "metadata": {}, 215 | "outputs": [], 216 | "source": [ 217 | "X, Y = shuffle(X, Y, random_state=0)" 218 | ] 219 | }, 220 | { 221 | "cell_type": "code", 222 | "execution_count": 36, 223 | "metadata": {}, 224 | "outputs": [ 225 | { 226 | "data": { 227 | "text/plain": [ 228 | "(28800, 50, 50, 1)" 229 | ] 230 | }, 231 | "execution_count": 36, 232 | "metadata": {}, 233 | "output_type": "execute_result" 234 | } 235 | ], 236 | "source": [ 237 | "X.shape" 238 | ] 239 | }, 240 | { 241 | "cell_type": "code", 242 | "execution_count": 95, 243 | "metadata": {}, 244 | "outputs": [], 245 | "source": [ 246 | "X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.3)" 247 | ] 248 | }, 249 | { 250 | "cell_type": "code", 251 | "execution_count": 96, 252 | "metadata": {}, 253 | "outputs": [ 254 | { 255 | "name": "stdout", 256 | "output_type": "stream", 257 | "text": [ 258 | "(20160, 50, 50, 1) (8640, 50, 50, 1)\n", 259 | "(20160, 25) (8640, 25)\n" 260 | ] 261 | } 262 | ], 263 | "source": [ 264 | "print(X_train.shape, X_test.shape)\n", 265 | "print(Y_train.shape, Y_test.shape)" 266 | ] 267 | }, 268 | { 269 | "cell_type": "code", 270 | "execution_count": 97, 271 | "metadata": {}, 272 | "outputs": [ 273 | { 274 | "name": "stdout", 275 | "output_type": "stream", 276 | "text": [ 277 | "_________________________________________________________________\n", 278 | "Layer (type) Output Shape Param # \n", 279 | "=================================================================\n", 280 | "conv2d_13 (Conv2D) (None, 48, 48, 64) 640 \n", 281 | "_________________________________________________________________\n", 282 | "max_pooling2d_11 (MaxPooling (None, 24, 24, 64) 0 \n", 283 | "_________________________________________________________________\n", 284 | "conv2d_14 (Conv2D) (None, 22, 22, 64) 36928 \n", 285 | "_________________________________________________________________\n", 286 | "max_pooling2d_12 (MaxPooling (None, 11, 11, 64) 0 \n", 287 | "_________________________________________________________________\n", 288 | "conv2d_15 (Conv2D) (None, 9, 9, 64) 36928 \n", 289 | "_________________________________________________________________\n", 290 | "max_pooling2d_13 (MaxPooling (None, 4, 4, 64) 0 \n", 291 | "_________________________________________________________________\n", 292 | "flatten_5 (Flatten) (None, 1024) 0 \n", 293 | "_________________________________________________________________\n", 294 | "dense_8 (Dense) (None, 128) 131200 \n", 295 | "_________________________________________________________________\n", 296 | "dropout_5 (Dropout) (None, 128) 0 \n", 297 | "_________________________________________________________________\n", 298 | "dense_9 (Dense) (None, 25) 3225 \n", 299 | "=================================================================\n", 300 | "Total params: 208,921\n", 301 | "Trainable params: 208,921\n", 302 | "Non-trainable params: 0\n", 303 | "_________________________________________________________________\n" 304 | ] 305 | } 306 | ], 307 | "source": [ 308 | "model = Sequential()\n", 309 | "model.add(Conv2D(64, kernel_size=(3,3), activation = 'relu', input_shape=(50,50 ,1) ))\n", 310 | "model.add(MaxPooling2D(pool_size = (2, 2)))\n", 311 | "\n", 312 | "model.add(Conv2D(64, kernel_size = (3, 3), activation = 'relu'))\n", 313 | "model.add(MaxPooling2D(pool_size = (2, 2)))\n", 314 | "\n", 315 | "model.add(Conv2D(64, kernel_size = (3, 3), activation = 'relu'))\n", 316 | "model.add(MaxPooling2D(pool_size = (2, 2)))\n", 317 | "\n", 318 | "model.add(Flatten())\n", 319 | "model.add(Dense(128, activation = 'relu'))\n", 320 | "model.add(Dropout(0.20))\n", 321 | "model.add(Dense(categories, activation = 'softmax'))\n", 322 | "\n", 323 | "model.summary()" 324 | ] 325 | }, 326 | { 327 | "cell_type": "code", 328 | "execution_count": 98, 329 | "metadata": {}, 330 | "outputs": [], 331 | "source": [ 332 | "model.compile(optimizer='Adam', metrics=['accuracy'], loss='categorical_crossentropy')" 333 | ] 334 | }, 335 | { 336 | "cell_type": "code", 337 | "execution_count": 99, 338 | "metadata": {}, 339 | "outputs": [ 340 | { 341 | "name": "stdout", 342 | "output_type": "stream", 343 | "text": [ 344 | "Train on 20160 samples, validate on 8640 samples\n", 345 | "Epoch 1/50\n", 346 | "20160/20160 [==============================] - 28s 1ms/step - loss: 0.7853 - acc: 0.7698 - val_loss: 0.1140 - val_acc: 0.9664\n", 347 | "Epoch 2/50\n", 348 | "20160/20160 [==============================] - 26s 1ms/step - loss: 0.1139 - acc: 0.9658 - val_loss: 0.0481 - val_acc: 0.9873\n", 349 | "Epoch 3/50\n", 350 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0671 - acc: 0.9788 - val_loss: 0.0381 - val_acc: 0.9891\n", 351 | "Epoch 4/50\n", 352 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0467 - acc: 0.9854 - val_loss: 0.0245 - val_acc: 0.9936\n", 353 | "Epoch 5/50\n", 354 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0292 - acc: 0.9911 - val_loss: 0.0291 - val_acc: 0.9926\n", 355 | "Epoch 6/50\n", 356 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0291 - acc: 0.9910 - val_loss: 0.0155 - val_acc: 0.9953\n", 357 | "Epoch 7/50\n", 358 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0248 - acc: 0.9919 - val_loss: 0.0130 - val_acc: 0.9957\n", 359 | "Epoch 8/50\n", 360 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0231 - acc: 0.9920 - val_loss: 0.0138 - val_acc: 0.9962\n", 361 | "Epoch 9/50\n", 362 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0149 - acc: 0.9951 - val_loss: 0.0116 - val_acc: 0.9966\n", 363 | "Epoch 10/50\n", 364 | "20160/20160 [==============================] - 28s 1ms/step - loss: 0.0160 - acc: 0.9942 - val_loss: 0.0140 - val_acc: 0.9961\n", 365 | "Epoch 11/50\n", 366 | "20160/20160 [==============================] - 28s 1ms/step - loss: 0.0122 - acc: 0.9959 - val_loss: 0.0118 - val_acc: 0.9968\n", 367 | "Epoch 12/50\n", 368 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0116 - acc: 0.9962 - val_loss: 0.0121 - val_acc: 0.9966\n", 369 | "Epoch 13/50\n", 370 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0105 - acc: 0.9965 - val_loss: 0.0109 - val_acc: 0.9970\n", 371 | "Epoch 14/50\n", 372 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0095 - acc: 0.9966 - val_loss: 0.0110 - val_acc: 0.9968\n", 373 | "Epoch 15/50\n", 374 | "20160/20160 [==============================] - 26s 1ms/step - loss: 0.0108 - acc: 0.9959 - val_loss: 0.0132 - val_acc: 0.9962\n", 375 | "Epoch 16/50\n", 376 | "20160/20160 [==============================] - 26s 1ms/step - loss: 0.0103 - acc: 0.9967 - val_loss: 0.0067 - val_acc: 0.9980\n", 377 | "Epoch 17/50\n", 378 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0087 - acc: 0.9975 - val_loss: 0.0086 - val_acc: 0.9971\n", 379 | "Epoch 18/50\n", 380 | "20160/20160 [==============================] - 26s 1ms/step - loss: 0.0053 - acc: 0.9981 - val_loss: 0.0100 - val_acc: 0.9976\n", 381 | "Epoch 19/50\n", 382 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0066 - acc: 0.9978 - val_loss: 0.0061 - val_acc: 0.9983\n", 383 | "Epoch 20/50\n", 384 | "20160/20160 [==============================] - 26s 1ms/step - loss: 0.0092 - acc: 0.9966 - val_loss: 0.0106 - val_acc: 0.9966\n", 385 | "Epoch 21/50\n", 386 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0073 - acc: 0.9977 - val_loss: 0.0149 - val_acc: 0.9957\n", 387 | "Epoch 22/50\n", 388 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0062 - acc: 0.9982 - val_loss: 0.0087 - val_acc: 0.9977\n", 389 | "Epoch 23/50\n", 390 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0032 - acc: 0.9989 - val_loss: 0.0074 - val_acc: 0.9977\n", 391 | "Epoch 24/50\n", 392 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0059 - acc: 0.9980 - val_loss: 0.0087 - val_acc: 0.9969\n", 393 | "Epoch 25/50\n", 394 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0087 - acc: 0.9971 - val_loss: 0.0134 - val_acc: 0.9963\n", 395 | "Epoch 26/50\n", 396 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0065 - acc: 0.9981 - val_loss: 0.0090 - val_acc: 0.9972\n", 397 | "Epoch 27/50\n", 398 | "20160/20160 [==============================] - 26s 1ms/step - loss: 0.0030 - acc: 0.9988 - val_loss: 0.0139 - val_acc: 0.9968\n", 399 | "Epoch 28/50\n", 400 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0075 - acc: 0.9976 - val_loss: 0.0086 - val_acc: 0.9976\n", 401 | "Epoch 29/50\n", 402 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0042 - acc: 0.9986 - val_loss: 0.0090 - val_acc: 0.9978\n", 403 | "Epoch 30/50\n", 404 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0049 - acc: 0.9984 - val_loss: 0.0184 - val_acc: 0.9959\n", 405 | "Epoch 31/50\n", 406 | "20160/20160 [==============================] - 26s 1ms/step - loss: 0.0089 - acc: 0.9970 - val_loss: 0.0061 - val_acc: 0.9983\n", 407 | "Epoch 32/50\n", 408 | "20160/20160 [==============================] - 26s 1ms/step - loss: 0.0027 - acc: 0.9992 - val_loss: 0.0058 - val_acc: 0.9981\n", 409 | "Epoch 33/50\n", 410 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0026 - acc: 0.9991 - val_loss: 0.0090 - val_acc: 0.9976\n", 411 | "Epoch 34/50\n", 412 | "20160/20160 [==============================] - 26s 1ms/step - loss: 0.0029 - acc: 0.9990 - val_loss: 0.0107 - val_acc: 0.9976\n", 413 | "Epoch 35/50\n", 414 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0048 - acc: 0.9985 - val_loss: 0.0102 - val_acc: 0.9973\n", 415 | "Epoch 36/50\n", 416 | "20160/20160 [==============================] - 26s 1ms/step - loss: 0.0029 - acc: 0.9990 - val_loss: 0.0096 - val_acc: 0.9980\n", 417 | "Epoch 37/50\n", 418 | "20160/20160 [==============================] - 26s 1ms/step - loss: 0.0043 - acc: 0.9986 - val_loss: 0.0061 - val_acc: 0.9987\n", 419 | "Epoch 38/50\n", 420 | "20160/20160 [==============================] - 26s 1ms/step - loss: 0.0018 - acc: 0.9995 - val_loss: 0.0062 - val_acc: 0.9986\n", 421 | "Epoch 39/50\n", 422 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0024 - acc: 0.9992 - val_loss: 0.0059 - val_acc: 0.9986\n", 423 | "Epoch 40/50\n", 424 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0055 - acc: 0.9981 - val_loss: 0.0073 - val_acc: 0.9973\n", 425 | "Epoch 41/50\n", 426 | "20160/20160 [==============================] - 28s 1ms/step - loss: 0.0055 - acc: 0.9980 - val_loss: 0.0113 - val_acc: 0.9971\n", 427 | "Epoch 42/50\n", 428 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0021 - acc: 0.9995 - val_loss: 0.0073 - val_acc: 0.9983\n", 429 | "Epoch 43/50\n", 430 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0066 - acc: 0.9977 - val_loss: 0.0139 - val_acc: 0.9970\n", 431 | "Epoch 44/50\n", 432 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0031 - acc: 0.9989 - val_loss: 0.0096 - val_acc: 0.9980\n", 433 | "Epoch 45/50\n", 434 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0024 - acc: 0.9990 - val_loss: 0.0111 - val_acc: 0.9980\n", 435 | "Epoch 46/50\n", 436 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0029 - acc: 0.9991 - val_loss: 0.0052 - val_acc: 0.9986\n", 437 | "Epoch 47/50\n", 438 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0034 - acc: 0.9988 - val_loss: 0.0268 - val_acc: 0.9921\n", 439 | "Epoch 48/50\n", 440 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0055 - acc: 0.9978 - val_loss: 0.0141 - val_acc: 0.9971\n", 441 | "Epoch 49/50\n", 442 | "20160/20160 [==============================] - 26s 1ms/step - loss: 0.0030 - acc: 0.9993 - val_loss: 0.0124 - val_acc: 0.9972\n", 443 | "Epoch 50/50\n", 444 | "20160/20160 [==============================] - 27s 1ms/step - loss: 0.0024 - acc: 0.9991 - val_loss: 0.0064 - val_acc: 0.9983\n" 445 | ] 446 | } 447 | ], 448 | "source": [ 449 | "history = model.fit(X_train, Y_train, batch_size=128, epochs=50, validation_data=[X_test, Y_test])" 450 | ] 451 | }, 452 | { 453 | "cell_type": "code", 454 | "execution_count": 100, 455 | "metadata": {}, 456 | "outputs": [], 457 | "source": [ 458 | "import matplotlib.pyplot as plt\n", 459 | "%matplotlib inline" 460 | ] 461 | }, 462 | { 463 | "cell_type": "code", 464 | "execution_count": 101, 465 | "metadata": {}, 466 | "outputs": [ 467 | { 468 | "data": { 469 | "image/png": "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\n", 470 | "text/plain": [ 471 | "
" 472 | ] 473 | }, 474 | "metadata": { 475 | "needs_background": "light" 476 | }, 477 | "output_type": "display_data" 478 | } 479 | ], 480 | "source": [ 481 | "plt.plot(history.history['acc'])\n", 482 | "plt.plot(history.history['val_acc'])\n", 483 | "plt.title(\"Accuracy\")\n", 484 | "plt.xlabel('epoch')\n", 485 | "plt.ylabel('accuracy')\n", 486 | "plt.legend(['train','test'])\n", 487 | "plt.show()" 488 | ] 489 | }, 490 | { 491 | "cell_type": "code", 492 | "execution_count": 102, 493 | "metadata": {}, 494 | "outputs": [], 495 | "source": [ 496 | "model.save('./new_model6.h5')" 497 | ] 498 | }, 499 | { 500 | "cell_type": "code", 501 | "execution_count": 31, 502 | "metadata": {}, 503 | "outputs": [], 504 | "source": [ 505 | "from keras.models import load_model\n" 506 | ] 507 | }, 508 | { 509 | "cell_type": "code", 510 | "execution_count": 32, 511 | "metadata": {}, 512 | "outputs": [], 513 | "source": [ 514 | "m = load_model('./new_model6.h5')" 515 | ] 516 | }, 517 | { 518 | "cell_type": "code", 519 | "execution_count": 33, 520 | "metadata": {}, 521 | "outputs": [], 522 | "source": [ 523 | "test_data = os.listdir('./test_data/')" 524 | ] 525 | }, 526 | { 527 | "cell_type": "code", 528 | "execution_count": 34, 529 | "metadata": {}, 530 | "outputs": [], 531 | "source": [ 532 | "x, y = [], []\n", 533 | "for ix in test_data:\n", 534 | " images = os.listdir('./test_data/' + ix)\n", 535 | " for cx in range(1,201):\n", 536 | " img_path = './test_data/' + ix + '/' + str(cx) + '.jpg'\n", 537 | " img = cv2.imread(img_path, 0)\n", 538 | " img = img.reshape((50,50,1))\n", 539 | " img = img/255.0\n", 540 | " x.append(img)\n", 541 | " y.append(dict_labels[ix])" 542 | ] 543 | }, 544 | { 545 | "cell_type": "code", 546 | "execution_count": 35, 547 | "metadata": {}, 548 | "outputs": [], 549 | "source": [ 550 | "X_t = np.array(x)\n", 551 | "y_t = np.array(y)\n", 552 | "Y_t = np_utils.to_categorical(y_t)" 553 | ] 554 | }, 555 | { 556 | "cell_type": "code", 557 | "execution_count": 36, 558 | "metadata": {}, 559 | "outputs": [ 560 | { 561 | "data": { 562 | "text/plain": [ 563 | "(4800, 50, 50, 1)" 564 | ] 565 | }, 566 | "execution_count": 36, 567 | "metadata": {}, 568 | "output_type": "execute_result" 569 | } 570 | ], 571 | "source": [ 572 | "X_t.shape" 573 | ] 574 | }, 575 | { 576 | "cell_type": "code", 577 | "execution_count": 37, 578 | "metadata": {}, 579 | "outputs": [], 580 | "source": [ 581 | "y_pred = m.predict(X_t)" 582 | ] 583 | }, 584 | { 585 | "cell_type": "code", 586 | "execution_count": 38, 587 | "metadata": {}, 588 | "outputs": [], 589 | "source": [ 590 | "from sklearn.metrics import accuracy_score" 591 | ] 592 | }, 593 | { 594 | "cell_type": "code", 595 | "execution_count": 39, 596 | "metadata": {}, 597 | "outputs": [ 598 | { 599 | "data": { 600 | "text/plain": [ 601 | "0.7985416666666667" 602 | ] 603 | }, 604 | "execution_count": 39, 605 | "metadata": {}, 606 | "output_type": "execute_result" 607 | } 608 | ], 609 | "source": [ 610 | "accuracy_score(Y_t, y_pred.round())" 611 | ] 612 | }, 613 | { 614 | "cell_type": "code", 615 | "execution_count": 40, 616 | "metadata": {}, 617 | "outputs": [], 618 | "source": [ 619 | "from sklearn.metrics import classification_report, confusion_matrix" 620 | ] 621 | }, 622 | { 623 | "cell_type": "code", 624 | "execution_count": 41, 625 | "metadata": {}, 626 | "outputs": [ 627 | { 628 | "name": "stdout", 629 | "output_type": "stream", 630 | "text": [ 631 | " precision recall f1-score support\n", 632 | "\n", 633 | " 0 0.00 0.00 0.00 0\n", 634 | " 1 1.00 0.99 1.00 202\n", 635 | " 2 0.99 0.88 0.93 226\n", 636 | " 3 0.91 1.00 0.95 181\n", 637 | " 4 0.94 0.68 0.79 275\n", 638 | " 5 1.00 0.69 0.82 290\n", 639 | " 6 0.79 0.71 0.75 223\n", 640 | " 7 0.61 0.46 0.52 265\n", 641 | " 8 0.28 0.56 0.38 102\n", 642 | " 9 0.94 0.99 0.97 191\n", 643 | " 10 0.80 0.92 0.85 172\n", 644 | " 11 0.83 1.00 0.91 167\n", 645 | " 12 0.84 0.54 0.66 311\n", 646 | " 13 0.96 0.58 0.72 333\n", 647 | " 14 1.00 1.00 1.00 201\n", 648 | " 15 1.00 0.90 0.95 223\n", 649 | " 16 0.89 0.84 0.86 211\n", 650 | " 17 0.51 0.89 0.65 113\n", 651 | " 18 0.10 0.95 0.18 21\n", 652 | " 19 0.04 1.00 0.07 7\n", 653 | " 20 1.00 1.00 1.00 200\n", 654 | " 21 1.00 0.83 0.90 242\n", 655 | " 22 0.77 0.94 0.85 162\n", 656 | " 23 1.00 0.74 0.85 269\n", 657 | " 24 0.96 0.99 0.98 195\n", 658 | "\n", 659 | "avg / total 0.89 0.80 0.83 4782\n", 660 | "\n" 661 | ] 662 | }, 663 | { 664 | "name": "stderr", 665 | "output_type": "stream", 666 | "text": [ 667 | "c:\\users\\asus\\appdata\\local\\programs\\python\\python36\\lib\\site-packages\\sklearn\\metrics\\classification.py:1135: UndefinedMetricWarning: Precision and F-score are ill-defined and being set to 0.0 in labels with no predicted samples.\n", 668 | " 'precision', 'predicted', average, warn_for)\n", 669 | "c:\\users\\asus\\appdata\\local\\programs\\python\\python36\\lib\\site-packages\\sklearn\\metrics\\classification.py:1137: UndefinedMetricWarning: Recall and F-score are ill-defined and being set to 0.0 in labels with no true samples.\n", 670 | " 'recall', 'true', average, warn_for)\n" 671 | ] 672 | } 673 | ], 674 | "source": [ 675 | "print(classification_report(y_pred.round(), Y_t))" 676 | ] 677 | }, 678 | { 679 | "cell_type": "code", 680 | "execution_count": null, 681 | "metadata": {}, 682 | "outputs": [], 683 | "source": [] 684 | } 685 | ], 686 | "metadata": { 687 | "kernelspec": { 688 | "display_name": "Python 3", 689 | "language": "python", 690 | "name": "python3" 691 | }, 692 | "language_info": { 693 | "codemirror_mode": { 694 | "name": "ipython", 695 | "version": 3 696 | }, 697 | "file_extension": ".py", 698 | "mimetype": "text/x-python", 699 | "name": "python", 700 | "nbconvert_exporter": "python", 701 | "pygments_lexer": "ipython3", 702 | "version": "3.6.5" 703 | } 704 | }, 705 | "nbformat": 4, 706 | "nbformat_minor": 2 707 | } 708 | -------------------------------------------------------------------------------- /new_model6.h5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sid-1998/Sign-Language-Recognition/fd8307b861dc07492de4f35a305576cfcec7e6cb/new_model6.h5 -------------------------------------------------------------------------------- /sample.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sid-1998/Sign-Language-Recognition/fd8307b861dc07492de4f35a305576cfcec7e6cb/sample.jpg --------------------------------------------------------------------------------