Skip to content

Commit 328df66

Browse files
author
denisovg
committed
Initial implementations of the Rhoana's classifier training and GALA's 2D segmentation scripts. Added or modified a number of utility scripts.
1 parent 03a40d7 commit 328df66

22 files changed

+905
-208
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
#! /usr/local/python-2.7.6/bin/python
2+
#
3+
# Copyright (C) 2015 by Howard Hughes Medical Institute.
4+
#
5+
# Purpose: perform 2D segmentation using GALA
6+
# then post-process results
7+
#
8+
# ------------------------- imports -------------------------
9+
10+
#from __future__ import absolute_import
11+
#from __future__ import print_function
12+
# imports
13+
import os, sys, re, optparse
14+
from gala import imio, classify, features, agglo, evaluate as ev
15+
from six.moves import map
16+
import numpy as np
17+
18+
import MS_LIB_Dict
19+
import MS_LIB_Options
20+
import MS_LIB_IO
21+
22+
from PIL import Image
23+
24+
ms_home = os.environ['MS_HOME'] # where source code is located
25+
ms_data = os.environ['MS_DATA'] # dir for initial input data and final output
26+
ms_temp = os.environ['MS_TEMP'] # dir for intermediate data files
27+
gala_home = os.environ['GALA_HOME'] # where source code is located
28+
ilastik_home = os.environ['ILASTIK_HOME'] # where source code is located
29+
30+
# -----------------------------------------------------------------------------
31+
32+
def perform_segmentation(training_raw, groundtruth_annot_dir, \
33+
groundtruth_seg_dir, production_raw, \
34+
options):
35+
raw_files = os.listdir(os.path.join(ms_data, training_raw))
36+
labels = os.listdir(os.path.join(ms_data, groundtruth_annot_dir))
37+
38+
# Assume only one raw and one labels file for now
39+
command = "MS_UT_CreateH5LabelsForIlastik.py " + groundtruth_annot_dir + \
40+
" groundtruth.h5"
41+
print "\nRunning the commmand: " , command
42+
os.system(command)
43+
44+
# Generate Ilastik project file
45+
command = "python " + os.path.join(ilastik_home, "ilastik", "bin", "train_headless.py") + \
46+
" training.ilp '" + training_raw + "/*.png' groundtruth.h5/main"
47+
print "\nRunning the commmand: " , command
48+
os.system(command)
49+
50+
# Produce the probabilities and oversegmentation files from the inputs
51+
if not os.path.isdir('seg_data'):
52+
print "\nRunning the commmand: mkdir seg_data"
53+
os.mkdir('seg_data')
54+
else:
55+
print "\nRunning the commmand: rm -f seg_data/*"
56+
os.system("rm -rf seg_data/*")
57+
if os.path.isfile('STACKED_prediction.h5'):
58+
command = "rm -f STACKED_prediction.h5"
59+
print "\nRunning the commmand: " , command
60+
os.system(command)
61+
if not os.path.islink('gala-segmentation-pipeline'):
62+
os.symlink('gala-segmentation-pipeline', os.path.join(gala_home, 'gala',\
63+
'bin', 'gala-segmentation-pipeline'))
64+
command = "python gala-segmentation-pipeline " + \
65+
" . -I '" + training_raw + "/*.png' --ilp-file training.ilp " + \
66+
" --enable-gen-supervoxels --enable-gen-agglomeration " + \
67+
" --enable-gen-pixel --seed-size 5 --segmentation-thresholds 0.0"
68+
print "\nRunning the commmand: " , command
69+
os.system(command)
70+
71+
# Put probabilities in the right format:
72+
command = "MS_UT_ProbsNF2GALA.py STACKED_prediction.h5 probabilities_training.h5"
73+
print "\nRunning the commmand: ", command
74+
os.system(command)
75+
76+
# Rename the oversegmentation training file
77+
for file in os.listdir("seg_data"):
78+
if re.search(".h5", file):
79+
oversegmentation_file = os.path.join("seg_data", file)
80+
command = "mv " + oversegmentation_file + " oversegmentation_training.h5"
81+
print "\nRunning the commmand: ", command
82+
os.system(command)
83+
84+
# Create the groundtruuth segmentation labels file
85+
command = "MS_UT_CreateH5Groundtruth.py " + groundtruth_seg_dir + " seg_labels_file.h5"
86+
print "\nRunning the commmand: " , command
87+
os.system(command)
88+
89+
# Read in training data
90+
print "\nReading training data into gala..."
91+
gt_train, pr_train, ws_train = (map(imio.read_h5_stack,
92+
['seg_labels_file.h5', 'probabilities_training.h5',
93+
'oversegmentation_training.h5']))
94+
95+
# create a feature manager
96+
fm = features.moments.Manager()
97+
fh = features.histogram.Manager()
98+
fc = features.base.Composite(children=[fm, fh])
99+
100+
# create graph and obtain a training dataset
101+
g_train = agglo.Rag(ws_train, pr_train, feature_manager=fc)
102+
(X, y, w, merges) = g_train.learn_agglomerate(gt_train, fc)[0]
103+
y = y[:, 0] # gala has 3 truth labeling schemes, pick the first one
104+
print((X.shape, y.shape)) # standard scikit-learn input format
105+
106+
# train a classifier, scikit-learn syntax
107+
rf = classify.DefaultRandomForest().fit(X, y)
108+
# a policy is the composition of a feature map and a classifier
109+
learned_policy = agglo.classifier_probability(fc, rf)
110+
111+
if not os.path.isdir('seg_data'):
112+
print "\nRunning the commmand: mkdir seg_data"
113+
os.mkdir('seg_data')
114+
else:
115+
command = "rm -f seg_data/*"
116+
print "\nRunning the commmand: ", command
117+
os.system(command)
118+
if os.path.isfile('STACKED_prediction.h5'):
119+
command = "rm -f STACKED_prediction.h5"
120+
print "\nRunning the commmand: " , command
121+
os.system(command)
122+
123+
# Produce the probabilities and oversegmentation files from the inputs
124+
command = "python " + os.path.join(gala_home, "gala", "bin", "gala-segmentation-pipeline") + \
125+
" . -I '" + productiobn_raw + "/*.png' --ilp-file training.ilp " + \
126+
" --enable-gen-supervoxels --enable-gen-agglomeration " + \
127+
" --enable-gen-pixel --seed-size 5 --segmentation-thresholds 0.0"
128+
print "\nRunning the commmand: ", command
129+
os.system(command)
130+
131+
# Put probabilities in the right format:
132+
if os.path.isdir("seg_data"):
133+
print "\nRunning the commmand: rm -rf seg_data"
134+
os.system("rm -rf seg_data")
135+
command = "MS_UT_ProbsNF2GALA.py STACKED_prediction.h5 probabilities_production.h5"
136+
print "\nRunning the commmand: ", command
137+
os.system(command)
138+
139+
# Rename the oversegmentation production file
140+
for file in os.listdir("seg_data"):
141+
if re.search(".h5", file):
142+
oversegmentation_file = os.path.join("seg_data", file)
143+
command = "mv " + oversegmentation_file + " oversegmentation_production.h5"
144+
145+
# get the production data and make a RAG with the trained policy
146+
pr_test, ws_test = (map(imio.read_h5_stack,
147+
['probabilities_production.h5', 'oversegmentation_production.h5']))
148+
g_test = agglo.Rag(ws_test, pr_test, learned_policy, feature_manager=fc)
149+
g_test.agglomerate(0.5) # best expected segmentation
150+
seg_production = g_test.get_segmentation()
151+
152+
# Output the segmentation file
153+
img = Image.fromarray(seg_production)
154+
img.save('segmentation_production.h5')
155+
156+
157+
# -----------------------------------------------------------------------------
158+
159+
def output_results(ws_test, gt_test, seg_test1):
160+
results = np.vstack((
161+
ev.split_vi(ws_test, gt_test),
162+
ev.split_vi(seg_test1, gt_test),
163+
))
164+
print(results)
165+
166+
# -----------------------------------------------------------------------------
167+
168+
if __name__ == "__main__":
169+
170+
usage = "Usage: \n\
171+
%prog <raw_train_data> <gt_labels> <raw_data> [options (-h to list)]"
172+
173+
parser = optparse.OptionParser(usage=usage, version="%%prog ")
174+
parser = MS_LIB_Options.GalaSegmentation2D_command_line_parser(parser)
175+
(options, args) = parser.parse_args()
176+
177+
if len(args) == 4:
178+
training_raw = args[0]
179+
gt_annot_labels = args[1]
180+
gt_seg_labels = args[2]
181+
production_raw = args[3]
182+
perform_segmentation(training_raw, gt_annot_labels, gt_seg_labels, \
183+
production_raw, options)
184+
else:
185+
parser.print_usage()
186+
sys.exit(2)
187+

