Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
514 changes: 514 additions & 0 deletions .gitignore

Large diffs are not rendered by default.

85 changes: 85 additions & 0 deletions Ai/aiModel.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import keras
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout
#from keras.preprocessing.image import ImageDataGenerator
from keras.src.legacy.preprocessing.image import ImageDataGenerator
from keras.layers import GlobalAveragePooling2D
import matplotlib.pyplot as plt

# Food Snap AI Model

model = Sequential([

# Conv2D extracts features like edges, texttures, colors of fruits and its patterns
Conv2D(32, (3,3), activation="relu", input_shape=(244,244,3)),
# Pooling layer used to reduce dimenstions of feature map from previous layers before passing to next layer, Make computation faster while keeping relevant info
MaxPooling2D(pool_size=(2,2)),

Conv2D(64, (3,3), activation='relu'),
MaxPooling2D(pool_size=(2,2)),

Conv2D(128, (3,3), activation='relu'),
MaxPooling2D(pool_size=(2,2)),

GlobalAveragePooling2D(),
# converts 2D feature maps into a single vector for classification
Flatten(),

Dense(128, activation='relu'),
# prevents overfitting, so model generalizes better.
Dropout(0.5), # Reduces overfitting
# Uses Softmax for multi-class classification
Dense(3, activation="softmax") # 3 output classes (Apple, Banana, Mango)
])

model.compile(
optimizer='adam',
loss='categorical_crossentropy',
metrics=['accuracy']
)

#Data Augmentation
train_datagen = ImageDataGenerator(
rescale =1./255, #Normalize pixel values (0 to 1 instead of 0 to 255)
rotation_range = 20, # Randomly rotate image by up to 20 degress
width_shift_range = 0.2, # Shift image width randomly by 20% (left or right)
height_shift_range = 0.2, # Shift image height randomly by 20% (up or down)
horizontal_flip = True, # Flip images randomly (left-right)
validation_split = 0.2 # reserve 20% data for validation
)

#Loading Images from folder
train_generator = train_datagen.flow_from_directory(
'dataset/',
target_size = (224, 224),
batch_size = 32,
class_mode = 'categorical', #Automatically assigns labels based on folder names
subset = 'training' #uses 80% images for training
)

# Preparing Validation Data
val_generator = train_datagen.flow_from_directory(
'dataset/',
target_size = (244, 244),
batch_size = 32,
class_mode = 'categorical',
subset = 'validation'
)

#Start CNN training
history = model.fit(
train_generator,
validation_data= val_generator,
epochs= 30
)

# Elavuate & Visualize results
plt.plot(history.history['accuracy'], label='Training Accuracy')
plt.plot(history.history['val_accuracy'], label='Validation Accuracy')
plt.xlabel('Epochs'),
plt.ylabel('Accuracy')
plt.legend()
plt.show()

# Save model
model.save("food_classifier_model_v2.h5")
39 changes: 39 additions & 0 deletions Ai/aiModelApp.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
from flask import Flask, request, jsonify
from keras.models import load_model
import numpy as np
from PIL import Image

# To Run flask --app .\aiModelApp.py run

app = Flask(__name__)
model = load_model("food_classifier_model_v2.h5")

def preprocess_image(image):
image = Image.open(image).resize((224,224)) #Resize to match CNN input
image = np.array(image) / 255.0 #normalize pixel value
image = np.expand_dims(image, axis=0)
return image

@app.route('/detect-image', methods=['POST'])
def detectImage():
file = request.files['image']
processed_image = preprocess_image(file)

prediction = model.predict(processed_image)
food_classes = ['Apple', 'Banana', 'Mango']

predicted_index = np.argmax(prediction)
predicted_class = food_classes[predicted_index]
confidence_score = float(prediction[0][predicted_index] * 100)

# convet full prediction into dict
prediction_dict = {food_classes[i]: round(float(prediction[0][i])* 100, 2) for i in range(len(food_classes))}

return jsonify({
"prediction": predicted_class,
"confidence": round(confidence_score, 2), #rounded to 2 decimal places
"fullPrediction": prediction_dict #show all
})

