IOMP / utils.py
Reboot2004's picture
Update utils.py
bb5f699 verified
import os
import zipfile
import random
import pandas as pd
import matplotlib.pyplot as plt
import shutil
import numpy as np
import cv2
preprocessed_folder = "uploads/"
intermediate_folder = "heatmaps/"
segmentation_folder = "segmentations/"
tables_folder = "tables/"
cell_descriptors_path = "cell_descriptors/cell_descriptors.csv"
zip_file_path = "outputs.zip"
def select_sample_images():
# first check if a zip file has been uploaded and extract images from it
for file_name in os.listdir(preprocessed_folder):
if file_name.endswith(".zip"):
zip_file_path = os.path.join(preprocessed_folder, file_name)
with zipfile.ZipFile(zip_file_path, "r") as zip_ref:
# Extract all contents of the zip file to the preprocessed_folder
zip_ref.extractall(path=preprocessed_folder)
# Remove the original zip file
os.remove(zip_file_path)
# print("Contents of the zip file extracted to the folder.")
break
# Get a list of all subfolders in the main folder
subfolders = [
f
for f in os.listdir(preprocessed_folder)
if os.path.isdir(os.path.join(preprocessed_folder, f))
]
# Iterate through each subfolder and move its files to the main folder
for subfolder in subfolders:
if "MACOSX" not in subfolder:
subfolder_path = os.path.join(preprocessed_folder, subfolder)
for file_name in os.listdir(subfolder_path):
source_path = os.path.join(subfolder_path, file_name)
destination_path = os.path.join(preprocessed_folder, file_name)
shutil.move(source_path, destination_path)
# print(f"Moved file '{file_name}' from '{subfolder}' to '{main_folder}'")
# Delete empty subfolders
for subfolder in subfolders:
if "MACOSX" not in subfolder:
subfolder_path = os.path.join(preprocessed_folder, subfolder)
try:
os.rmdir(subfolder_path)
# print(f"Deleted empty folder '{subfolder}'")
except OSError as e:
print(f"Error deleting folder '{subfolder}': {e}")
# next check the count of images in the folder
image_extensions = [
".jpg",
".jpeg",
".png",
".gif",
".bmp",
] # Add more extensions if needed
image_count = 0
for file_name in os.listdir(preprocessed_folder):
if any(file_name.lower().endswith(ext) for ext in image_extensions):
image_count += 1
# if count > 5, return 5 random indices
# else, return all 5 indices
if image_count > 5:
indices = random.sample(range(image_count), 5)
indices.sort()
return indices
else:
return list(range(image_count))
def create_cell_descriptors_table(table_path, nucleus_area, cytoplasm_area, ratio):
# Sample data for the table
data = {
"Metric": ["Nucleus Area", "Cytoplasm Area", "N:C Ratio"],
"Value": [
str(round(nucleus_area, 5)),
str(round(cytoplasm_area, 5)),
str(round(ratio, 5)),
],
}
# Define cell colors
cell_colors = [
["lightgrey", "lightblue"],
["lightgrey", "lightgreen"],
["lightgrey", "lightyellow"],
]
# Create a DataFrame
df = pd.DataFrame(data)
# Plot table
fig = plt.figure(figsize=(2, 2))
table = plt.table(
cellText=df.values,
colLabels=df.columns,
loc="center",
cellLoc="center",
cellColours=cell_colors,
)
# Set cell heights
table.auto_set_font_size(False)
table.set_fontsize(6) # Adjust font size if needed
table.scale(1, 2) # Increase cell heights
# Hide axes
plt.axis("off")
fig.tight_layout()
# Save as image
fig.savefig(table_path) # pad_inches=(0.1, 0.1, 0.1, 0.1) bbox_inches="tight"
plt.close()
# plt.show()
def delete_folders(folder_names):
for folder_name in folder_names:
try:
shutil.rmtree(folder_name)
# print(f"Folder deleted: {folder_name}")
except FileNotFoundError:
print(f"Folder does not exist: {folder_name}")
except Exception as e:
print(f"Error deleting folder {folder_name}: {e}")
def create_folders(folder_names):
for folder_name in folder_names:
try:
os.makedirs(folder_name)
# print(f"Folder created: {folder_name}")
except FileExistsError:
print(f"Folder already exists: {folder_name}")
except Exception as e:
print(f"Error creating folder {folder_name}: {e}")
def calculate_cell_descriptors(
original_shape, resized_shape, pixel_conversion, segmentation_mask
):
area_of_pixel = (
original_shape[0]
* original_shape[1]
* (pixel_conversion**2)
/ (resized_shape[0] * resized_shape[1])
)
binary_nucleus = np.zeros(resized_shape, dtype=np.uint8)
binary_cytoplasm = np.zeros(resized_shape, dtype=np.uint8)
binary_nucleus[(segmentation_mask == [255, 0, 0]).all(axis=2)] = 1
binary_cytoplasm[(segmentation_mask == [128, 0, 0]).all(axis=2)] = 1
# Find contours in the binary masks
nucleus_contours, _ = cv2.findContours(
binary_nucleus, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE
) # nucleus
cytoplasm_contours, _ = cv2.findContours(
binary_cytoplasm, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE
) # cytoplasm
# Calculate area for nucleus and cytoplasm
nucleus_area = sum(cv2.contourArea(contour) for contour in nucleus_contours)
cytoplasm_area = sum(cv2.contourArea(contour) for contour in cytoplasm_contours)
if cytoplasm_area == 0:
ratio = np.NaN
else:
ratio = nucleus_area / cytoplasm_area
return nucleus_area * area_of_pixel, cytoplasm_area * area_of_pixel, ratio
def create_zip_file():
folders = [intermediate_folder, segmentation_folder]
csv_file = cell_descriptors_path
with zipfile.ZipFile(zip_file_path, "w") as zipf:
# Add folders to the zip file
for folder in folders:
for root, dirs, files in os.walk(folder):
for file in files:
file_path = os.path.join(root, file)
arcname = os.path.relpath(file_path, os.path.join(folder, ".."))
zipf.write(file_path, arcname=arcname)
# Add the CSV file to the zip file
zipf.write(csv_file, arcname=os.path.basename(csv_file))