diff --git a/Bone Fracture Detection/PredictResults/firstRes.png b/Bone Fracture Detection/PredictResults/firstRes.png
new file mode 100644
index 00000000..e60d4ac1
Binary files /dev/null and b/Bone Fracture Detection/PredictResults/firstRes.png differ
diff --git a/Bone Fracture Detection/PredictResults/secRes.png b/Bone Fracture Detection/PredictResults/secRes.png
new file mode 100644
index 00000000..54e7c08d
Binary files /dev/null and b/Bone Fracture Detection/PredictResults/secRes.png differ
diff --git a/Bone Fracture Detection/README.md b/Bone Fracture Detection/README.md
new file mode 100644
index 00000000..22e9350b
--- /dev/null
+++ b/Bone Fracture Detection/README.md
@@ -0,0 +1,79 @@
+# Bone-Fracture-Detection
+## Introduction
+ Since long ago, bone fractures was a long standing issue for mankind, and it's classification via x-ray has always depended on human diagnostics – which may be sometimes flawed.
+In recent years, Machine learning and AI based solutions have become an integral part of our lives, in all aspects, as well as in the medical field.
+In the scope of our research and project, we have been studying this issue of classification and have been trying, based on previous attempts and researches, to develop and fine tune a feasible solution for the medical field in terms of identification and classification of various bone fractures, using CNN ( Convolutional Neural Networks ) in the scope of modern models, such as ResNet, DenseNet, VGG16, and so forth.
+After performing multiple model fine tuning attempts for various models, we have achieved classification results lower then the predefined threshold of confidence agreed upon later in this research, but with the promising results we did achieve, we believe that systems of this type, machine learning and deep learning based solutions for identification and classification of bone fractures, with further fine tuning and applications of more advanced techniques such as Feature Extraction, may replace the traditional methods currently employed in the medical field, with much better results.
+
+
+## Dataset
+The data set we used called MURA and included 3 different bone parts, MURA is a dataset of musculoskeletal radiographs and contains 20,335 images described below:
+
+
+| **Part** | **Normal** | **Fractured** | **Total** |
+|--------------|:----------:|--------------:|----------:|
+| **Elbow** | 3160 | 2236 | 5396 |
+| **Hand** | 4330 | 1673 | 6003 |
+| **Shoulder** | 4496 | 4440 | 8936 |
+
+The data is separated into train and valid where each folder contains a folder of a patient and for each patient between 1-3 images for the same bone part
+
+## Algorithm
+Our data contains about 20,000 x-ray images, including three different types of bones - elbow, hand, and shoulder. After loading all the images into data frames and assigning a label to each image, we split our images into 72% training, 18% validation and 10% test. The algorithm starts with data augmentation and pre-processing the x-ray images, such as flip horizontal. The second step uses a ResNet50 neural network to classify the type of bone in the image. Once the bone type has been predicted, A specific model will be loaded for that bone type prediction from 3 different types that were each trained to identify a fracture in another bone type and used to detect whether the bone is fractured.
+This approach utilizes the strong image classification capabilities of ResNet50 to identify the type of bone and then employs a specific model for each bone to determine if there is a fracture present. Utilizing this two-step process, the algorithm can efficiently and accurately analyze x-ray images, helping medical professionals diagnose patients quickly and accurately.
+The algorithm can determine whether the prediction should be considered a positive result, indicating that a bone fracture is present, or a negative result, indicating that no bone fracture is present. The results of the bone type classification and bone fracture detection will be displayed to the user in the application, allowing for easy interpretation.
+This algorithm has the potential to greatly aid medical professionals in detecting bone fractures and improving patient diagnosis and treatment. Its efficient and accurate analysis of x-ray images can speed up the diagnosis process and help patients receive appropriate care.
+
+
+
+
+
+
+## Results
+### Body Part Prediction
+
+
+
+### Fracture Prediction
+#### Elbow
+
+
+
+#### Hand
+
+
+#### Shoulder
+
+
+
+# Installations
+### PyCharm IDE
+### Python v3.7.x
+### Install requirements.txt
+
+* customtkinter~=5.0.3
+* PyAutoGUI~=0.9.53
+* PyGetWindow~=0.0.9
+* Pillow~=8.4.0
+* numpy~=1.19.5
+* tensorflow~=2.6.2
+* keras~=2.6.0
+* pandas~=1.1.5
+* matplotlib~=3.3.4
+* scikit-learn~=0.24.2
+* colorama~=0.4.5
+
+Run mainGUI.Py
+
+# GUI
+### Main
+
+
+### Info-Rules
+
+
+### Test Normal & Fractured
+
+
+
+
diff --git a/Bone Fracture Detection/images/Architecture.png b/Bone Fracture Detection/images/Architecture.png
new file mode 100644
index 00000000..33035268
Binary files /dev/null and b/Bone Fracture Detection/images/Architecture.png differ
diff --git a/Bone Fracture Detection/images/Question_Mark.jpg b/Bone Fracture Detection/images/Question_Mark.jpg
new file mode 100644
index 00000000..307d4288
Binary files /dev/null and b/Bone Fracture Detection/images/Question_Mark.jpg differ
diff --git a/Bone Fracture Detection/images/info.png b/Bone Fracture Detection/images/info.png
new file mode 100644
index 00000000..44d66b48
Binary files /dev/null and b/Bone Fracture Detection/images/info.png differ
diff --git a/Bone Fracture Detection/images/rules.jpeg b/Bone Fracture Detection/images/rules.jpeg
new file mode 100644
index 00000000..1a8ac2cd
Binary files /dev/null and b/Bone Fracture Detection/images/rules.jpeg differ
diff --git a/Bone Fracture Detection/mainGUI.py b/Bone Fracture Detection/mainGUI.py
new file mode 100644
index 00000000..7368071b
--- /dev/null
+++ b/Bone Fracture Detection/mainGUI.py
@@ -0,0 +1,130 @@
+import os
+from tkinter import filedialog
+import customtkinter as ctk
+import pyautogui
+import pygetwindow
+from PIL import ImageTk, Image
+
+from predictions import predict
+
+# global variables
+
+project_folder = os.path.dirname(os.path.abspath(__file__))
+folder_path = project_folder + '/images/'
+
+filename = ""
+
+
+class App(ctk.CTk):
+ def __init__(self):
+ super().__init__()
+
+ self.title("Bone Fracture Detection")
+ self.geometry(f"{500}x{740}")
+ self.head_frame = ctk.CTkFrame(master=self)
+ self.head_frame.pack(pady=20, padx=60, fill="both", expand=True)
+ self.main_frame = ctk.CTkFrame(master=self)
+ self.main_frame.pack(pady=20, padx=60, fill="both", expand=True)
+ self.head_label = ctk.CTkLabel(master=self.head_frame, text="Bone Fracture Detection",
+ font=(ctk.CTkFont("Roboto"), 28))
+ self.head_label.pack(pady=20, padx=10, anchor="nw", side="left")
+ img1 = ctk.CTkImage(Image.open(folder_path + "info.png"))
+
+ self.img_label = ctk.CTkButton(master=self.head_frame, text="", image=img1, command=self.open_image_window,
+ width=40, height=40)
+
+ self.img_label.pack(pady=10, padx=10, anchor="nw", side="right")
+
+ self.info_label = ctk.CTkLabel(master=self.main_frame,
+ text="Bone fracture detection system, upload an x-ray image for fracture detection.",
+ wraplength=300, font=(ctk.CTkFont("Roboto"), 18))
+ self.info_label.pack(pady=10, padx=10)
+
+ self.upload_btn = ctk.CTkButton(master=self.main_frame, text="Upload Image", command=self.upload_image)
+ self.upload_btn.pack(pady=0, padx=1)
+
+ self.frame2 = ctk.CTkFrame(master=self.main_frame, fg_color="transparent", width=256, height=256)
+ self.frame2.pack(pady=10, padx=1)
+
+ img = Image.open(folder_path + "Question_Mark.jpg")
+ img_resized = img.resize((int(256 / img.height * img.width), 256)) # new width & height
+ img = ImageTk.PhotoImage(img_resized)
+
+ self.img_label = ctk.CTkLabel(master=self.frame2, text="", image=img)
+ self.img_label.pack(pady=1, padx=10)
+
+
+ self.predict_btn = ctk.CTkButton(master=self.main_frame, text="Predict", command=self.predict_gui)
+ self.predict_btn.pack(pady=0, padx=1)
+
+ self.result_frame = ctk.CTkFrame(master=self.main_frame, fg_color="transparent", width=200, height=100)
+ self.result_frame.pack(pady=5, padx=5)
+
+ self.loader_label = ctk.CTkLabel(master=self.main_frame, width=100, height=100, text="")
+ self.loader_label.pack(pady=3, padx=3)
+
+ self.res1_label = ctk.CTkLabel(master=self.result_frame, text="")
+ self.res1_label.pack(pady=5, padx=20)
+
+ self.res2_label = ctk.CTkLabel(master=self.result_frame, text="")
+ self.res2_label.pack(pady=5, padx=20)
+
+ self.save_btn = ctk.CTkButton(master=self.result_frame, text="Save Result", command=self.save_result)
+
+ self.save_label = ctk.CTkLabel(master=self.result_frame, text="")
+
+
+
+ def upload_image(self):
+ global filename
+ f_types = [("All Files", "*.*")]
+ filename = filedialog.askopenfilename(filetypes=f_types, initialdir=project_folder+'/test/Wrist/')
+ self.save_label.configure(text="")
+ self.res2_label.configure(text="")
+ self.res1_label.configure(text="")
+ self.img_label.configure(self.frame2, text="", image="")
+ img = Image.open(filename)
+ img_resized = img.resize((int(256 / img.height * img.width), 256)) # new width & height
+ img = ImageTk.PhotoImage(img_resized)
+ self.img_label.configure(self.frame2, image=img, text="")
+ self.img_label.image = img
+ self.save_btn.pack_forget()
+ self.save_label.pack_forget()
+
+ def predict_gui(self):
+ global filename
+ bone_type_result = predict(filename)
+ result = predict(filename, bone_type_result)
+ print(result)
+ if result == 'fractured':
+ self.res2_label.configure(text_color="RED", text="Result: Fractured", font=(ctk.CTkFont("Roboto"), 24))
+ else:
+ self.res2_label.configure(text_color="GREEN", text="Result: Normal", font=(ctk.CTkFont("Roboto"), 24))
+ bone_type_result = predict(filename, "Parts")
+ self.res1_label.configure(text="Type: " + bone_type_result, font=(ctk.CTkFont("Roboto"), 24))
+ print(bone_type_result)
+ self.save_btn.pack(pady=10, padx=1)
+ self.save_label.pack(pady=5, padx=20)
+
+ def save_result(self):
+ tempdir = filedialog.asksaveasfilename(parent=self, initialdir=project_folder + '/PredictResults/',
+ title='Please select a directory and filename', defaultextension=".png")
+ screenshots_dir = tempdir
+ window = pygetwindow.getWindowsWithTitle('Bone Fracture Detection')[0]
+ left, top = window.topleft
+ right, bottom = window.bottomright
+ pyautogui.screenshot(screenshots_dir)
+ im = Image.open(screenshots_dir)
+ im = im.crop((left + 10, top + 35, right - 10, bottom - 10))
+ im.save(screenshots_dir)
+ self.save_label.configure(text_color="WHITE", text="Saved!", font=(ctk.CTkFont("Roboto"), 16))
+
+ def open_image_window(self):
+ im = Image.open(folder_path + "rules.jpeg")
+ im = im.resize((700, 700))
+ im.show()
+
+
+if __name__ == "__main__":
+ app = App()
+ app.mainloop()
diff --git a/Bone Fracture Detection/plots/BodyPartAcc.png b/Bone Fracture Detection/plots/BodyPartAcc.png
new file mode 100644
index 00000000..51e41500
Binary files /dev/null and b/Bone Fracture Detection/plots/BodyPartAcc.png differ
diff --git a/Bone Fracture Detection/plots/BodyPartLoss.png b/Bone Fracture Detection/plots/BodyPartLoss.png
new file mode 100644
index 00000000..3909e3f1
Binary files /dev/null and b/Bone Fracture Detection/plots/BodyPartLoss.png differ
diff --git a/Bone Fracture Detection/plots/testPredictions.png b/Bone Fracture Detection/plots/testPredictions.png
new file mode 100644
index 00000000..0c98e5e9
Binary files /dev/null and b/Bone Fracture Detection/plots/testPredictions.png differ
diff --git a/Bone Fracture Detection/prediction_test.py b/Bone Fracture Detection/prediction_test.py
new file mode 100644
index 00000000..8180b67d
--- /dev/null
+++ b/Bone Fracture Detection/prediction_test.py
@@ -0,0 +1,75 @@
+import os
+from colorama import Fore
+from predictions import predict
+
+
+# load images to predict from paths
+# .... / elbow1.jpg
+# Hand fractured -- elbow2.png
+# / / \ .....
+# test - Elbow ------
+# \ \ / elbow1.png
+# Shoulder normal -- elbow2.jpg
+# .... \
+#
+def load_path(path):
+ dataset = []
+ for body in os.listdir(path):
+ body_part = body
+ path_p = path + '/' + str(body)
+ for lab in os.listdir(path_p):
+ label = lab
+ path_l = path_p + '/' + str(lab)
+ for img in os.listdir(path_l):
+ img_path = path_l + '/' + str(img)
+ dataset.append(
+ {
+ 'body_part': body_part,
+ 'label': label,
+ 'image_path': img_path,
+ 'image_name': img
+ }
+ )
+ return dataset
+
+
+categories_parts = ["Elbow", "Hand", "Shoulder"]
+categories_fracture = ['fractured', 'normal']
+
+
+def reportPredict(dataset):
+ total_count = 0
+ part_count = 0
+ status_count = 0
+
+ print(Fore.YELLOW +
+ '{0: <28}'.format('Name') +
+ '{0: <14}'.format('Part') +
+ '{0: <20}'.format('Predicted Part') +
+ '{0: <20}'.format('Status') +
+ '{0: <20}'.format('Predicted Status'))
+ for img in dataset:
+ body_part_predict = predict(img['image_path'])
+ fracture_predict = predict(img['image_path'], body_part_predict)
+ if img['body_part'] == body_part_predict:
+ part_count = part_count + 1
+ if img['label'] == fracture_predict:
+ status_count = status_count + 1
+ color = Fore.GREEN
+ else:
+ color = Fore.RED
+ print(color +
+ '{0: <28}'.format(img['image_name']) +
+ '{0: <14}'.format(img['body_part']) +
+ '{0: <20}'.format(body_part_predict) +
+ '{0: <20}'.format((img['label'])) +
+ '{0: <20}'.format(fracture_predict))
+
+ print(Fore.BLUE + '\npart acc: ' + str("%.2f" % (part_count / len(dataset) * 100)) + '%')
+ print(Fore.BLUE + 'status acc: ' + str("%.2f" % (status_count / len(dataset) * 100)) + '%')
+ return
+
+
+THIS_FOLDER = os.path.dirname(os.path.abspath(__file__))
+test_dir = THIS_FOLDER + '/test/'
+reportPredict(load_path(test_dir))
diff --git a/Bone Fracture Detection/predictions.py b/Bone Fracture Detection/predictions.py
new file mode 100644
index 00000000..ab8920ea
--- /dev/null
+++ b/Bone Fracture Detection/predictions.py
@@ -0,0 +1,48 @@
+import numpy as np
+import tensorflow as tf
+from keras.preprocessing import image
+
+# load the models when import "predictions.py"
+model_elbow_frac = tf.keras.models.load_model("weights/ResNet50_Elbow_frac.h5")
+model_hand_frac = tf.keras.models.load_model("weights/ResNet50_Hand_frac.h5")
+model_shoulder_frac = tf.keras.models.load_model("weights/ResNet50_Shoulder_frac.h5")
+model_parts = tf.keras.models.load_model("weights/ResNet50_BodyParts.h5")
+
+# categories for each result by index
+
+# 0-Elbow 1-Hand 2-Shoulder
+categories_parts = ["Elbow", "Hand", "Shoulder"]
+
+# 0-fractured 1-normal
+categories_fracture = ['fractured', 'normal']
+
+
+# get image and model name, the default model is "Parts"
+# Parts - bone type predict model of 3 classes
+# otherwise - fracture predict for each part
+def predict(img, model="Parts"):
+ size = 224
+ if model == 'Parts':
+ chosen_model = model_parts
+ else:
+ if model == 'Elbow':
+ chosen_model = model_elbow_frac
+ elif model == 'Hand':
+ chosen_model = model_hand_frac
+ elif model == 'Shoulder':
+ chosen_model = model_shoulder_frac
+
+ # load image with 224px224p (the training model image size, rgb)
+ temp_img = image.load_img(img, target_size=(size, size))
+ x = image.img_to_array(temp_img)
+ x = np.expand_dims(x, axis=0)
+ images = np.vstack([x])
+ prediction = np.argmax(chosen_model.predict(images), axis=1)
+
+ # chose the category and get the string prediction
+ if model == 'Parts':
+ prediction_str = categories_parts[prediction.item()]
+ else:
+ prediction_str = categories_fracture[prediction.item()]
+
+ return prediction_str
diff --git a/Bone Fracture Detection/requirements.txt b/Bone Fracture Detection/requirements.txt
new file mode 100644
index 00000000..7de9345d
Binary files /dev/null and b/Bone Fracture Detection/requirements.txt differ
diff --git a/Bone Fracture Detection/training_fracture.py b/Bone Fracture Detection/training_fracture.py
new file mode 100644
index 00000000..7330f0c6
--- /dev/null
+++ b/Bone Fracture Detection/training_fracture.py
@@ -0,0 +1,190 @@
+import numpy as np
+import pandas as pd
+import os.path
+import matplotlib.pyplot as plt
+from sklearn.model_selection import train_test_split
+import tensorflow as tf
+from tensorflow.keras.optimizers import Adam
+
+
+# load images to build and train the model
+# .... / img1.jpg
+# test Hand patient0000 positive -- img2.png
+# / / \ .....
+# Dataset - Elbow ------ patient0001
+# \ train \ / img1.png
+# Shoulder patient0002 negative -- img2.jpg
+# .... \
+#
+
+def load_path(path, part):
+ """
+ load X-ray dataset
+ """
+ dataset = []
+ for folder in os.listdir(path):
+ folder = path + '/' + str(folder)
+ if os.path.isdir(folder):
+ for body in os.listdir(folder):
+ if body == part:
+ body_part = body
+ path_p = folder + '/' + str(body)
+ for id_p in os.listdir(path_p):
+ patient_id = id_p
+ path_id = path_p + '/' + str(id_p)
+ for lab in os.listdir(path_id):
+ if lab.split('_')[-1] == 'positive':
+ label = 'fractured'
+ elif lab.split('_')[-1] == 'negative':
+ label = 'normal'
+ path_l = path_id + '/' + str(lab)
+ for img in os.listdir(path_l):
+ img_path = path_l + '/' + str(img)
+ dataset.append(
+ {
+ 'body_part': body_part,
+ 'patient_id': patient_id,
+ 'label': label,
+ 'image_path': img_path
+ }
+ )
+ return dataset
+
+
+# this function get part and know what kind of part to train, save model and save plots
+def trainPart(part):
+ # categories = ['fractured', 'normal']
+ THIS_FOLDER = os.path.dirname(os.path.abspath(__file__))
+ image_dir = THIS_FOLDER + '/Dataset/'
+ data = load_path(image_dir, part)
+ labels = []
+ filepaths = []
+
+ # add labels for dataframe for each category 0-fractured, 1- normal
+ for row in data:
+ labels.append(row['label'])
+ filepaths.append(row['image_path'])
+
+ filepaths = pd.Series(filepaths, name='Filepath').astype(str)
+ labels = pd.Series(labels, name='Label')
+
+ images = pd.concat([filepaths, labels], axis=1)
+
+ # split all dataset 10% test, 90% train (after that the 90% train will split to 20% validation and 80% train
+ train_df, test_df = train_test_split(images, train_size=0.9, shuffle=True, random_state=1)
+
+ # each generator to process and convert the filepaths into image arrays,
+ # and the labels into one-hot encoded labels.
+ # The resulting generators can then be used to train and evaluate a deep learning model.
+
+ # now we have 10% test, 72% training and 18% validation
+ train_generator = tf.keras.preprocessing.image.ImageDataGenerator(horizontal_flip=True,
+ preprocessing_function=tf.keras.applications.resnet50.preprocess_input,
+ validation_split=0.2)
+
+ # use ResNet50 architecture
+ test_generator = tf.keras.preprocessing.image.ImageDataGenerator(
+ preprocessing_function=tf.keras.applications.resnet50.preprocess_input)
+
+ train_images = train_generator.flow_from_dataframe(
+ dataframe=train_df,
+ x_col='Filepath',
+ y_col='Label',
+ target_size=(224, 224),
+ color_mode='rgb',
+ class_mode='categorical',
+ batch_size=64,
+ shuffle=True,
+ seed=42,
+ subset='training'
+ )
+
+ val_images = train_generator.flow_from_dataframe(
+ dataframe=train_df,
+ x_col='Filepath',
+ y_col='Label',
+ target_size=(224, 224),
+ color_mode='rgb',
+ class_mode='categorical',
+ batch_size=64,
+ shuffle=True,
+ seed=42,
+ subset='validation'
+ )
+
+ test_images = test_generator.flow_from_dataframe(
+ dataframe=test_df,
+ x_col='Filepath',
+ y_col='Label',
+ target_size=(224, 224),
+ color_mode='rgb',
+ class_mode='categorical',
+ batch_size=32,
+ shuffle=False
+ )
+
+ # we use rgb 3 channels and 224x224 pixels images, use feature extracting , and average pooling
+ pretrained_model = tf.keras.applications.resnet50.ResNet50(
+ input_shape=(224, 224, 3),
+ include_top=False,
+ weights='imagenet',
+ pooling='avg')
+
+ # for faster performance
+ pretrained_model.trainable = False
+
+ inputs = pretrained_model.input
+ x = tf.keras.layers.Dense(128, activation='relu')(pretrained_model.output)
+ x = tf.keras.layers.Dense(50, activation='relu')(x)
+
+ # outputs Dense '2' because of 2 classes, fratured and normal
+ outputs = tf.keras.layers.Dense(2, activation='softmax')(x)
+ model = tf.keras.Model(inputs, outputs)
+ # print(model.summary())
+ print("-------Training " + part + "-------")
+
+ # Adam optimizer with low learning rate for better accuracy
+ model.compile(optimizer=Adam(learning_rate=0.0001), loss='categorical_crossentropy', metrics=['accuracy'])
+
+ # early stop when our model is over fit or vanishing gradient, with restore best values
+ callbacks = tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience=3, restore_best_weights=True)
+ history = model.fit(train_images, validation_data=val_images, epochs=25, callbacks=[callbacks])
+
+ # save model to this path
+ model.save(THIS_FOLDER + "/weights/ResNet50_" + part + "_frac.h5")
+ results = model.evaluate(test_images, verbose=0)
+ print(part + " Results:")
+ print(results)
+ print(f"Test Accuracy: {np.round(results[1] * 100, 2)}%")
+
+ # create plots for accuracy and save it
+ plt.plot(history.history['accuracy'])
+ plt.plot(history.history['val_accuracy'])
+ plt.title('model accuracy')
+ plt.ylabel('accuracy')
+ plt.xlabel('epoch')
+ plt.legend(['train', 'test'], loc='upper left')
+ # plt.show()
+ figAcc = plt.gcf()
+ my_file = os.path.join(THIS_FOLDER, "./plots/FractureDetection/" + part + "/_Accuracy.jpeg")
+ figAcc.savefig(my_file)
+ plt.clf()
+
+ # create plots for loss and save it
+ plt.plot(history.history['loss'])
+ plt.plot(history.history['val_loss'])
+ plt.title('model loss')
+ plt.ylabel('loss')
+ plt.xlabel('epoch')
+ plt.legend(['train', 'test'], loc='upper left')
+ # plt.show()
+ figAcc = plt.gcf()
+ my_file = os.path.join(THIS_FOLDER, "./plots/FractureDetection/" + part + "/_Loss.jpeg")
+ figAcc.savefig(my_file)
+ plt.clf()
+
+
+# run the function and create model for each parts in the array
+categories_parts = ["Elbow", "Hand", "Shoulder"]
+for category in categories_parts:
+ trainPart(category)
diff --git a/Bone Fracture Detection/training_parts.py b/Bone Fracture Detection/training_parts.py
new file mode 100644
index 00000000..db237c60
--- /dev/null
+++ b/Bone Fracture Detection/training_parts.py
@@ -0,0 +1,168 @@
+import numpy as np
+import pandas as pd
+import os.path
+import matplotlib.pyplot as plt
+from sklearn.model_selection import train_test_split
+import tensorflow as tf
+from tensorflow.keras.optimizers import Adam
+
+
+# load images to build and train the model
+# .... / img1.jpg
+# test Hand patient0000 positive -- img2.png
+# / / \ .....
+# Dataset - Elbow ------ patient0001
+# \ train \ / img1.png
+# Shoulder patient0002 negative -- img2.jpg
+# .... \
+#
+def load_path(path):
+ """
+ load X-ray dataset
+ """
+ dataset = []
+ for folder in os.listdir(path):
+ folder = path + '/' + str(folder)
+ if os.path.isdir(folder):
+ for body in os.listdir(folder):
+ path_p = folder + '/' + str(body)
+ for id_p in os.listdir(path_p):
+ patient_id = id_p
+ path_id = path_p + '/' + str(id_p)
+ for lab in os.listdir(path_id):
+ if lab.split('_')[-1] == 'positive':
+ label = 'fractured'
+ elif lab.split('_')[-1] == 'negative':
+ label = 'normal'
+ path_l = path_id + '/' + str(lab)
+ for img in os.listdir(path_l):
+ img_path = path_l + '/' + str(img)
+ dataset.append(
+ {
+ 'label': body,
+ 'image_path': img_path
+ }
+ )
+ return dataset
+
+
+# load data from path
+THIS_FOLDER = os.path.dirname(os.path.abspath(__file__))
+image_dir = THIS_FOLDER + '/Dataset'
+data = load_path(image_dir)
+labels = []
+filepaths = []
+
+# add labels for dataframe for each category 0-Elbow, 1-Hand, 2-Shoulder
+Labels = ["Elbow", "Hand", "Shoulder"]
+for row in data:
+ labels.append(row['label'])
+ filepaths.append(row['image_path'])
+
+filepaths = pd.Series(filepaths, name='Filepath').astype(str)
+labels = pd.Series(labels, name='Label')
+
+images = pd.concat([filepaths, labels], axis=1)
+
+# split all dataset 10% test, 90% train (after that the 90% train will split to 20% validation and 80% train
+train_df, test_df = train_test_split(images, train_size=0.9, shuffle=True, random_state=1)
+
+# each generator to process and convert the filepaths into image arrays,
+# and the labels into one-hot encoded labels.
+# The resulting generators can then be used to train and evaluate a deep learning model.
+
+# now we have 10% test, 72% training and 18% validation
+
+train_generator = tf.keras.preprocessing.image.ImageDataGenerator(
+ preprocessing_function=tf.keras.applications.resnet50.preprocess_input,
+ validation_split=0.2)
+
+test_generator = tf.keras.preprocessing.image.ImageDataGenerator(
+ preprocessing_function=tf.keras.applications.resnet50.preprocess_input)
+
+train_images = train_generator.flow_from_dataframe(
+ dataframe=train_df,
+ x_col='Filepath',
+ y_col='Label',
+ target_size=(224, 224),
+ color_mode='rgb',
+ class_mode='categorical',
+ batch_size=64,
+ shuffle=True,
+ seed=42,
+ subset='training'
+)
+
+val_images = train_generator.flow_from_dataframe(
+ dataframe=train_df,
+ x_col='Filepath',
+ y_col='Label',
+ target_size=(224, 224),
+ color_mode='rgb',
+ class_mode='categorical',
+ batch_size=64,
+ shuffle=True,
+ seed=42,
+ subset='validation'
+)
+
+test_images = test_generator.flow_from_dataframe(
+ dataframe=test_df,
+ x_col='Filepath',
+ y_col='Label',
+ target_size=(224, 224),
+ color_mode='rgb',
+ class_mode='categorical',
+ batch_size=32,
+ shuffle=False
+)
+
+# we use rgb 3 channels and 224x224 pixels images, use feature extracting , and average pooling
+pretrained_model = tf.keras.applications.resnet50.ResNet50(
+ input_shape=(224, 224, 3),
+ include_top=False,
+ weights='imagenet',
+ pooling='avg')
+
+# for faster performance
+pretrained_model.trainable = False
+
+inputs = pretrained_model.input
+x = tf.keras.layers.Dense(128, activation='relu')(pretrained_model.output)
+x = tf.keras.layers.Dense(50, activation='relu')(x)
+outputs = tf.keras.layers.Dense(len(Labels), activation='softmax')(x)
+model = tf.keras.Model(inputs, outputs)
+print(model.summary())
+
+# Adam optimizer with low learning rate for better accuracy
+model.compile(optimizer=Adam(learning_rate=0.0001), loss='categorical_crossentropy', metrics=['accuracy'])
+
+# early stop when our model is over fit or vanishing gradient, with restore best values
+callbacks = tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience=3, restore_best_weights=True)
+history = model.fit(train_images, validation_data=val_images, epochs=25,
+ callbacks=[callbacks])
+
+# save model to this path
+model.save(THIS_FOLDER + "/weights/ResNet50_BodyParts.h5")
+results = model.evaluate(test_images, verbose=0)
+print(results)
+print(f"Test Accuracy: {np.round(results[1] * 100, 2)}%")
+
+
+# create plots for accuracy and save it
+plt.plot(history.history['accuracy'])
+plt.plot(history.history['val_accuracy'])
+plt.title('model accuracy')
+plt.ylabel('accuracy')
+plt.xlabel('epoch')
+plt.legend(['train', 'test'], loc='upper left')
+plt.show()
+
+# create plots for loss and save it
+plt.plot(history.history['loss'])
+plt.plot(history.history['val_loss'])
+plt.title('model loss')
+plt.ylabel('loss')
+plt.xlabel('epoch')
+plt.legend(['train', 'test'], loc='upper left')
+plt.show()
diff --git a/Bone Fracture Detection/weights/ResNet50_BodyParts.h5 b/Bone Fracture Detection/weights/ResNet50_BodyParts.h5
new file mode 100644
index 00000000..e69de29b
diff --git a/Bone Fracture Detection/weights/ResNet50_Elbow_frac.h5 b/Bone Fracture Detection/weights/ResNet50_Elbow_frac.h5
new file mode 100644
index 00000000..e69de29b
diff --git a/Bone Fracture Detection/weights/ResNet50_Hand_frac.h5 b/Bone Fracture Detection/weights/ResNet50_Hand_frac.h5
new file mode 100644
index 00000000..e69de29b
diff --git a/Bone Fracture Detection/weights/ResNet50_Shoulder_frac.h5 b/Bone Fracture Detection/weights/ResNet50_Shoulder_frac.h5
new file mode 100644
index 00000000..e69de29b