if __name__ == '__main__':
app.run(port=5000, debug=True)
Binary file added Ai/dataset/apple/apple1.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Ai/dataset/apple/apple10.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Ai/dataset/apple/apple2.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Ai/dataset/apple/apple3.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Ai/dataset/apple/apple4.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Ai/dataset/apple/apple5.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Ai/dataset/apple/apple6.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Ai/dataset/apple/apple7.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Ai/dataset/apple/apple8.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Ai/dataset/apple/apple9.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Ai/dataset/banana/banana1.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Ai/dataset/banana/banana10.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Ai/dataset/banana/banana2.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Ai/dataset/banana/banana3.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Ai/dataset/banana/banana4.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Ai/dataset/banana/banana5.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Ai/dataset/banana/banana6.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Ai/dataset/banana/banana7.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Ai/dataset/banana/banana8.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Ai/dataset/banana/banana9.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 14 additions & 0 deletions Ai/dataset/dataPreProcess.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import cv2
import os
import tensorflow as tf

folderList = ["apple", "banana", "mango"]

for folder in folderList:
for fileName in os.listdir(f"dataset/{folder}"):
image = cv2.imread(f"dataset/{folder}/{fileName}")
resized = cv2.resize(image, (224, 224)) #Resize to match CNN input

cv2.imwrite(f"dataset/{folder}/{fileName}", resized)


Binary file added Ai/dataset/mango/mango1.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Ai/dataset/mango/mango10.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Ai/dataset/mango/mango2.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Ai/dataset/mango/mango3.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Ai/dataset/mango/mango4.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Ai/dataset/mango/mango5.jpg
Binary file added Ai/dataset/mango/mango6.jpg
Binary file added Ai/dataset/mango/mango7.jpg
Binary file added Ai/dataset/mango/mango8.jpg
Binary file added Ai/dataset/mango/mango9.jpg
Empty file added Ai/dataset/webScraper.py
Empty file.
Binary file added Ai/food_classifier_model.h5
Binary file not shown.
Binary file added Ai/food_classifier_model_v2.h5
Binary file not shown.
17 changes: 17 additions & 0 deletions Client/.editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Editor configuration, see https://editorconfig.org
root = true

[*]
charset = utf-8
indent_style = space
indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true

[*.ts]
quote_type = single
ij_typescript_use_double_quotes = false

[*.md]
max_line_length = off
trim_trailing_whitespace = false
42 changes: 42 additions & 0 deletions Client/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# See https://docs.github.com/get-started/getting-started-with-git/ignoring-files for more about ignoring files.

# Compiled output
/dist
/tmp
/out-tsc
/bazel-out

# Node
/node_modules
npm-debug.log
yarn-error.log

# IDEs and editors
.idea/
.project
.classpath
.c9/
*.launch
.settings/
*.sublime-workspace

# Visual Studio Code
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
.history/*

# Miscellaneous
/.angular/cache
.sass-cache/
/connect.lock
/coverage
/libpeerconnection.log
testem.log
/typings

# System files
.DS_Store
Thumbs.db
4 changes: 4 additions & 0 deletions Client/.vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=827846
"recommendations": ["angular.ng-template"]
}
20 changes: 20 additions & 0 deletions Client/.vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "ng serve",
"type": "chrome",
"request": "launch",
"preLaunchTask": "npm: start",
"url": "http://localhost:4200/"
},
{
"name": "ng test",
"type": "chrome",
"request": "launch",
"preLaunchTask": "npm: test",
"url": "http://localhost:9876/debug.html"
}
]
}
42 changes: 42 additions & 0 deletions Client/.vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{
// For more information, visit: https://go.microsoft.com/fwlink/?LinkId=733558
"version": "2.0.0",
"tasks": [
{
"type": "npm",
"script": "start",
"isBackground": true,
"problemMatcher": {
"owner": "typescript",
"pattern": "$tsc",
"background": {
"activeOnStart": true,
"beginsPattern": {
"regexp": "(.*?)"
},
"endsPattern": {
"regexp": "bundle generation complete"
}
}
}
},
{
"type": "npm",
"script": "test",
"isBackground": true,
"problemMatcher": {
"owner": "typescript",
"pattern": "$tsc",
"background": {
"activeOnStart": true,
"beginsPattern": {
"regexp": "(.*?)"
},
"endsPattern": {
"regexp": "bundle generation complete"
}
}
}
}
]
}
27 changes: 27 additions & 0 deletions Client/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Client

This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 18.2.11.

## Development server

Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The application will automatically reload if you change any of the source files.

## Code scaffolding

Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`.

## Build

Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory.

## Running unit tests

Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).

## Running end-to-end tests

Run `ng e2e` to execute the end-to-end tests via a platform of your choice. To use this command, you need to first add a package that implements end-to-end testing capabilities.

## Further help

To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page.
Loading