import gradio as gr import subprocess from PIL import Image import pandas as pd import matplotlib.pyplot as plt from itertools import product import numpy as np from sklearn.preprocessing import MinMaxScaler import os import time import pdb def preprocess_images(input_type): k = 2 batch_size = 8 img_dir = 'Dataset' data_folder = 'Agrilife_Dataset_Clean' dataset_subfolder_paths = {} dataset_img_files = {} for (_, dirnames, _) in os.walk(img_dir): for dirname in dirnames: if 'Recording' in dirname: dataset_name = os.path.basename(os.path.dirname(os.path.join(img_dir, dirname, 'TIFF'))) # Extract dataset name subdir_path = os.path.join(img_dir, dirname, 'TIFF') # Path to the 'TIFF' subdirectory master_folders = [folder for folder in os.listdir(subdir_path) if folder.startswith('MASTER')] slave_folders = [folder for folder in os.listdir(subdir_path) if folder.startswith('SLAVE')] use_master = bool(master_folders) use_slave = bool(slave_folders) # Create subfolders for the current dataset subfolder_paths = create_dataset_folders(dataset_name, use_master or use_slave) if subfolder_paths: print("Folders created successfully for dataset:", dataset_name) print("Subfolder paths:") for path in subfolder_paths: print(path) # Store the subfolder paths for the current dataset dataset_subfolder_paths[dataset_name] = subfolder_paths # Determine the folder to read images from (MASTER or SLAVE) read_folder = master_folders[0] if use_master else slave_folders[0] subdir_path = os.path.join(subdir_path, read_folder) # Read images and append to img_files for the current dataset img_files_dataset = [] if os.path.exists(subdir_path): for _, _, filenames in os.walk(subdir_path): for file in filenames: img_path = os.path.join(subdir_path, file) img_files_dataset.append(img_path) # Store the img_files for the current dataset dataset_img_files[dataset_name] = img_files_dataset print("Images appended and saved to subfolders successfully!") # Process and save images for each dataset for dataset_name, img_files_dataset in dataset_img_files.items(): subfolder_paths = dataset_subfolder_paths[dataset_name] visual_subfolder, analysis_subfolder, preprocess_subfolder, segmented_subfolder, stitched_subfolder, dataframe = subfolder_paths # Read CSV and filter out images of interest img_indices = np.arange(len(img_files_dataset)) ############################ if input_type == "Run Preprocessing": channel_names = ['Red (660 nm)', 'Green (580 nm)','Red Edge (730 nm)', 'NIR (820 nm)'] for img_index in img_indices: img_path = img_files_dataset[img_index] title = os.path.splitext(os.path.basename(img_path))[0] im = Image.open(img_path) # Divide image into 4 equal parts (separate channels) img_size = im.size[0] // 2 img_slices = tile(im, d=img_size) # Visualize each slice (optional, remove if not needed) fig, axs = plt.subplots(1, 4) i = 0 scaler = MinMaxScaler(feature_range=(0, 1)) img_stack = np.zeros((img_size, img_size, len(img_slices))) for box_coords in img_slices: # Grab image based on box_coords temp_img = np.array(im.crop(box_coords)) # Normalize and save to composite image scaler.fit(temp_img) temp_img = scaler.transform(temp_img) img_stack[:, :, i] = temp_img i += 1 # Grab each channel and stack to be R-G-NR-RE red = np.expand_dims(img_stack[:, :, 1], axis=-1) green = np.expand_dims(img_stack[:, :, 0], axis=-1) red_edge = np.expand_dims(img_stack[:, :, 2], axis=-1) NIR = np.expand_dims(img_stack[:, :, -1], axis=-1) composite_img = np.concatenate((green, red_edge, red), axis=-1) * 255 gray_img, binary = CCA_Preprocess(composite_img, preprocess_subfolder, title.replace('/', '_'), title, k=k) preprocessed_img = np.repeat(np.expand_dims(binary, axis=-1), 3, axis=-1) * composite_img # Perform Min-Max normalization # normalized_img = (composite_img - composite_img.min()) / (composite_img.max() - composite_img.min()) # normalized_img *= 255 # normalized_img = normalized_img.astype(np.uint8) # Save image for processing with all channels (for algorithms) save_img = Image.fromarray(np.uint8(preprocessed_img)) save_img.save(os.path.join(analysis_subfolder, '{}.png'.format(title.replace('/', '_')))) # Redo visualization with mask (find more efficient way for this) for channel in range(0, composite_img.shape[-1]): # Visualize (optional, remove if not needed) axs[channel].imshow(composite_img[:, :, channel] * binary, cmap='BuGn') axs[channel].axis('off') axs[channel].set_title(channel_names[channel], fontsize=10) # Save Visual (optional, remove if not needed) plt.suptitle(title) plt.tight_layout() fig.savefig(os.path.join(visual_subfolder, '{}.png'.format(title.replace('/', '_')))) # Close figures (optional, remove if not needed) plt.close('all') print('Finished processing Image {} of {}'.format(img_index + 1, len(img_indices))) # Define the input and output interfaces using Gradio iface = gr.Interface( fn=image_processing, inputs=[gr.components.Dropdown(["Run Preprocessing", "Run Image Stitching", "Run Image Segmentation", "Run Image Stats"], label="Choose the operation to be performed")], title = "Agrilife Automated Phenotyping", description = "Select processing steps and run the script.") iface.launch()