RhoanaSegmentation/MS_RS_RhoanaSegmentation2D.py

+18-34
Original file line numberDiff line numberDiff line change
@@ -32,34 +32,25 @@ def produce_segmentation(input_data, probs_file_list, options):
3232
"Segment", "segment.py")
3333
for i in range(0, len(probs_file_list)):
3434
probs_file = ntpath.basename(probs_file_list[i])
35-
output_file = probs_file.split(".")[0] + ".png"
36-
output_dir = os.path.join(ms_data, "seg_" + options.output_tag)
35+
output_file = probs_file.split(".")[0] + ".h5"
36+
if re.search("mitochondria", options.classifier):
37+
output_dir = os.path.join(ms_data, "segmentation_2D_bw_mitochondria_" \
38+
+ options.output_tag)
39+
else:
40+
output_dir = os.path.join(ms_data, "segmentation_2D_bw_membranes_" \
41+
+ options.output_tag)
3742
if not os.path.isdir(output_dir):
3843
os.mkdir(output_dir)
3944
command = "python " + segmentation_script + " " + probs_file_list[i] +\
40-
" " + os.path.join(ms_data, output_file)
45+
" " + os.path.join(output_dir, output_file)
46+
if options.verbose:
47+
print "\nSegmentation command=", command, "\n"
4148
os.system(command)
4249
return
4350

