├── ML Model ├── .gitkeep ├── Models │ ├── 2-conv-64-nodes-2-dense-1655332877.model.h5 │ └── PneumoniaClassifierV1.model │ │ ├── keras_metadata.pb │ │ ├── saved_model.pb │ │ └── variables │ │ ├── variables.data-00000-of-00001 │ │ └── variables.index └── TRAINING.ipynb ├── README.md ├── backend ├── .gitkeep ├── Model │ └── 2-conv-64-nodes-2-dense-1655332877.model.h5 ├── __pycache__ │ ├── main.cpython-36.pyc │ └── ml.cpython-36.pyc ├── main.py ├── ml.py └── tmp.jpg ├── environment.yml └── frontend ├── .gitignore ├── README.md ├── package-lock.json ├── package.json ├── public ├── favicon.ico ├── index.html ├── logo192.png ├── logo512.png ├── manifest.json └── robots.txt └── src ├── App.js ├── index.css ├── index.js └── logo.svg /ML Model/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/upes-open/OSC-Medical-Analysis-Application-Using-ML/a55bf84d7ee30c8e47fcfb70e1ffd2e866ce7e10/ML Model/.gitkeep -------------------------------------------------------------------------------- /ML Model/Models/2-conv-64-nodes-2-dense-1655332877.model.h5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/upes-open/OSC-Medical-Analysis-Application-Using-ML/a55bf84d7ee30c8e47fcfb70e1ffd2e866ce7e10/ML Model/Models/2-conv-64-nodes-2-dense-1655332877.model.h5 -------------------------------------------------------------------------------- /ML Model/Models/PneumoniaClassifierV1.model/keras_metadata.pb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/upes-open/OSC-Medical-Analysis-Application-Using-ML/a55bf84d7ee30c8e47fcfb70e1ffd2e866ce7e10/ML Model/Models/PneumoniaClassifierV1.model/keras_metadata.pb -------------------------------------------------------------------------------- /ML Model/Models/PneumoniaClassifierV1.model/saved_model.pb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/upes-open/OSC-Medical-Analysis-Application-Using-ML/a55bf84d7ee30c8e47fcfb70e1ffd2e866ce7e10/ML Model/Models/PneumoniaClassifierV1.model/saved_model.pb -------------------------------------------------------------------------------- /ML Model/Models/PneumoniaClassifierV1.model/variables/variables.data-00000-of-00001: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/upes-open/OSC-Medical-Analysis-Application-Using-ML/a55bf84d7ee30c8e47fcfb70e1ffd2e866ce7e10/ML Model/Models/PneumoniaClassifierV1.model/variables/variables.data-00000-of-00001 -------------------------------------------------------------------------------- /ML Model/Models/PneumoniaClassifierV1.model/variables/variables.index: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/upes-open/OSC-Medical-Analysis-Application-Using-ML/a55bf84d7ee30c8e47fcfb70e1ffd2e866ce7e10/ML Model/Models/PneumoniaClassifierV1.model/variables/variables.index -------------------------------------------------------------------------------- /ML Model/TRAINING.ipynb: -------------------------------------------------------------------------------- 1 | {"nbformat":4,"nbformat_minor":0,"metadata":{"colab":{"name":"TRAINING-1.ipynb","provenance":[],"collapsed_sections":[],"authorship_tag":"ABX9TyMag7xR6xHAPCIXRsIqNeU/"},"kernelspec":{"name":"python3","display_name":"Python 3"},"language_info":{"name":"python"},"accelerator":"GPU","gpuClass":"standard"},"cells":[{"cell_type":"code","execution_count":4,"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"slZ0-IXX5_UU","executionInfo":{"status":"ok","timestamp":1655332755448,"user_tz":-330,"elapsed":3113,"user":{"displayName":"Siddhant Singh","userId":"17564338630205346662"}},"outputId":"5bf456cb-c963-4a74-f0c0-ee847889629e"},"outputs":[{"output_type":"stream","name":"stdout","text":["Drive already mounted at /content/gdrive; to attempt to forcibly remount, call drive.mount(\"/content/gdrive\", force_remount=True).\n"]}],"source":["from google.colab import drive\n","drive.mount('/content/gdrive')"]},{"cell_type":"code","source":["cd MyDrive/OSC/DATA3"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"ewwFhc106nAz","executionInfo":{"status":"ok","timestamp":1655332803775,"user_tz":-330,"elapsed":354,"user":{"displayName":"Siddhant Singh","userId":"17564338630205346662"}},"outputId":"ab0eb868-9a58-4258-f08d-5dd7c2538c1d"},"execution_count":9,"outputs":[{"output_type":"stream","name":"stdout","text":["/content/gdrive/MyDrive/OSC/DATA3\n"]}]},{"cell_type":"code","source":["#import stuff\n","import numpy as np\n","from tensorflow import keras\n","from tensorflow.keras import layers\n","import pickle\n","from tensorflow.keras.callbacks import TensorBoard\n","import tensorflow as tf\n","import time\n","from sklearn.utils import shuffle\n"],"metadata":{"id":"jUuRx_9j60Wr","executionInfo":{"status":"ok","timestamp":1655332809552,"user_tz":-330,"elapsed":341,"user":{"displayName":"Siddhant Singh","userId":"17564338630205346662"}}},"execution_count":10,"outputs":[]},{"cell_type":"code","source":["#import data\n","pickle_in = open(\"X.pickle\",\"rb\")\n","X = pickle.load(pickle_in)\n","\n","pickle_in = open(\"Y.pickle\",\"rb\")\n","Y = pickle.load(pickle_in)\n","\n","X = np.array(X)\n","Y = np.array(Y)\n","\n","print(X[0])\n","\n","#shuffle data\n","X, Y = shuffle(X, Y, random_state=0)\n","\n","print(X.shape)"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"Hxmlhbkt8TBw","executionInfo":{"status":"ok","timestamp":1655332858016,"user_tz":-330,"elapsed":43377,"user":{"displayName":"Siddhant Singh","userId":"17564338630205346662"}},"outputId":"c57a294d-e111-456b-e87e-efd438efb0f7"},"execution_count":11,"outputs":[{"output_type":"stream","name":"stdout","text":["[[0. 0. 0. ... 0.04296875 0.03125 0.015625 ]\n"," [0. 0. 0. ... 0.0390625 0.02734375 0.01171875]\n"," [0. 0. 0. ... 0.03515625 0.0234375 0.01171875]\n"," ...\n"," [0. 0. 0. ... 0. 0. 0. ]\n"," [0. 0. 0. ... 0. 0. 0. ]\n"," [0. 0. 0. ... 0. 0. 0. ]]\n","(5856, 300, 300)\n"]}]},{"cell_type":"code","source":["input_shape = (300, 300, 1)\n","dense_layers = [2]\n","layer_sizes = [64]\n","conv_layers = [2]\n","\n","batch_size = 100\n","epochs = 40\n","\n","\n","\n","for dense_layer in dense_layers:\n"," for layer_size in layer_sizes:\n"," for conv_layer in conv_layers:\n"," NAME = \"{}-conv-{}-nodes-{}-dense-{}\".format(conv_layer, layer_size, dense_layer, int(time.time()))\n"," print(NAME)\n"," # tensorboard = TensorBoard(log_dir=\"final-logs/{}\".format(NAME))\n"," # stopping = tf.keras.callbacks.EarlyStopping(monitor='loss', patience=5)\n","\n"," model = keras.Sequential()\n","\n"," #conv layers\n"," model.add(layers.Conv2D(layer_size, (3, 3), input_shape=input_shape))\n"," model.add(layers.Activation('relu'))\n"," model.add(layers.MaxPooling2D(pool_size=(2, 2)))\n","\n"," for i in range(conv_layer-1):\n"," model.add(layers.Conv2D(layer_size, (3, 3),strides=(3, 3)))\n"," model.add(layers.Activation('relu'))\n"," model.add(layers.MaxPooling2D(pool_size=(2, 2)))\n","\n"," #dense layers\n"," model.add(layers.Flatten()) \n"," for j in range(dense_layer):\n"," model.add(layers.Dense(layer_size, activation=\"relu\"))\n","\n"," \n","\n"," #output layer\n"," model.add(layers.Dense(1, activation=\"sigmoid\"))\n","\n","\n"," model.summary()\n"," model.compile(loss=\"binary_crossentropy\", optimizer=\"adam\", metrics=[\"accuracy\"])\n"," # model.fit(X, Y, batch_size=batch_size, epochs=epochs, validation_split=0.3,callbacks=[stopping,tensorboard])\n"," model.fit(X, Y, batch_size=batch_size, epochs=epochs, validation_split=0.3)\n","\n","\n"," model.save(\"final/\" + NAME + \".model\") \n"," \n","\n"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"ba1tFROO75cy","executionInfo":{"status":"ok","timestamp":1655333342325,"user_tz":-330,"elapsed":464913,"user":{"displayName":"Siddhant Singh","userId":"17564338630205346662"}},"outputId":"1cd84ac5-fb5d-4c1f-ded3-f7434f550e6a"},"execution_count":12,"outputs":[{"output_type":"stream","name":"stdout","text":["2-conv-64-nodes-2-dense-1655332877\n","Model: \"sequential\"\n","_________________________________________________________________\n"," Layer (type) Output Shape Param # \n","=================================================================\n"," conv2d (Conv2D) (None, 298, 298, 64) 640 \n"," \n"," activation (Activation) (None, 298, 298, 64) 0 \n"," \n"," max_pooling2d (MaxPooling2D (None, 149, 149, 64) 0 \n"," ) \n"," \n"," conv2d_1 (Conv2D) (None, 49, 49, 64) 36928 \n"," \n"," activation_1 (Activation) (None, 49, 49, 64) 0 \n"," \n"," max_pooling2d_1 (MaxPooling (None, 24, 24, 64) 0 \n"," 2D) \n"," \n"," flatten (Flatten) (None, 36864) 0 \n"," \n"," dense (Dense) (None, 64) 2359360 \n"," \n"," dense_1 (Dense) (None, 64) 4160 \n"," \n"," dense_2 (Dense) (None, 1) 65 \n"," \n","=================================================================\n","Total params: 2,401,153\n","Trainable params: 2,401,153\n","Non-trainable params: 0\n","_________________________________________________________________\n","Epoch 1/40\n","41/41 [==============================] - 25s 328ms/step - loss: 0.4366 - accuracy: 0.7931 - val_loss: 0.3106 - val_accuracy: 0.8589\n","Epoch 2/40\n","41/41 [==============================] - 11s 268ms/step - loss: 0.1883 - accuracy: 0.9244 - val_loss: 0.1919 - val_accuracy: 0.9237\n","Epoch 3/40\n","41/41 [==============================] - 11s 270ms/step - loss: 0.1389 - accuracy: 0.9483 - val_loss: 0.1579 - val_accuracy: 0.9431\n","Epoch 4/40\n","41/41 [==============================] - 11s 269ms/step - loss: 0.1120 - accuracy: 0.9573 - val_loss: 0.1505 - val_accuracy: 0.9488\n","Epoch 5/40\n","41/41 [==============================] - 11s 270ms/step - loss: 0.1212 - accuracy: 0.9534 - val_loss: 0.1484 - val_accuracy: 0.9408\n","Epoch 6/40\n","41/41 [==============================] - 11s 270ms/step - loss: 0.0832 - accuracy: 0.9705 - val_loss: 0.1892 - val_accuracy: 0.9351\n","Epoch 7/40\n","41/41 [==============================] - 11s 269ms/step - loss: 0.0771 - accuracy: 0.9717 - val_loss: 0.1619 - val_accuracy: 0.9402\n","Epoch 8/40\n","41/41 [==============================] - 11s 269ms/step - loss: 0.0658 - accuracy: 0.9761 - val_loss: 0.1599 - val_accuracy: 0.9437\n","Epoch 9/40\n","41/41 [==============================] - 11s 269ms/step - loss: 0.0496 - accuracy: 0.9822 - val_loss: 0.1774 - val_accuracy: 0.9380\n","Epoch 10/40\n","41/41 [==============================] - 11s 274ms/step - loss: 0.0440 - accuracy: 0.9876 - val_loss: 0.1899 - val_accuracy: 0.9402\n","Epoch 11/40\n","41/41 [==============================] - 11s 270ms/step - loss: 0.0270 - accuracy: 0.9927 - val_loss: 0.1721 - val_accuracy: 0.9505\n","Epoch 12/40\n","41/41 [==============================] - 11s 272ms/step - loss: 0.0168 - accuracy: 0.9954 - val_loss: 0.1969 - val_accuracy: 0.9476\n","Epoch 13/40\n","41/41 [==============================] - 11s 272ms/step - loss: 0.0150 - accuracy: 0.9951 - val_loss: 0.2962 - val_accuracy: 0.9254\n","Epoch 14/40\n","41/41 [==============================] - 11s 270ms/step - loss: 0.0212 - accuracy: 0.9937 - val_loss: 0.2188 - val_accuracy: 0.9402\n","Epoch 15/40\n","41/41 [==============================] - 11s 271ms/step - loss: 0.0090 - accuracy: 0.9976 - val_loss: 0.2253 - val_accuracy: 0.9437\n","Epoch 16/40\n","41/41 [==============================] - 11s 269ms/step - loss: 0.0099 - accuracy: 0.9971 - val_loss: 0.2431 - val_accuracy: 0.9431\n","Epoch 17/40\n","41/41 [==============================] - 11s 271ms/step - loss: 0.0048 - accuracy: 0.9990 - val_loss: 0.2596 - val_accuracy: 0.9488\n","Epoch 18/40\n","41/41 [==============================] - 11s 270ms/step - loss: 0.0018 - accuracy: 0.9998 - val_loss: 0.2712 - val_accuracy: 0.9471\n","Epoch 19/40\n","41/41 [==============================] - 11s 271ms/step - loss: 0.0012 - accuracy: 1.0000 - val_loss: 0.2734 - val_accuracy: 0.9471\n","Epoch 20/40\n","41/41 [==============================] - 11s 270ms/step - loss: 5.4482e-04 - accuracy: 1.0000 - val_loss: 0.2827 - val_accuracy: 0.9499\n","Epoch 21/40\n","41/41 [==============================] - 11s 270ms/step - loss: 3.7613e-04 - accuracy: 1.0000 - val_loss: 0.2871 - val_accuracy: 0.9516\n","Epoch 22/40\n","41/41 [==============================] - 11s 271ms/step - loss: 2.6247e-04 - accuracy: 1.0000 - val_loss: 0.2929 - val_accuracy: 0.9499\n","Epoch 23/40\n","41/41 [==============================] - 11s 270ms/step - loss: 2.2165e-04 - accuracy: 1.0000 - val_loss: 0.2985 - val_accuracy: 0.9516\n","Epoch 24/40\n","41/41 [==============================] - 11s 271ms/step - loss: 2.0102e-04 - accuracy: 1.0000 - val_loss: 0.3013 - val_accuracy: 0.9516\n","Epoch 25/40\n","41/41 [==============================] - 11s 270ms/step - loss: 1.7829e-04 - accuracy: 1.0000 - val_loss: 0.3047 - val_accuracy: 0.9511\n","Epoch 26/40\n","41/41 [==============================] - 11s 270ms/step - loss: 1.6700e-04 - accuracy: 1.0000 - val_loss: 0.3095 - val_accuracy: 0.9499\n","Epoch 27/40\n","41/41 [==============================] - 11s 274ms/step - loss: 1.5104e-04 - accuracy: 1.0000 - val_loss: 0.3109 - val_accuracy: 0.9511\n","Epoch 28/40\n","41/41 [==============================] - 11s 271ms/step - loss: 1.3583e-04 - accuracy: 1.0000 - val_loss: 0.3137 - val_accuracy: 0.9511\n","Epoch 29/40\n","41/41 [==============================] - 11s 271ms/step - loss: 1.3032e-04 - accuracy: 1.0000 - val_loss: 0.3166 - val_accuracy: 0.9516\n","Epoch 30/40\n","41/41 [==============================] - 12s 292ms/step - loss: 1.1468e-04 - accuracy: 1.0000 - val_loss: 0.3189 - val_accuracy: 0.9499\n","Epoch 31/40\n","41/41 [==============================] - 11s 270ms/step - loss: 1.0383e-04 - accuracy: 1.0000 - val_loss: 0.3223 - val_accuracy: 0.9505\n","Epoch 32/40\n","41/41 [==============================] - 11s 271ms/step - loss: 9.7322e-05 - accuracy: 1.0000 - val_loss: 0.3240 - val_accuracy: 0.9511\n","Epoch 33/40\n","41/41 [==============================] - 11s 272ms/step - loss: 9.0548e-05 - accuracy: 1.0000 - val_loss: 0.3268 - val_accuracy: 0.9505\n","Epoch 34/40\n","41/41 [==============================] - 11s 271ms/step - loss: 8.3937e-05 - accuracy: 1.0000 - val_loss: 0.3289 - val_accuracy: 0.9511\n","Epoch 35/40\n","41/41 [==============================] - 11s 272ms/step - loss: 7.8706e-05 - accuracy: 1.0000 - val_loss: 0.3320 - val_accuracy: 0.9511\n","Epoch 36/40\n","41/41 [==============================] - 11s 271ms/step - loss: 7.4587e-05 - accuracy: 1.0000 - val_loss: 0.3332 - val_accuracy: 0.9511\n","Epoch 37/40\n","41/41 [==============================] - 11s 271ms/step - loss: 6.9081e-05 - accuracy: 1.0000 - val_loss: 0.3349 - val_accuracy: 0.9516\n","Epoch 38/40\n","41/41 [==============================] - 11s 274ms/step - loss: 6.9137e-05 - accuracy: 1.0000 - val_loss: 0.3377 - val_accuracy: 0.9505\n","Epoch 39/40\n","41/41 [==============================] - 11s 272ms/step - loss: 6.1396e-05 - accuracy: 1.0000 - val_loss: 0.3395 - val_accuracy: 0.9516\n","Epoch 40/40\n","41/41 [==============================] - 11s 272ms/step - loss: 5.8201e-05 - accuracy: 1.0000 - val_loss: 0.3414 - val_accuracy: 0.9505\n","INFO:tensorflow:Assets written to: final/2-conv-64-nodes-2-dense-1655332877.model/assets\n"]}]},{"cell_type":"code","source":[" "],"metadata":{"id":"UFvyHamv-Ozn"},"execution_count":null,"outputs":[]}]} -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # OSC-Medical-Analysis-Application-Using-ML 2 | 3 | An CNN based binary classification model to classify X-Ray scans on whether they are suffering from pneumonia or not. It would be trained on the Kaggle dataset mentioned below and would be built with Keras and TensorFlow. The frontend would act as an interface where we would upload images for inference. It would access the model through an api built using python. 4 | 5 | ## Star ⭐ and Fork the repository to earn bonus points. 6 | 7 | ## Tech Stack 8 | 9 | - ML: Tensorflow, Keras, NumPy, Pandas, SciKit-Learn, MatPlotlib 10 | - Frontend: React.js, HTML, CSS, JavaScript 11 | - Backend: FastAPI 12 | 13 | ## Data 14 | 15 | The data originates from a [2018 Kaggle competition](https://www.kaggle.com/datasets/paultimothymooney/chest-xray-pneumonia). 16 | 17 | The dataset is organized into 3 folders (train, test, val) and contains subfolders for each image category (Pneumonia/Normal). There are 5,863 X-Ray images (JPEG) and 2 categories (Pneumonia/Normal). 18 | 19 | Chest X-ray images (anterior-posterior) were selected from retrospective cohorts of pediatric patients of one to five years old from Guangzhou Women and Children’s Medical Center, Guangzhou. All chest X-ray imaging was performed as part of patients’ routine clinical care. 20 | 21 | For the analysis of chest x-ray images, all chest radiographs were initially screened for quality control by removing all low quality or unreadable scans. The diagnoses for the images were then graded by two expert physicians before being cleared for training the AI system. In order to account for any grading errors, the evaluation set was also checked by a third expert. 22 | 23 | ## The Model 24 | 25 | The model would be a CNN built through Keras and TensorFLow, the architecture of the model is left to the contributor, it is recommended to use a combination of convolution, maxpooling, dense and dropout layer to ensure maximum accuracy and efficiency. Since it is a binary classifier, Binary cross enthropy loss function is recommended. 26 | 27 | The current Model uses 2 Convolutional Layers and 2 Dense Layers of 64 nodes and has the following metrics 28 | ```loss: 5.8201e-05 - accuracy: 1.0000 - val_accuracy: 0.9505``` 29 | 30 | The Model input undergoes the following preprocessing 31 | ```python 32 | def preprocessing(img): 33 | img_array = cv2.imread( img,cv2.IMREAD_GRAYSCALE) #convert image to grayscale 34 | 35 | new_array = cv2.resize(img_array, (size, size)) #resize image 36 | 37 | # return image 38 | return new_array/256 39 | ``` 40 | ## Frontend 41 | 42 | The frontend would be made using react. It would consist of a Form like interface where one can upload an image. The image would then be send to the backend for inference and would await a response from the backend. On recieving the prediction it would display it to the user. 43 | 44 | ## File Structure 45 | 46 | 1. The frontend folder consist of an new react app created using npx create-react-app, it will house the entire frontend that will be used to access the model. 47 | 2. The backend folder will contain the api which will receive photos send buy the frontend and perform inference in them 48 | 3. The ML Model folder will contain the Jupyter notebook used for data processing and training and the saved model. 49 | 50 | ## Repository Setup 51 | 1. Install Anaconda 52 | 2. Create a new environment using the `environment.yml` file 53 | ```conda env create -f environment.yml``` 54 | 3. Activate the environment 55 | ```conda activate OSC-Medical-Analysis``` 56 | 57 | ## Backend 58 | The backend uses a simple api created using FastAPI that acceps the images as binary strings and returns the prediction in the following format 59 | ```json 60 | { 61 | "result": "Potentially Pneumonia", // or Normal 62 | "prediction": "95.1230" // model's prediction 63 | } 64 | ``` 65 | 66 | ### Backend Setup 67 | 1. Navigate to the backend folder 68 | ```cd backend``` 69 | 2. Start the server 70 | ```uvicorn main:app --reload``` 71 | 3. Open http://localhost:8000/docs 72 | 73 | ### Frontend Setup 74 | 1. Navigate to the frontend foler 75 | ```cd frontend``` 76 | 2. Install dependancies 77 | ```npm install``` 78 | 3. Run frontend server (make sure backend is running before this) 79 | ```npm run start``` 80 | 81 | -------------------------------------------------------------------------------- /backend/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/upes-open/OSC-Medical-Analysis-Application-Using-ML/a55bf84d7ee30c8e47fcfb70e1ffd2e866ce7e10/backend/.gitkeep -------------------------------------------------------------------------------- /backend/Model/2-conv-64-nodes-2-dense-1655332877.model.h5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/upes-open/OSC-Medical-Analysis-Application-Using-ML/a55bf84d7ee30c8e47fcfb70e1ffd2e866ce7e10/backend/Model/2-conv-64-nodes-2-dense-1655332877.model.h5 -------------------------------------------------------------------------------- /backend/__pycache__/main.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/upes-open/OSC-Medical-Analysis-Application-Using-ML/a55bf84d7ee30c8e47fcfb70e1ffd2e866ce7e10/backend/__pycache__/main.cpython-36.pyc -------------------------------------------------------------------------------- /backend/__pycache__/ml.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/upes-open/OSC-Medical-Analysis-Application-Using-ML/a55bf84d7ee30c8e47fcfb70e1ffd2e866ce7e10/backend/__pycache__/ml.cpython-36.pyc -------------------------------------------------------------------------------- /backend/main.py: -------------------------------------------------------------------------------- 1 | from typing import Optional 2 | from ml import predict, preprocessing 3 | from fastapi import FastAPI, File, UploadFile 4 | from fastapi.middleware.cors import CORSMiddleware 5 | import shutil 6 | import cv2 7 | 8 | app = FastAPI(title="OSC-Medical-Analysis-Application-Using-ML",description="An CNN based binary classification model to classify X-Ray scans on whether they are suffering from pneumonia or not.") 9 | app.add_middleware( 10 | CORSMiddleware, 11 | allow_origins=["*"], 12 | allow_credentials=True, 13 | allow_methods=["*"], 14 | allow_headers=["*"], 15 | ) 16 | 17 | @app.post("/") 18 | async def root(file: UploadFile = File(...)): 19 | threshold = 0.75 20 | with open("tmp.jpg","wb") as buffer: 21 | shutil.copyfileobj(file.file, buffer) 22 | image = preprocessing("tmp.jpg") 23 | prediction = predict(image) 24 | options = ["Normal","Potentially Pneumonia"] 25 | msg = 0 26 | if prediction > threshold: 27 | msg = 1 28 | return {"result": options[msg], "prediction":str(prediction)} 29 | 30 | -------------------------------------------------------------------------------- /backend/ml.py: -------------------------------------------------------------------------------- 1 | from keras.models import load_model 2 | import cv2 3 | size = 300 4 | 5 | def preprocessing(img): 6 | img_array = cv2.imread( img,cv2.IMREAD_GRAYSCALE) 7 | new_array = cv2.resize(img_array, (size, size)) 8 | return new_array/256 9 | 10 | def predict(image): 11 | model = load_model("Model/2-conv-64-nodes-2-dense-1655332877.model.h5") 12 | input_shape = (1,300,300,1) 13 | a = image.reshape(input_shape) 14 | return model.predict(a)[0][0] 15 | -------------------------------------------------------------------------------- /backend/tmp.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/upes-open/OSC-Medical-Analysis-Application-Using-ML/a55bf84d7ee30c8e47fcfb70e1ffd2e866ce7e10/backend/tmp.jpg -------------------------------------------------------------------------------- /environment.yml: -------------------------------------------------------------------------------- 1 | name: OSC-Medical-Analysis 2 | channels: 3 | - conda-forge 4 | - defaults 5 | dependencies: 6 | - _libgcc_mutex=0.1=main 7 | - _openmp_mutex=5.1=1_gnu 8 | - ca-certificates=2022.6.15=ha878542_0 9 | - certifi=2016.9.26=py36_0 10 | - ld_impl_linux-64=2.38=h1181459_1 11 | - libffi=3.3=he6710b0_2 12 | - libgcc-ng=11.2.0=h1234567_1 13 | - libgomp=11.2.0=h1234567_1 14 | - libstdcxx-ng=11.2.0=h1234567_1 15 | - ncurses=6.3=h7f8727e_2 16 | - openssl=1.1.1o=h166bdaf_0 17 | - pip=21.2.2=py36h06a4308_0 18 | - python=3.6.13=h12debd9_1 19 | - readline=8.1.2=h7f8727e_1 20 | - setuptools=58.0.4=py36h06a4308_0 21 | - sqlite=3.38.3=hc218d9a_0 22 | - tk=8.6.12=h1ccaba5_0 23 | - typing_extensions=3.10.0.2=pyha770c72_0 24 | - wheel=0.37.1=pyhd3eb1b0_0 25 | - xz=5.2.5=h7f8727e_1 26 | - zlib=1.2.12=h7f8727e_2 27 | - pip: 28 | - absl-py==0.15.0 29 | - anyio==3.6.1 30 | - asgiref==3.4.1 31 | - astunparse==1.6.3 32 | - cached-property==1.5.2 33 | - cachetools==4.2.4 34 | - charset-normalizer==2.0.12 35 | - clang==5.0 36 | - click==8.0.4 37 | - contextlib2==21.6.0 38 | - contextvars==2.4 39 | - dataclasses==0.8 40 | - dnspython==2.2.1 41 | - email-validator==1.2.1 42 | - fastapi==0.78.0 43 | - flatbuffers==1.12 44 | - gast==0.4.0 45 | - google-auth==1.35.0 46 | - google-auth-oauthlib==0.4.6 47 | - google-pasta==0.2.0 48 | - grpcio==1.46.3 49 | - h11==0.13.0 50 | - h5py==3.1.0 51 | - httptools==0.3.0 52 | - idna==3.3 53 | - immutables==0.18 54 | - importlib-metadata==4.8.3 55 | - itsdangerous==2.0.1 56 | - jinja2==3.0.3 57 | - keras==2.6.0 58 | - keras-preprocessing==1.1.2 59 | - markdown==3.3.7 60 | - markupsafe==2.0.1 61 | - numpy==1.19.5 62 | - oauthlib==3.2.0 63 | - opencv-python==4.6.0.66 64 | - opt-einsum==3.3.0 65 | - orjson==3.6.1 66 | - protobuf==3.19.4 67 | - pyasn1==0.4.8 68 | - pyasn1-modules==0.2.8 69 | - pydantic==1.9.1 70 | - python-dotenv==0.20.0 71 | - python-multipart==0.0.5 72 | - pyyaml==6.0 73 | - requests==2.27.1 74 | - requests-oauthlib==1.3.1 75 | - rsa==4.8 76 | - six==1.15.0 77 | - sniffio==1.2.0 78 | - starlette==0.19.1 79 | - tensorboard==2.6.0 80 | - tensorboard-data-server==0.6.1 81 | - tensorboard-plugin-wit==1.8.1 82 | - tensorflow==2.6.2 83 | - tensorflow-estimator==2.6.0 84 | - termcolor==1.1.0 85 | - typing-extensions==3.7.4.3 86 | - ujson==4.0.1 87 | - urllib3==1.26.9 88 | - uvicorn==0.16.0 89 | - uvloop==0.14.0 90 | - watchgod==0.7 91 | - websockets==9.1 92 | - werkzeug==2.0.3 93 | - wrapt==1.12.1 94 | - zipp==3.6.0 95 | prefix: /home/captaincuckoo/anaconda3/envs/ml-shit 96 | -------------------------------------------------------------------------------- /frontend/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /frontend/README.md: -------------------------------------------------------------------------------- 1 | # Getting Started with Create React App 2 | 3 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). 4 | 5 | ## Available Scripts 6 | 7 | In the project directory, you can run: 8 | 9 | ### `npm start` 10 | 11 | Runs the app in the development mode.\ 12 | Open [http://localhost:3000](http://localhost:3000) to view it in your browser. 13 | 14 | The page will reload when you make changes.\ 15 | You may also see any lint errors in the console. 16 | 17 | ### `npm test` 18 | 19 | Launches the test runner in the interactive watch mode.\ 20 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. 21 | 22 | ### `npm run build` 23 | 24 | Builds the app for production to the `build` folder.\ 25 | It correctly bundles React in production mode and optimizes the build for the best performance. 26 | 27 | The build is minified and the filenames include the hashes.\ 28 | Your app is ready to be deployed! 29 | 30 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. 31 | 32 | ### `npm run eject` 33 | 34 | **Note: this is a one-way operation. Once you `eject`, you can't go back!** 35 | 36 | If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. 37 | 38 | Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own. 39 | 40 | You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it. 41 | 42 | ## Learn More 43 | 44 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). 45 | 46 | To learn React, check out the [React documentation](https://reactjs.org/). 47 | 48 | ### Code Splitting 49 | 50 | This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting) 51 | 52 | ### Analyzing the Bundle Size 53 | 54 | This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size) 55 | 56 | ### Making a Progressive Web App 57 | 58 | This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app) 59 | 60 | ### Advanced Configuration 61 | 62 | This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration) 63 | 64 | ### Deployment 65 | 66 | This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment) 67 | 68 | ### `npm run build` fails to minify 69 | 70 | This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify) 71 | -------------------------------------------------------------------------------- /frontend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "frontend", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.16.4", 7 | "@testing-library/react": "^13.3.0", 8 | "@testing-library/user-event": "^13.5.0", 9 | "axios": "^0.27.2", 10 | "react": "^18.1.0", 11 | "react-dom": "^18.1.0", 12 | "react-scripts": "5.0.1", 13 | "web-vitals": "^2.1.4" 14 | }, 15 | "scripts": { 16 | "start": "react-scripts start", 17 | "build": "react-scripts build", 18 | "test": "react-scripts test", 19 | "eject": "react-scripts eject" 20 | }, 21 | "eslintConfig": { 22 | "extends": [ 23 | "react-app", 24 | "react-app/jest" 25 | ] 26 | }, 27 | "browserslist": { 28 | "production": [ 29 | ">0.2%", 30 | "not dead", 31 | "not op_mini all" 32 | ], 33 | "development": [ 34 | "last 1 chrome version", 35 | "last 1 firefox version", 36 | "last 1 safari version" 37 | ] 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /frontend/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/upes-open/OSC-Medical-Analysis-Application-Using-ML/a55bf84d7ee30c8e47fcfb70e1ffd2e866ce7e10/frontend/public/favicon.ico -------------------------------------------------------------------------------- /frontend/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 | 7 | 8 | 12 | 13 | 17 | 18 | 27 |