modular / app.py
yashzambre's picture
Create app.py
ff071bd
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()