# -*- coding: utf-8 -*- """app.ipynb Automatically generated by Colaboratory. Original file is located at https://colab.research.google.com/drive/1EabZcU6Wk8QL6n0_cXYso4djYWFXPOIJ """ import numpy as np import pandas as pd import tensorflow as tf from tensorflow import keras import gradio as gr from pathlib import Path import os import subprocess # Run the command as a subprocess def run_subprocess(command,subprocess_result_Q=True): print(f'\n{command}\n') process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = process.communicate() if subprocess_result_Q: # Print the output and errors if any print(f"\nOutput: {stdout}\n", ) print(f"\nErrors: {stderr}\n", ) command = [ "python", "-m", "pip", "install", "--upgrade", "pip" ] run_subprocess(command) command = [ "pip", "install", "transformers" ] run_subprocess(command) # !pip install ultralytics command = [ "pip3", "install", "--upgrade", "ultralytics" ] run_subprocess(command) from ultralytics import YOLO """# set up paths""" # project_path = Path('Fu-Chuen/Fungus_Classification_Genus_Species/tree/main') project_path = Path('./') model_path = Path(project_path,'Model') test_path = Path(project_path,'Test') os.makedirs(test_path, exist_ok=True) Yolov8n_path = Path(project_path,'Result/Yolov8n') os.makedirs(Yolov8n_path, exist_ok=True) detect_path = Path(project_path,'runs/detect') weight_path = Path(model_path,'best_Yolo_v8n.pt') # 指定工作目录 # working_directory = '/home/user/app' working_directory = os.getcwd() print(f'\nworking directory: {working_directory}\n') # 递归获取目录下所有文件 def get_all_files(directory): all_files = [] all_directories = [] for root, dirs, files in os.walk(directory): for file in files: all_files.append(os.path.join(root, file)) for dir in dirs: all_directories.append(os.path.join(root, dir)) # 打印所有文件路径 print("\n所有的文件:\n") for file in all_files: print(file) # 打印所有文件路径 print("\n所有的目录:\n") for dir in all_directories: print(dir) return all_files, all_directories # 列出工作目录及其子目录下的所有文件 # get_all_files(working_directory) """# load MobileNet model""" MobileNet_model = keras.models.load_model(Path(model_path,'MobileNetV3Large_Genus_5th_fold_model')) genus_labels = ['Aspergillus', "Cladosporium", 'Penicillium', 'Trichophyton', "Others"] """# find the most frequent element""" def most_frequent_element(my_list): # Create an empty dictionary to store element frequencies element_count = {} # Count the occurrences of each element in the list for element in my_list: if element in element_count: element_count[element] += 1 else: element_count[element] = 1 # Find the element(s) with the highest frequency max_frequency = max(element_count.values()) most_frequent_elements = [element for element, frequency in element_count.items() if frequency == max_frequency] # Print the result # print("The element(s) with the highest frequency:", most_frequent_elements) # print("The highest frequency:", max_frequency) return most_frequent_elements, max_frequency """# genus classify using MobileNet model""" def genus_classify_images(files,threshold): results = "" predict = [] for i, file_path in enumerate(files): print(f'\ngenus_classify_image {i+1}: {file_path.name} \n') try: inp = tf.keras.preprocessing.image.load_img(file_path.name, target_size=(224, 224)) inp = tf.keras.preprocessing.image.img_to_array(inp) inp = inp.reshape((-1, 224, 224, 3)) inp = tf.keras.applications.mobilenet_v3.preprocess_input(inp) model, labels = (MobileNet_model,genus_labels) prediction = model.predict(inp).flatten() confidences = {labels[i]: float(prediction[i]) for i in range(len(labels))} top_3 = sorted(confidences.items(), key=lambda x: x[1], reverse=True)[:3] predict.append(top_3[0][0]) results += f"Image {i+1}: Top 3 predictions: {', '.join([f'{label}: {probab:.3f}' for label, probab in top_3])}\n" except Exception as e: results += f"Image: {file_path.name} - Error: {str(e)}\n" ensemble_predict, max_frequency = most_frequent_element(predict) predict_result = ensemble_predict[0] if max_frequency/len(files) >= threshold else "Unclassified" results = f'Prediction of genus: {predict_result}\n\n' + results return predict_result, results """# Aspergillus classify and count statistics""" # 實時偵測 2013-10-05 OK # --source 偵測圖像路徑 # --save-txt 儲存標籤文件 # --conf 0.25 只保留置信度分數高於0.25的 def delete_files_in_folder(path): for root, dirs, files in os.walk(path): print(f'root: {root}') for file in files: print(f'file: {file}') file_path = os.path.join(root, file) os.remove(file_path) def find_the_most_recent_predict_path(path): path = list(map(lambda x: x.split('/'),path)) path = [i for i in path if 'predict' in i[-1]] # Sort the list by the last element of each inner list path = sorted(path, key=lambda x: x[-1]) return '/'.join(path[-1]) def Aspergillus_Detect(threshold): # get_all_files(working_directory) model = YOLO(weight_path) # pretrained YOLOv8n model # model.predict(test_path, save = True , save_txt = True, output_dir = Yolov8n_path ) # predict on an image model.predict(test_path, save = True , save_txt = True, ) # predict on an image all_files, all_directories = get_all_files(working_directory) image_path = Path(find_the_most_recent_predict_path(all_directories)) label_path = Path(image_path,'labels') print('\nmost_recent_predict_path: {image_path}\n') file_paths = [] for root, dirs, files in os.walk(label_path): for file in files: if file.lower().endswith('.jpg'): file_path = os.path.join(root, file) file_paths.append(file_path) df_test = pd.DataFrame({'filepath': file_paths}) files = os.listdir(label_path) print(f'\nfiles in label_path: {files}\n') # initialize an empty list to store data data = [] # loop through each file and extract the data for file in files: if file.endswith('.txt'): with open(os.path.join(label_path, file), 'r') as f: lines = f.readlines() for line in lines: line = line.strip().split(' ') data.append([file[:-4], line[0], float(line[1]), float(line[2]), float(line[3]), float(line[4])]) # convert list of data to data frame df = pd.DataFrame(data, columns=['image', 'class', 'xmin', 'ymin', 'xmax', 'ymax']) # group by labels, count the number of detections for each label counts = df.groupby(['image', 'class']).size().reset_index(name='count') # add the file name to the data frame counts['file'] = counts['image'].apply(lambda x: x + '.jpg') counts['filepath'] = counts['file'].apply(lambda x: Path(label_path,x)) replace_dict = {'0': 'flavus-oryzae', '1': 'fumigatus', '2': 'niger', '3': 'terreus', '4': 'versicolor'} counts['label'] = counts['class'].replace(replace_dict) # Select only the relevant columns counts = counts[['filepath', 'label', 'count']] df_pivot = pd.pivot_table(counts, values='count', index=['filepath'], columns='label', aggfunc='sum') df_pivot['detect'] = df_pivot.sum(axis=1) pd.options.display.float_format = '{:,.0f}'.format df_pivot = pd.DataFrame(df_pivot) total_col = df_pivot.pop('detect') df_pivot.insert(0, 'detect', total_col) detect_number = round(df_pivot['detect'].sum()) a = [] for i in df_pivot.columns[1:]: a.append([i,round(df_pivot[i].sum()/detect_number,3)]) a = sorted(a,key=lambda x: x[1],reverse=True) print(f'\na: {a}\n') # # 列出工作目录及其子目录下的所有文件 # get_all_files(working_directory) # delete_files_in_folder(image_path) result = [f'Prediction of species of Aspergillus: {a[0][0] if a[0][1] >= threshold else "Unclassified"}', f'There are {df_pivot.shape[0]} mold images.', f'Yolov8n detects {detect_number} instances.', f'The top {len(a)} percentage of specifies:'] for i in a: # print(f'i: {i}') result.append(f'{i[0]} {i[1]}') return '\n'.join(result) """# classify images: genus and Aspergillus""" def classify_images(files,threshold): print(f'threshold = {threshold}') predict, result1 = genus_classify_images(files,threshold) # # 列出工作目录及其子目录下的所有文件 # all_files = get_all_files(working_directory) if predict == 'Aspergillus': result2 = Aspergillus_Detect(threshold) return f'{result1}\n\n{result2}' return result1 import shutil def upload_file(files): delete_folder(test_path) file_paths = [] for file in files: # Save the uploaded image to the 'Test' folder file_path = Path(test_path, file.name.split('/')[-1]) print(f'\nupload_file:{file}, {file.name}, {os.path.abspath(file_path)}\n') try: shutil.copy(file.name, file_path) file_paths.append(file_path) print(f"File copied successfully.") except: print("\nError occurred while copying file.\n") # print(f'\nfile_paths: {file_paths}\n') return file_paths # # Define the path to the directory you want to delete files from # directory_path = test_path # Iterate through all files in the directory and delete them def delete_folder(directory_path): for filename in os.listdir(directory_path): file_path = os.path.join(directory_path, filename) try: if os.path.isfile(file_path) or os.path.islink(file_path): os.unlink(file_path) elif os.path.isdir(file_path): shutil.rmtree(file_path) except Exception as e: print(f"Failed to delete {file_path}: {e}") # delete_folder(test_path) """# main of gradio""" # threshold = 0.6 with gr.Blocks() as fungus_classification: threshold = gr.Slider(minimum=0.1, maximum=1, step=0.1, value=0.6, label="Threshold", info="Choose between 0.1 and 1") image_output = gr.Gallery(label = 'Images of Molds') predict_outputs = gr.Textbox(label = 'Prediction Result') upload_button = gr.UploadButton("Click to Upload Files", file_types=["image", "video"], file_count="multiple") upload_button.upload(upload_file, upload_button, image_output) upload_button.upload(classify_images, [upload_button,threshold], predict_outputs) fungus_classification.launch(share=True, debug=True) # fungus_classification.launch(share=True, debug=True, enable_queue=True)