{ "cells": [ { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "# remove warning message\n", "import os\n", "os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'\n", "\n", "# required library\n", "import cv2\n", "import numpy as np\n", "import matplotlib.pyplot as plt\n", "import matplotlib.gridspec as gridspec\n", "from local_utils import detect_lp\n", "from os.path import splitext,basename\n", "from keras.models import model_from_json\n", "from keras.preprocessing.image import load_img, img_to_array\n", "from keras.applications.mobilenet_v2 import preprocess_input\n", "from sklearn.preprocessing import LabelEncoder\n", "import glob" ] }, { "cell_type": "code", "execution_count": 63, "metadata": {}, "outputs": [], "source": [ "def load_model(path):\n", " try:\n", " path = splitext(path)[0]\n", " with open('%s.json' % path, 'r') as json_file:\n", " model_json = json_file.read()\n", " model = model_from_json(model_json, custom_objects={})\n", " model.load_weights('%s.h5' % path)\n", " print(\"Loading model successfully...\")\n", " return model\n", " except Exception as e:\n", " print(e)" ] }, { "cell_type": "code", "execution_count": 64, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Loading model successfully...\n" ] } ], "source": [ "wpod_net_path = \"wpod-net.json\"\n", "wpod_net = load_model(wpod_net_path)" ] }, { "cell_type": "code", "execution_count": 74, "metadata": {}, "outputs": [], "source": [ "def preprocess_image(image_path,resize=False):\n", " img = cv2.imread(image_path)\n", " img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n", " img = img / 255\n", " if resize:\n", " img = cv2.resize(img, (224,224))\n", " return img\n", "\n", "def get_plate(image_path, Dmax=650, Dmin = 270):\n", " vehicle = preprocess_image(image_path)\n", " ratio = float(max(vehicle.shape[:2])) / min(vehicle.shape[:2])\n", " side = int(ratio * Dmin)\n", " bound_dim = min(side, Dmax)\n", " _ , LpImg, _, cor = detect_lp(wpod_net, vehicle, bound_dim, lp_threshold=0.5)\n", " return vehicle, LpImg, cor\n", "\n", "test_image_path = \"Plate_examples/india_car_plate.jpg\"\n", "vehicle, LpImg,cor = get_plate(test_image_path)\n", "\n" ] }, { "cell_type": "code", "execution_count": 75, "metadata": {}, "outputs": [], "source": [ "if (len(LpImg)): #check if there is at least one license image\n", " # Scales, calculates absolute values, and converts the result to 8-bit.\n", " plate_image = cv2.convertScaleAbs(LpImg[0], alpha=(255.0))\n", " \n", " # convert to grayscale and blur the image\n", " gray = cv2.cvtColor(plate_image, cv2.COLOR_BGR2GRAY)\n", " blur = cv2.GaussianBlur(gray,(7,7),0)\n", " \n", " # Applied inversed thresh_binary \n", " binary = cv2.threshold(blur, 180, 255,\n", " cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]\n", " \n", " kernel3 = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))\n", " thre_mor = cv2.morphologyEx(binary, cv2.MORPH_DILATE, kernel3)\n", "\n", " \n", "\n", "# plt.savefig(\"threshding.png\", dpi=300)" ] }, { "cell_type": "code", "execution_count": 77, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Detect 10 letters...\n" ] }, { "data": { "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# Create sort_contours() function to grab the contour of each digit from left to right\n", "def sort_contours(cnts,reverse = False):\n", " i = 0\n", " boundingBoxes = [cv2.boundingRect(c) for c in cnts]\n", " (cnts, boundingBoxes) = zip(*sorted(zip(cnts, boundingBoxes),\n", " key=lambda b: b[1][i], reverse=reverse))\n", " return cnts\n", "\n", "cont, _ = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)\n", "\n", "# creat a copy version \"test_roi\" of plat_image to draw bounding box\n", "test_roi = plate_image.copy()\n", "\n", "# Initialize a list which will be used to append charater image\n", "crop_characters = []\n", "\n", "# define standard width and height of character\n", "digit_w, digit_h = 30, 60\n", "\n", "for c in sort_contours(cont):\n", " (x, y, w, h) = cv2.boundingRect(c)\n", " ratio = h/w\n", " if 1<=ratio<=3.5: # Only select contour with defined ratio\n", " if h/plate_image.shape[0]>=0.5: # Select contour which has the height larger than 50% of the plate\n", " # Draw bounding box arroung digit number\n", " cv2.rectangle(test_roi, (x, y), (x + w, y + h), (0, 255,0), 2)\n", "\n", " # Sperate number and gibe prediction\n", " curr_num = thre_mor[y:y+h,x:x+w]\n", " curr_num = cv2.resize(curr_num, dsize=(digit_w, digit_h))\n", " _, curr_num = cv2.threshold(curr_num, 220, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)\n", " crop_characters.append(curr_num)\n", "\n", "print(\"Detect {} letters...\".format(len(crop_characters)))\n", "fig = plt.figure(figsize=(10,6))\n", "#plt.axis(False)\n", "#plt.imshow(test_roi)\n", "#plt.savefig('grab_digit_contour.png',dpi=300)" ] }, { "cell_type": "code", "execution_count": 78, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[INFO] Model loaded successfully...\n", "[INFO] Labels loaded successfully...\n" ] } ], "source": [ "# Load model architecture, weight and labels\n", "json_file = open('MobileNets_character_recognition.json', 'r')\n", "loaded_model_json = json_file.read()\n", "json_file.close()\n", "model = model_from_json(loaded_model_json)\n", "model.load_weights(\"License_character_recognition_weight.h5\")\n", "print(\"[INFO] Model loaded successfully...\")\n", "\n", "labels = LabelEncoder()\n", "labels.classes_ = np.load('license_character_classes.npy')\n", "print(\"[INFO] Labels loaded successfully...\")" ] }, { "cell_type": "code", "execution_count": 79, "metadata": {}, "outputs": [], "source": [ "# pre-processing input images and pedict with model\n", "def predict_from_model(image,model,labels):\n", " image = cv2.resize(image,(80,80))\n", " image = np.stack((image,)*3, axis=-1)\n", " prediction = labels.inverse_transform([np.argmax(model.predict(image[np.newaxis,:]))])\n", " return prediction" ] }, { "cell_type": "code", "execution_count": 80, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "MH12DE1433\n" ] }, { "data": { "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "fig = plt.figure(figsize=(15,3))\n", "cols = len(crop_characters)\n", "grid = gridspec.GridSpec(ncols=cols,nrows=1,figure=fig)\n", "\n", "final_string = ''\n", "for i,character in enumerate(crop_characters):\n", " #fig.add_subplot(grid[i])\n", " title = np.array2string(predict_from_model(character,model,labels))\n", " #plt.title('{}'.format(title.strip(\"'[]\"),fontsize=20))\n", " final_string+=title.strip(\"'[]\")\n", " #plt.axis(False)\n", " #plt.imshow(character,cmap='gray')\n", "\n", "print(final_string)\n" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[[ 85 57 76]\n", " [ 93 65 84]\n", " [ 95 68 84]\n", " ...\n", " [173 151 145]\n", " [170 148 143]\n", " [169 147 142]]\n", "\n", " [[ 85 59 75]\n", " [ 94 69 83]\n", " [ 99 74 88]\n", " ...\n", " [173 151 145]\n", " [171 149 144]\n", " [170 148 143]]\n", "\n", " [[113 92 101]\n", " [119 98 106]\n", " [122 101 109]\n", " ...\n", " [174 152 146]\n", " [172 150 145]\n", " [171 149 144]]\n", "\n", " ...\n", "\n", " [[204 216 228]\n", " [201 213 223]\n", " [206 218 228]\n", " ...\n", " [102 76 62]\n", " [ 94 68 54]\n", " [ 92 66 52]]\n", "\n", " [[206 217 231]\n", " [200 211 225]\n", " [205 216 230]\n", " ...\n", " [ 99 73 61]\n", " [ 92 68 56]\n", " [ 93 69 57]]\n", "\n", " [[216 226 243]\n", " [227 237 254]\n", " [221 232 246]\n", " ...\n", " [ 92 66 54]\n", " [ 86 62 50]\n", " [ 91 67 55]]]\n" ] } ], "source": [ "\n", "img = cv2.imread(\"C:/Users/JomerJuan/Documents/Deep Learning/Plate Number Recognition/Plate_examples/germany_car_plate.jpg\")\n", "\n", "img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n", "print(img)" ] } ], "metadata": { "interpreter": { "hash": "6e8d6bc3219a43fccaa16aa1e841da92ab3f69dc51828f7269e34e3f0779a8af" }, "kernelspec": { "display_name": "Python 3.8.3 ('Plate_Number_Recognition': venv)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.3" }, "orig_nbformat": 4 }, "nbformat": 4, "nbformat_minor": 2 }