Last active
December 15, 2022 15:41
-
-
Save MartGro/c20c0cccc4886ce5df1103b4c995e0f7 to your computer and use it in GitHub Desktop.
How to create binary masks from a ImageJ ROI in python (from roi zip files)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# This relies on the read-roi library from here: https://github.com/hadim/read-roi | |
# Additionally, it requires shapely for the polygons | |
# And ray for parallelizing | |
from read_roi import read_roi_zip | |
import glob | |
#find all roi zip files | |
all_zip_path = glob.glob("your_folder/*.zip") | |
import re | |
#this is only for extracting the index from a naming convention of the zip files | |
#The files are called | |
#RoiSet_1.zip | |
#RoiSet_2.zip | |
#RoiSet_99.zip | |
#etc. | |
def extract_index(path: str) -> int: | |
# Use a regular expression to match the pattern of the file name | |
# and extract the index from the path | |
match = re.match(r'your_folder/RoiSet_(\d+)\.zip', path) | |
# If a match was found, return the index as an integer | |
if match: | |
return int(match.group(1)) | |
# If no match was found, return -1 | |
return -1 | |
dict_of_roi_dicts = {extract_index(path):read_roi_zip(path) for path in all_zip_path} | |
from shapely.geometry import Polygon | |
# This constructs a polygon from the x and y coordinates of the freehand path of the ROI | |
def construct_polygon(x: list, y: list) -> Polygon: | |
# Zip the x and y coordinates to create a list of (x, y) tuples | |
coordinates = list(zip(x, y)) | |
# Construct a polygon from the list of coordinates | |
polygon = Polygon(coordinates) | |
return polygon | |
import numpy as np | |
from shapely.geometry import Polygon, Point | |
import ray | |
ray.init() | |
#ATTENTION: THIS ASSUMES THAT THE FINAL IMAGE HAS SIZE 512x512. IF THIS IS NOT THE CASE: CHANGE IT ACCORDINGLY | |
@ray.remote | |
def create_array(polygon: Polygon) -> np.ndarray: | |
# Create an array of size 512x512 filled with zeros | |
array = np.zeros((512, 512)) | |
# Loop through all pixels in the array | |
for i in range(512): | |
for j in range(512): | |
point = Point(i, j) | |
# Check if the current pixel is within the polygon | |
if polygon.intersects(point): | |
# If the pixel is within the polygon, set it to 1 | |
array[i, j] = 1 | |
return array | |
def extract_particle_positions_into_matrix(input_dict: dict) -> list: | |
particles = input_dict.keys() | |
results = [] | |
for particle_index in particles: | |
#import pdb;pdb.set_trace() | |
particle = input_dict[particle_index] | |
polygon = construct_polygon(particle["x"],particle["y"]) | |
results.append(create_array.remote(polygon)) | |
out_results = [] | |
for result in results: | |
out_results.append(ray.get(result)) | |
return out_results | |
for roi_dict_key in dict_of_roi_dicts.keys(): | |
res = extract_particle_positions_into_matrix(dict_of_roi_dicts[roi_dict_key]) | |
sum_matrix = np.stack(res).sum(axis=0) | |
sum_matrix[sum_matrix>0] = 1 | |
sum_matrix[sum_matrix<1] = 0 | |
dict_of_roi_dicts[roi_dict_key]["particle_matrix"] = sum_matrix | |
print(f"Done {roi_dict_key}") | |
import imageio | |
# Create | |
for key in dict_of_roi_dicts.keys(): | |
print(f"{key}") | |
matrix = dict_of_roi_dicts[key]["particle_matrix"]*255 | |
matrix = matrix.astype(np.uint8).T | |
#import pdb;pdb.set_trace() | |
#img = Image.fromarray(matrix,mode="L") | |
#plt.imshow(matrix, cmap='matrix') | |
#img.save(f"cropped_blind 2_ROIs_gil/Relabel_mask_{key}_gil.png") | |
imageio.imwrite(f"cropped_blind 2_ROIs_gil/Relabel_mask_{key}_gil.png", matrix, format='png',) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Added code for generating .png images