Fu-Chuen commited on
Commit
f44deb5
·
1 Parent(s): b03480d

Upload app.py

Browse files

Classification of genus and species of medical fungus

Files changed (1) hide show
  1. app.py +222 -0
app.py ADDED
@@ -0,0 +1,222 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ """app.ipynb
3
+
4
+ Automatically generated by Colaboratory.
5
+
6
+ Original file is located at
7
+ https://colab.research.google.com/drive/1EabZcU6Wk8QL6n0_cXYso4djYWFXPOIJ
8
+ """
9
+
10
+ import numpy as np
11
+ import pandas as pd
12
+
13
+ import tensorflow as tf
14
+ from tensorflow import keras
15
+ import gradio as gr
16
+ from pathlib import Path
17
+ import os
18
+
19
+ """# set up paths"""
20
+
21
+ project_path = Path('Fu-Chuen/Fungus_Classification_Genus_Species/tree/main')
22
+ model_path = Path(project_path,'Model')
23
+ test_path = Path(project_path,'Test')
24
+ image_path = Path(project_path,'yolov7_environment_data/runs/detect/exp')
25
+ label_path = Path(image_path,'labels')
26
+
27
+ """# load MobileNet model"""
28
+
29
+ MobileNet_model = keras.models.load_model(Path(model_path,'MobileNetV3Large_Genus_5th_fold_model'))
30
+ genus_labels = ['Aspergillus', "Cladosporium", 'Penicillium', 'Trichophyton', "Others"]
31
+
32
+ """# set up the paths of YoloV7 enviroment and weights of pretrianed YoloV7"""
33
+
34
+ # Commented out IPython magic to ensure Python compatibility.
35
+ # 指定YOLO環境檔路徑
36
+ # %cd Fu-Chuen/Fungus_Classification_Genus_Species/tree/main/yolov7_environment_data/
37
+ # 指定 YOLO v7 模型權重檔
38
+ WEIGHTS = r'Fu-Chuen/Fungus_Classification_Genus_Species/tree/main/Model/best_Yolo_v7.pt'
39
+ # !pip3 install ultralytics
40
+
41
+ """# find the most frequent element"""
42
+
43
+ def most_frequent_element(my_list):
44
+
45
+ # Create an empty dictionary to store element frequencies
46
+ element_count = {}
47
+
48
+ # Count the occurrences of each element in the list
49
+ for element in my_list:
50
+ if element in element_count:
51
+ element_count[element] += 1
52
+ else:
53
+ element_count[element] = 1
54
+
55
+ # Find the element(s) with the highest frequency
56
+ max_frequency = max(element_count.values())
57
+ most_frequent_elements = [element for element, frequency in element_count.items() if frequency == max_frequency]
58
+
59
+ # Print the result
60
+ # print("The element(s) with the highest frequency:", most_frequent_elements)
61
+ # print("The highest frequency:", max_frequency)
62
+ return most_frequent_elements, max_frequency
63
+
64
+ """# genus classify using MobileNet model"""
65
+
66
+ def genus_classify_images(files):
67
+ results = ""
68
+ predict = []
69
+ for i,file_path in enumerate(files):
70
+ try:
71
+ inp = tf.keras.preprocessing.image.load_img(file_path.name, target_size=(224, 224))
72
+ inp = tf.keras.preprocessing.image.img_to_array(inp)
73
+ inp = inp.reshape((-1, 224, 224, 3))
74
+ inp = tf.keras.applications.mobilenet_v3.preprocess_input(inp)
75
+ model, labels = (MobileNet_model,genus_labels)
76
+ prediction = model.predict(inp).flatten()
77
+ confidences = {labels[i]: float(prediction[i]) for i in range(len(labels))}
78
+ top_3 = sorted(confidences.items(), key=lambda x: x[1], reverse=True)[:3]
79
+ predict.append(top_3[0][0])
80
+ # results += f"Image: {file_path.name} - Top 3 Predictions: {', '.join([f'{label}: {probab:.3f}' for label, probab in top_3])}\n"
81
+ # results += f"Image: {file_path.name.split('/')[-1]} - Top 3 Predictions: {', '.join([f'{label}: {probab:.3f}' for label, probab in top_3])}\n"
82
+ results += f"Image {i+1}: Top 3 predictions: {', '.join([f'{label}: {probab:.3f}' for label, probab in top_3])}\n"
83
+ except Exception as e:
84
+ results += f"Image: {file_path.name} - Error: {str(e)}\n"
85
+ ensemble_predict, max_frequency = most_frequent_element(predict)
86
+ predict_result = ensemble_predict[0] if max_frequency/len(files) >= threshold else "Unclassified"
87
+ results = f'Prediction of genus: {predict_result}\n\n' + results
88
+
89
+ return predict_result, results
90
+
91
+ """# Aspergillus classify and count statistics"""
92
+
93
+ # 實時偵測 2013-10-05 OK
94
+ # --source 偵測圖像路徑
95
+ # --save-txt 儲存標籤文件
96
+ # --conf 0.25 只保留置信度分數高於0.25的
97
+ # import os
98
+ # import pandas as pd
99
+
100
+ def delete_files_in_folder(path):
101
+ for root, dirs, files in os.walk(path):
102
+ print(f'root: {root}')
103
+ for file in files:
104
+ print(f'file: {file}')
105
+ file_path = os.path.join(root, file)
106
+ os.remove(file_path)
107
+
108
+ def Aspergillus_Detect():
109
+ delete_files_in_folder(image_path)
110
+ !python detect.py --source Fu-Chuen/Fungus_Classification_Genus_Species/tree/main/Test/ --weights $WEIGHTS --conf 0.25 --save-txt --exist-ok
111
+ file_paths = []
112
+ for root, dirs, files in os.walk(label_path):
113
+ for file in files:
114
+ if file.lower().endswith('.jpg'):
115
+ file_path = os.path.join(root, file)
116
+ file_paths.append(file_path)
117
+
118
+ df_test = pd.DataFrame({'filepath': file_paths})
119
+
120
+ files = os.listdir(label_path)
121
+
122
+ # initialize an empty list to store data
123
+ data = []
124
+
125
+ # loop through each file and extract the data
126
+ for file in files:
127
+ if file.endswith('.txt'):
128
+ with open(os.path.join(label_path, file), 'r') as f:
129
+ lines = f.readlines()
130
+ for line in lines:
131
+ line = line.strip().split(' ')
132
+ data.append([file[:-4], line[0], float(line[1]), float(line[2]), float(line[3]), float(line[4])])
133
+
134
+ # convert list of data to data frame
135
+ df = pd.DataFrame(data, columns=['image', 'class', 'xmin', 'ymin', 'xmax', 'ymax'])
136
+ # group by labels, count the number of detections for each label
137
+ counts = df.groupby(['image', 'class']).size().reset_index(name='count')
138
+ # add the file name to the data frame
139
+ counts['file'] = counts['image'].apply(lambda x: x + '.jpg')
140
+
141
+ counts['filepath'] = counts['file'].apply(lambda x: Path(label_path,x))
142
+
143
+ replace_dict = {'0': 'flavus-oryzae', '1': 'fumigatus', '2': 'niger', '3': 'terreus', '4': 'versicolor'}
144
+ counts['label'] = counts['class'].replace(replace_dict)
145
+
146
+ # Select only the relevant columns
147
+ counts = counts[['filepath', 'label', 'count']]
148
+ df_pivot = pd.pivot_table(counts, values='count', index=['filepath'], columns='label', aggfunc='sum')
149
+ df_pivot['detect'] = df_pivot.sum(axis=1)
150
+ pd.options.display.float_format = '{:,.0f}'.format
151
+ df_pivot = pd.DataFrame(df_pivot)
152
+
153
+ total_col = df_pivot.pop('detect')
154
+ df_pivot.insert(0, 'detect', total_col)
155
+ detect_number = round(df_pivot['detect'].sum())
156
+ a = []
157
+ for i in df_pivot.columns[1:]:
158
+ a.append([i,round(df_pivot[i].sum()/detect_number,3)])
159
+ a = sorted(a,key=lambda x: x[1],reverse=True)
160
+
161
+ result = [f'Prediction of species of Aspergillus: {a[0][0] if a[0][1] >= threshold else "Unclassified"}',
162
+ f'There are {df_pivot.shape[0]} mold images.',
163
+ f'Yolov7 detects {detect_number} instances.',
164
+ f'The top {len(a)} percentage of specifies:']
165
+ for i in a:
166
+ # print(f'i: {i}')
167
+ result.append(f'{i[0]} {i[1]}')
168
+
169
+ return '\n'.join(result)
170
+
171
+ """# classify images: genus and Aspergillus"""
172
+
173
+ def classify_images(files):
174
+ predict, result1 = genus_classify_images(files)
175
+ if predict == 'Aspergillus':
176
+ result2 = Aspergillus_Detect()
177
+ return f'{result1}\n\n{result2}'
178
+ return result1
179
+
180
+ import shutil
181
+
182
+ # Create the 'Test' folder if it doesn't exist
183
+ # test_path = Path(project_path,'Test')
184
+ # os.makedirs(test_path, exist_ok=True)
185
+
186
+ def upload_file(files):
187
+ delete_folder(test_path)
188
+ file_paths = []
189
+ for file in files:
190
+ # Save the uploaded image to the 'Test' folder
191
+ file_name = Path(test_path, file.name.split('/')[-1])
192
+ shutil.copy(file.name, file_name)
193
+ file_paths.append(file_name)
194
+
195
+ return file_paths
196
+
197
+ # Define the path to the directory you want to delete files from
198
+ directory_path = test_path
199
+
200
+ # Iterate through all files in the directory and delete them
201
+ def delete_folder(directory_path):
202
+ for filename in os.listdir(directory_path):
203
+ file_path = os.path.join(directory_path, filename)
204
+ try:
205
+ if os.path.isfile(file_path) or os.path.islink(file_path):
206
+ os.unlink(file_path)
207
+ elif os.path.isdir(file_path):
208
+ shutil.rmtree(file_path)
209
+ except Exception as e:
210
+ print(f"Failed to delete {file_path}: {e}")
211
+ delete_folder(directory_path)
212
+
213
+ """# main of gradio"""
214
+
215
+ threshold = 0.6
216
+ with gr.Blocks() as fungus_classification:
217
+ image_output = gr.Gallery(label = 'Images of Molds')
218
+ predict_outputs = gr.Textbox(label = 'Prediction Result')
219
+ upload_button = gr.UploadButton("Click to Upload Files", file_types=["image", "video"], file_count="multiple")
220
+ upload_button.upload(upload_file, upload_button, image_output)
221
+ upload_button.upload(classify_images, upload_button, predict_outputs)
222
+ fungus_classification.launch(share=True,debug=True)