4451
# -----------------------------------------------------------------------------
4552

46-
def invert_probabilities(h5_infile, h5_outfile):
47-
print "h5_outfile=", h5_outfile
48-
f = h5py.File(h5_infile, 'r')
49-
f2 = h5py.File(h5_outfile, 'w')
50-
keys = f.keys()
51-
for k in keys:
52-
if not k == "probabilities":
53-
f2.create_dataset(k, data = f[k])
54-
else:
55-
probs = f["probabilities"]
56-
inverse_probs = 1. - numpy.array(probs)
57-
f2.create_dataset("probabilities", data = inverse_probs)
58-
return
59-
60-
# -----------------------------------------------------------------------------
61-
62-
def compute_membrane_probabilities(input_data, file_list, options):
53+
def compute_segmented_object_probabilities(input_data, file_list, options):
6354
classify_image_executable = options.executable
6455
classifier_file = options.classifier
6556
output_file_list = []
@@ -68,28 +59,19 @@ def compute_membrane_probabilities(input_data, file_list, options):
6859
print "input_file_path=", input_file_path
6960
input_file = ntpath.basename(input_file_path)
7061
output_file = input_file.split(".")[0] + ".h5"
71-
output_dir = os.path.join(ms_data, "probs_" + input_data)
62+
input_tag = input_data
63+
if input_data[:4] == "raw_":
64+
input_tag = input_data[4:]
65+
output_dir = os.path.join(ms_data, options.seg_type + "_prob_" + input_tag)
7266
if not os.path.isdir(output_dir):
7367
os.mkdir(output_dir)
74-
if input_data[0:4] == "raw_":
75-
output_dir = os.path.join(ms_data, "probs_" + input_data[4:])
76-
output_dir2 = os.path.join(ms_data, "probs_inv_" + input_data[4:])
7768
output_file_path = os.path.join(output_dir, output_file)
7869
output_file_list.append(output_file_path)
7970
command = classify_image_executable + " " + input_file_path + " " + \
8071
classifier_file + " " + output_file_path
8172
if options.verbose:
8273
print "...command=", command
8374
os.system(command)
84-
# Inverse probabilities
85-
if options.inverse_probabilities:
86-
output_dir2 = os.path.join(ms_data, "probs_inv_" + input_data)
87-
if input_data[0:4] == "raw_":
88-
output_dir2 = os.path.join(ms_data, "probs_inv_" + input_data[4:])
89-
if not os.path.isdir(output_dir2):
90-
os.mkdir(output_dir2)
91-
output_file_path2= os.path.join(output_dir2, output_file)
92-
invert_probabilities(output_file_path, output_file_path2)
9375
return output_file_list
9476

9577
# -----------------------------------------------------------------------------
@@ -146,7 +128,7 @@ def process_input_data(input_data, input_type, input_label, options):
146128

147129
if len(input_file_list) > 0:
148130
if int(options.processing_start) == 1:
149-
probs_file_list = compute_membrane_probabilities(input_data, \
131+
probs_file_list = compute_segmented_object_probabilities(input_data, \
150132
filtered_input_file_list, options)
151133

152134
if int(options.processing_end) == 2:
@@ -190,6 +172,8 @@ def process_input_data(input_data, input_type, input_label, options):
190172
sys.exit(2)
191173
if options.verbose:
192174
print "\nProcessing input data ..."
175+
if len(options.output_tag) == 0:
176+
options.output_tag = input_data
193177
process_input_data(input_data, input_type, input_label, options)
194178
else:
195179
parser.print_usage()

0 commit comments

Comments
 (0)