-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
5253768
commit 36e5d23
Showing
9 changed files
with
114 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
SECRET_KEY = 'XNet@123' | ||
UPLOAD_FOLDER = 'webapp/uploads' | ||
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg'} | ||
MAX_CONTENT_LENGTH = 8 * 1000 * 1000 |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import os | ||
from webapp import webapp | ||
from flask import render_template, flash, request, session | ||
|
||
from werkzeug.utils import secure_filename | ||
|
||
from webapp import xnet | ||
|
||
@webapp.route("/", methods = ['GET']) | ||
def index(): | ||
# Routine to render the home page of our website | ||
return render_template("index.html") | ||
|
||
@webapp.route("/predict/", methods = ['GET']) | ||
def predict(): | ||
# Routine to route requests from the predict page to display the upload dialog box | ||
return render_template("predict.html") | ||
|
||
@webapp.route("/upload/", methods = ['POST', 'GET']) | ||
def upload(): | ||
# Routine to deal with the uploaded form data i.e. image in this case | ||
# Fetches the uploaded image, runs basic validations and saves to the specified directory | ||
def __allowed_file(filename): | ||
return '.' in filename and \ | ||
filename.rsplit('.', 1)[1].lower() in webapp.config["ALLOWED_EXTENSIONS"] | ||
|
||
# Clear any existing flash messages from the session | ||
session.pop('_flashes', None) | ||
|
||
# Run sanity checks | ||
if request.method == 'POST': | ||
print("Passed request method sanity check!") | ||
# First check whether or not the request contains our desired file | ||
if 'file' not in request.files: | ||
# Flash an error message and redirect to the same page | ||
flash('No file part! Try again!', 'error') | ||
return render_template("predict.html") | ||
|
||
print("Passed file exist sanity check!") | ||
uploaded_file = request.files['file'] | ||
|
||
# Check for the allowed file types and save to the local disk | ||
if uploaded_file and __allowed_file(uploaded_file.filename): | ||
path = os.path.join(webapp.config['UPLOAD_FOLDER'], | ||
secure_filename(uploaded_file.filename)) | ||
uploaded_file.save(path) | ||
else: | ||
# Flash an error message and redirect to the same page | ||
flash('The file must be of one of the accepted formats only! Try again!', 'error') | ||
return render_template("predict.html") | ||
print("Passed file extension and save check!") | ||
|
||
# Next, run the XNet prediction service | ||
result = xnet.predict(webapp.config['XNET_MODEL'], path = path) | ||
print("Passed XNet prediction check!") | ||
print(result) | ||
return render_template("upload.html", filename=uploaded_file.filename, result=result) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import os | ||
import cv2 | ||
import numpy as np | ||
import tensorflow as tf | ||
from keras.models import model_from_json | ||
from tensorflow.keras.optimizers import Adam | ||
|
||
def load_model(path:str='model'): | ||
# Routine to load the XNet model for inference | ||
# Reading the model architecture from the model json file | ||
json_file = open(os.path.join(path, 'XNet.json'),'r') | ||
loaded_model_json = json_file.read() | ||
json_file.close() | ||
|
||
# Use Keras model_from_json to restore the architecture | ||
loaded_model = model_from_json(loaded_model_json) | ||
print("\nSuccessfully restored model architecture!") | ||
|
||
# Load weights into the reconstructed model | ||
loaded_model.load_weights(os.path.join(path, 'XNet.h5')) | ||
print("Successfully restored model weights!") | ||
|
||
# Compile and return the loaded model | ||
optimizer = Adam(learning_rate=0.0001, decay=1e-5) | ||
loaded_model.compile(loss='binary_crossentropy',optimizer=optimizer,metrics=['accuracy']) | ||
print("Successfully compiled model!\n") | ||
|
||
return loaded_model | ||
|
||
def predict(model, path:str='uploads'): | ||
# Transform each stock image into a 224x224 RGB image and | ||
# then into a vector of the same size but normalized between 0 and 1 | ||
img = cv2.imread(path) | ||
img = cv2.resize(img, (224,224)) | ||
|
||
if img.shape[2] ==1: | ||
img = np.dstack([img, img, img]) | ||
|
||
# Normalize the input image and convert into a tensor for inference | ||
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) | ||
img = img.astype(np.float32)/255. | ||
X = np.expand_dims(img, axis=0) | ||
X = np.array(X) | ||
X = tf.convert_to_tensor(X) | ||
|
||
# Run inference | ||
y = model.predict(X) | ||
file_name = os.path.basename(path) | ||
if y[0][0] > 0.5: | ||
result = file_name + ' is PNEUMONIA with {}% prediction confidence!'.format(round(y[0][0]*100)) | ||
else: | ||
result = file_name + ' is NORMAL with {}% prediction confidence!'.format(round((1-y[0][0])*100)) | ||
return result |