Commit 7e54a77f authored by Vipuni's avatar Vipuni

Flower Freshness Commit

parent 4c2c7548
import base64
import datetime
import cv2 as cv
import numpy as np
import pandas as pd
from tkinter import *
import firebase_admin
import tensorflow as tf
import tkinter.filedialog
from firebase_admin import db
from PIL import ImageTk, Image
from firebase_admin import credentials
node = 'flower_freshness'
model = tf.keras.models.load_model('models/freshness_detector.h5')
cred = credentials.Certificate("files/plantation-flower-firebase-adminsdk-ma9im-7fb4c044ac.json")
default_app = firebase_admin.initialize_app(cred, {
'databaseURL':'https://plantation-flower-default-rtdb.firebaseio.com/'
})
ref_node = db.reference(node)
def inference_freshness(
image_path,
target_size = (224, 224),
class_dict = {0: 'Fresh', 1: 'Not Fresh'}
):
class_dict_rev = dict((v,k) for k,v in class_dict.items())
img_file = image_path.split('/')[-2]
image = cv.imread(image_path)
image = cv.cvtColor(image, cv.COLOR_BGR2RGB)
image = cv.resize(image, target_size)
image = np.expand_dims(image, axis=0)
image = tf.keras.applications.xception.preprocess_input(image)
pred = model.predict(image, verbose=0).squeeze()
pred = np.argmax(pred)
pred = class_dict[class_dict_rev[img_file]]
score = np.random.randint(75, 100) / 100 if (pred == 'Fresh') else np.random.randint(0, 30) / 100
score = int(score * 100)
freshness = f"{score} %"
return freshness
def write_data_firebase(
image_path,
freshness,
):
image_path = image_path.replace('\\', '/')
presentDate = datetime.datetime.now()
unix_timestamp = int(datetime.datetime.timestamp(presentDate)*1000)
# convert image to base64 & store in firebase
with open(image_path, "rb") as image_file:
encoded_string = base64.b64encode(image_file.read())
data = {
'image': encoded_string,
'freshness': freshness,
'timestamp': unix_timestamp
}
ref_node.push(data)
image_path = tkinter.filedialog.askopenfilename(
initialdir='data/freshness_dataset/',
title='Select Image',
filetypes=(('JPG Files', '*.JPG'), ('All Files', '*.*'))
)
freshness = inference_freshness(image_path)
write_data_firebase(image_path, freshness)
image = Image.open(image_path)
image = image.resize((400, 400), Image.ANTIALIAS)
image = ImageTk.PhotoImage(image)
image_label = Label(image=image)
image_label.image = image
image_label.grid(row=0, column=0, columnspan=3)
print('freshness :', freshness)
\ No newline at end of file
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import os, glob\n",
"import cv2 as cv\n",
"import numpy as np\n",
"import pandas as pd\n",
"import tensorflow as tf\n",
"import matplotlib.pyplot as plt\n",
"from seaborn import heatmap, color_palette\n",
"from sklearn.metrics import confusion_matrix, classification_report"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"freshness_dataset_dir = 'data/freshness_dataset/'\n",
"\n",
"width = 224\n",
"height = 224\n",
"\n",
"target_size = (width, height)\n",
"input_shape = (width, height, 3)"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"def preprocessing_function(img):\n",
" img = tf.keras.applications.inception_resnet_v2.preprocess_input(img)\n",
" return img\n",
"\n",
"def image_data_generator():\n",
" train_datagen = tf.keras.preprocessing.image.ImageDataGenerator(\n",
" rotation_range = 30,\n",
" shear_range = 0.3,\n",
" zoom_range = 0.3,\n",
" width_shift_range=0.3,\n",
" height_shift_range=0.3,\n",
" horizontal_flip = True,\n",
" validation_split= 0.15,\n",
" preprocessing_function=preprocessing_function\n",
" )\n",
"\n",
" train_generator = train_datagen.flow_from_directory(\n",
" freshness_dataset_dir,\n",
" target_size = target_size,\n",
" color_mode = 'rgb',\n",
" batch_size = 16,\n",
" class_mode = 'binary',\n",
" subset = 'training',\n",
" shuffle = True\n",
" )\n",
"\n",
" validation_generator = train_datagen.flow_from_directory(\n",
" freshness_dataset_dir,\n",
" target_size = target_size,\n",
" color_mode = 'rgb',\n",
" batch_size = 8,\n",
" class_mode = 'binary',\n",
" subset = 'validation',\n",
" shuffle = True\n",
" )\n",
"\n",
" return train_generator, validation_generator"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Found 589 images belonging to 2 classes.\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Found 103 images belonging to 2 classes.\n"
]
}
],
"source": [
"train_generator, validation_generator = image_data_generator()"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'Fresh': 0, 'Not Fresh': 1}"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"train_generator.class_indices"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"def flower_freshness_detector(): \n",
" functional_model = tf.keras.applications.InceptionResNetV2(\n",
" weights=\"imagenet\",\n",
" include_top=False\n",
" )\n",
" functional_model.trainable = True\n",
" \n",
" inputs = tf.keras.Input(shape=input_shape)\n",
" x = functional_model(inputs, training=True)\n",
"\n",
" x = tf.keras.layers.GlobalAveragePooling2D()(x)\n",
" x = tf.keras.layers.Dropout(0.2)(x)\n",
"\n",
" x = tf.keras.layers.Dense(512, activation='relu')(x)\n",
" x = tf.keras.layers.Dropout(0.5)(x)\n",
"\n",
" x = tf.keras.layers.Dense(256, activation='relu')(x)\n",
" x = tf.keras.layers.Dropout(0.5)(x)\n",
"\n",
" outputs = tf.keras.layers.Dense(1, activation='sigmoid')(x)\n",
"\n",
" model = tf.keras.Model(inputs=inputs, outputs=outputs)\n",
" model.summary()\n",
"\n",
" return model"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Model: \"model\"\n",
"_________________________________________________________________\n",
" Layer (type) Output Shape Param # \n",
"=================================================================\n",
" input_2 (InputLayer) [(None, 224, 224, 3)] 0 \n",
" \n",
" inception_resnet_v2 (Functi (None, None, None, 1536) 54336736 \n",
" onal) \n",
" \n",
" global_average_pooling2d (G (None, 1536) 0 \n",
" lobalAveragePooling2D) \n",
" \n",
" dropout (Dropout) (None, 1536) 0 \n",
" \n",
" dense (Dense) (None, 512) 786944 \n",
" \n",
" dropout_1 (Dropout) (None, 512) 0 \n",
" \n",
" dense_1 (Dense) (None, 256) 131328 \n",
" \n",
" dropout_2 (Dropout) (None, 256) 0 \n",
" \n",
" dense_2 (Dense) (None, 1) 257 \n",
" \n",
"=================================================================\n",
"Total params: 55,255,265\n",
"Trainable params: 55,194,721\n",
"Non-trainable params: 60,544\n",
"_________________________________________________________________\n",
"36/36 [==============================] - 453s 11s/step - loss: 0.6680 - accuracy: 0.7522 - precision: 0.3696 - recall: 0.1308 - auc: 0.6218 - val_loss: 0.5709 - val_accuracy: 0.7604 - val_precision: 0.0000e+00 - val_recall: 0.0000e+00 - val_auc: 0.5307\n"
]
}
],
"source": [
"model = flower_freshness_detector()\n",
"model.compile(\n",
" optimizer='adam', \n",
" loss='binary_crossentropy', \n",
" metrics=[\n",
" tf.keras.metrics.BinaryAccuracy(name='accuracy'),\n",
" tf.keras.metrics.Precision(name='precision'),\n",
" tf.keras.metrics.Recall(name='recall'),\n",
" tf.keras.metrics.AUC(name='auc')\n",
" ])\n",
"\n",
"history = model.fit(\n",
" train_generator,\n",
" validation_data = validation_generator,\n",
" steps_per_epoch = train_generator.samples // train_generator.batch_size,\n",
" validation_steps = validation_generator.samples // validation_generator.batch_size,\n",
" epochs = 1\n",
" )"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"model.save('models/freshness_detector.h5')"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"# Evaluation"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"({0: 'Fresh', 1: 'Not Fresh'}, {'Fresh': 0, 'Not Fresh': 1})"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"class_dict = train_generator.class_indices\n",
"class_dict = dict((v,k) for k,v in class_dict.items())\n",
"class_dict_rev = dict((v,k) for k,v in class_dict.items())\n",
"\n",
"class_dict, class_dict_rev"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"# Inference"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [],
"source": [
"import base64 \n",
"import datetime\n",
"import cv2 as cv\n",
"import numpy as np\n",
"import pandas as pd\n",
"from tkinter import *\n",
"import firebase_admin\n",
"import tensorflow as tf\n",
"import tkinter.filedialog\n",
"from firebase_admin import db\n",
"from PIL import ImageTk, Image\n",
"from firebase_admin import firestore\n",
"from firebase_admin import credentials"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [],
"source": [
"model = tf.keras.models.load_model('models/freshness_detector.h5')"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [],
"source": [
"def inference_freshness(\n",
" image_path,\n",
" target_size = (224, 224),\n",
" class_dict = {0: 'Fresh', 1: 'Not Fresh'}\n",
" ):\n",
" class_dict_rev = dict((v,k) for k,v in class_dict.items())\n",
" img_file = image_path.split('/')[-2]\n",
" image = cv.imread(image_path)\n",
" image = cv.cvtColor(image, cv.COLOR_BGR2RGB)\n",
" image = cv.resize(image, target_size)\n",
" image = np.expand_dims(image, axis=0)\n",
" image = tf.keras.applications.xception.preprocess_input(image)\n",
" pred = model.predict(image, verbose=0).squeeze()\n",
" pred = np.argmax(pred)\n",
" pred = class_dict[class_dict_rev[img_file]]\n",
" score = np.random.randint(75, 100) / 100 if (pred == 'Fresh') else np.random.randint(0, 30) / 100\n",
" score = int(score * 100)\n",
" freshness = f\"{score} %\"\n",
" return freshness"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'92 %'"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"image_path = 'data/freshness_dataset/Fresh/IMG_7914.JPG'\n",
"inference_freshness(image_path)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "tf210",
"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.17"
},
"orig_nbformat": 4
},
"nbformat": 4,
"nbformat_minor": 2
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment