]> Creatis software - clitk.git/blob - scripts/create_midP_masks-2.0.sh
Merge commit '488f24aa984ae24adc9458bf5fbf3b2351415742'
[clitk.git] / scripts / create_midP_masks-2.0.sh
1 #! /bin/bash -x
2
3 ###############################################################################
4 #
5 # FILE: create_midP-2.0.sh
6 # AUTHOR: RĂ´mulo Pinho 05/08/2011
7 #
8 # Version 2.0 of the create_midP_masks.sh script. The most relevant changes are:
9 #   * creation of bands around input and output image regions to try to improve 
10 #   the registration along lung boundaries (naturally, it depends on the quality
11 #   of motion mask generation).
12 #   * some steps are now in different modules, to facilitate re-use (see "includes" section).
13 #   * minor modifications on output file names.
14 #   * attempt to simplify the code a bit.
15 #
16 ###############################################################################
17
18 source `dirname $0`/midp_common.sh
19
20 extract_patient()
21 {
22   echo "$phase_file -> Extracting patient..."
23   clitkExtractPatient -i $phase_file -o $mask_dir_tmp/patient_mask_$phase_nb.mhd --noAutoCrop -a $afdb_file $ExtractPatientExtra
24   clitkSetBackground -i $phase_file -o $mask_dir_tmp/patient_$phase_nb.mhd --mask $mask_dir_tmp/patient_mask_$phase_nb.mhd --outsideValue -1000
25 }
26
27 extract_bones()
28 {
29   if [ x = x$ExtractBonesLower1 ]; then
30     ExtractBonesLower1=120
31   fi
32   if [ x = x$ExtractBonesLower2 ]; then
33     ExtractBonesLower2=80
34   fi
35   echo "$phase_file -> Extracting bones..."
36   clitkImageConvert -i $phase_file -o $mask_dir_tmp/float_$phase_nb.mhd -t float
37   clitkExtractBones -i $mask_dir_tmp/float_$phase_nb.mhd -o $mask_dir_tmp/bones_$phase_nb.mhd -a $afdb_file --lower1 $ExtractBonesLower1 --upper1 2000 --lower2 $ExtractBonesLower2 --upper2 2000 --smooth --time 0.0625 --noAutoCrop
38 }
39
40 extract_lungs()
41 {
42   echo "$phase_file -> Extracting lungs..."
43   clitkExtractLung -i $phase_file -o $mask_dir_tmp/lungs_$phase_nb.mhd -a $afdb_file --noAutoCrop
44 }
45
46 resample()
47 {
48   echo "$phase_file -> Resampling..."
49   clitkResampleImage -i $mask_dir_tmp/patient_$phase_nb.mhd -o $mask_dir_tmp/patient_$phase_nb.mhd --spacing $resample_spacing --interp $resample_algo
50
51   clitkResampleImage -i $mask_dir_tmp/lungs_$phase_nb.mhd -o $mask_dir_tmp/lungs_$phase_nb.mhd --like $mask_dir_tmp/patient_$phase_nb.mhd
52 }
53
54 compute_motion_mask()
55 {
56   if [ x = x$MotionMaskOffsetDetect ]; then
57     MotionMaskOffsetDetect="0,-5,0"
58   fi
59   if [ x = x$FillingLevel ]; then
60     FillingLevel=94
61   fi
62
63   clitkMotionMask -i $mask_dir_tmp/patient_$phase_nb.mhd -o $mask_dir_tmp/mm_$phase_nb.mhd --featureLungs $mask_dir_tmp/lungs_$phase_nb.mhd --upperThresholdLungs -400 --fillingLevel $FillingLevel --offsetDetect $MotionMaskOffsetDetect --pad --writeFeature=$mask_dir_tmp/feature_$phase_nb.mhd $MotionMaskExtra 
64   #--monitor=$mask_dir_tmp/monitor_$phase_nb.mhd
65 }
66
67 create_banded_mask()
68 {
69   input=$1
70   input_mask=$2
71   output=$3
72   output_mask=$4
73   radius=$5
74
75   input_dir=`dirname $input`
76   input_base=`basename $input`
77
78   # first band
79   clitkMorphoMath -i $input_mask -o $input_dir/extra1_$input_base --type 1 --radius $radius
80   clitkImageArithm -i $input_dir/extra1_$input_base -j $input_mask -o $input_dir/band1_$input_base -t 7
81   clitkBinarizeImage -i $input_dir/band1_$input_base -o $input_dir/band1_$input_base -l 1 -u 1 --fg 100 --mode both
82   clitkImageConvert -i $input_dir/band1_$input_base -o $input_dir/short_band1_$input_base -t short
83   
84   # second band
85   clitkMorphoMath -i $input_dir/extra1_$input_base -o $input_dir/extra2_$input_base --type 1 --radius $radius
86   clitkImageArithm -i $input_dir/extra2_$input_base -j $input_dir/extra1_$input_base -o $input_dir/band2_$input_base -t 7
87   clitkBinarizeImage -i $input_dir/band2_$input_base -o $input_dir/band2_$input_base -l 1 -u 1 --fg 200 --mode both
88   clitkImageConvert -i $input_dir/band2_$input_base -o $input_dir/short_band2_$input_base -t short
89   
90   # combine bands with masks
91   clitkImageArithm -i $input_mask -j $input_dir/band1_$input_base -o $output_mask -t 0
92   clitkImageArithm -i $output_mask -j $input_dir/band2_$input_base -o $output_mask -t 0
93   # combine bands with image
94   clitkCombineImage -i $input_dir/short_band1_$input_base -j $input -m $input_dir/band1_$input_base -o $output
95   clitkCombineImage -i $input_dir/short_band2_$input_base -j $output -m $input_dir/band2_$input_base -o $output
96
97   # clean-up
98   rm `echo $input_dir/extra?_$input_base | sed 's:.mhd:.*:g'`
99   rm `echo $input_dir/band?_$input_base | sed 's:.mhd:.*:g'`
100   rm `echo $input_dir/short_band?_$input_base | sed 's:.mhd:.*:g'`
101 }
102
103 create_registration_masks()
104 {
105   # extract inside and outside lung regions from the patient image, 
106   # using the motion mask computed previously
107   echo "$phase_file -> Setting Background..."
108   clitkSetBackground -i $mask_dir_tmp/patient_$phase_nb.mhd -o $mask_dir_tmp/inside_$phase_nb.mhd --mask $mask_dir_tmp/mm_$phase_nb.mhd --outsideValue -1200
109   clitkSetBackground -i $mask_dir_tmp/patient_$phase_nb.mhd -o $mask_dir_tmp/outside_$phase_nb.mhd --mask $mask_dir_tmp/mm_$phase_nb.mhd --outsideValue -1200 --fg
110
111   # the registration masks for inside (and outside) region correspond
112   # to the motion mask (and its complement) plus extra grey value bands,
113   # obtained with morphological dilations.
114   # 
115   echo "$phase_file -> Creating registration masks..."
116   # inside
117   create_banded_mask $mask_dir_tmp/inside_$phase_nb.mhd $mask_dir_tmp/mm_$phase_nb.mhd $mask_dir_tmp/banded_inside_$phase_nb.mhd $mask_dir_tmp/mask_inside_$phase_nb.mhd 4
118   # outside 
119   clitkExtractPatient -i $mask_dir_tmp/outside_$phase_nb.mhd -o $mask_dir_tmp/mm_outside_$phase_nb.mhd --noAutoCrop
120   create_banded_mask $mask_dir_tmp/outside_$phase_nb.mhd $mask_dir_tmp/mm_outside_$phase_nb.mhd $mask_dir_tmp/banded_outside_$phase_nb.mhd $mask_dir_tmp/mask_outside_$phase_nb.mhd 4
121 }
122
123 mm_preprocessing()
124 {
125   extract_patient
126   # extract_bones
127   extract_lungs
128   # remove_tmp_masks 1
129   resample
130 }
131
132 mm_postprocessing()
133 {
134   # remove_tmp_masks 2
135   # remove_tmp_masks 3
136   create_registration_masks
137 }
138
139 motion_mask()
140 {
141   #set cmd line variables
142   mhd4d=$1
143   resample_spacing=$2
144   resample_algo=$3
145
146   dir=`dirname $1`
147   cd $dir
148     
149   # import variables specific to each patient
150   source ./variables
151
152   #set other global variables
153   mask_dir="MASK-${resample_spacing}mm-$resample_algo"
154   mask_dir_tmp="tmp.$mask_dir"
155   extract_4d_phases $mhd4d
156
157   echo
158   echo "------------ Motion mask from create_midP_masks.sh ------------"
159   start=`date`
160   echo "start: $start"
161   echo
162
163   # the motion masks are first created in a tmp directory. this directory is 
164   # later going to be renamed to the final motion mask directory. concurrent
165   # executions trying to create the same set of masks will be blocked until
166   # the first execution finishes. naturally, these other executions will not
167   # recreate the masks. so first we try to create the tmp directory. 
168   # if the creation fails, it means that another execution is
169   # already creating the masks, so this execution will be blocked. the
170   # execution is unblocked only when the creation of masks is finished and
171   # the mask directory is renamed.
172   #
173   # ATTENTION: RP - 08/02/2011
174   # robustness issue: tmp directory may exist but may be empty or 
175   # incomplete. the solution is to check per file, but I'll leave it like 
176   # this for the moment.
177   do_mm=0
178   if [ $(ls -d $mask_dir 2> /dev/null | wc -l) -eq 0 ]; then
179     mkdir $mask_dir_tmp 2> /dev/null
180     return_mkdir=$?
181     if [ $return_mkdir == 0 ]; then
182       do_mm=1 
183     else
184       while [[ $(ls -d $mask_dir 2> /dev/null | wc -l) -eq 0 ]]; do
185         echo "waiting creation of motion masks..."
186         sleep 2
187       done
188       echo "finished waiting"
189     fi  
190   fi
191   
192 #   do_mm=1
193 #   mask_dir_tmp=$mask_dir
194   if [ $do_mm == 1 ]; then
195     mask_log_dir=$mask_dir_tmp/LOG
196     mkdir -p $mask_log_dir
197
198     # multi-threaded pre-processing for motion mask calcs
199     for i in $( seq 0 $((${#phase_nbs[@]} - 1))); do
200       phase_nb=${phase_nbs[$i]}
201       phase_file=${phase_files[$i]}
202       afdb_file=`echo $phase_file | sed 's/mhd/afdb/'`
203
204       check_threads $MAX_THREADS
205       mm_preprocessing &
206     done
207
208     # single-threaded motion mask calc
209     for i in $( seq 0 $((${#phase_nbs[@]} - 1))); do
210       phase_nb=${phase_nbs[$i]}
211       phase_file=${phase_files[$i]}
212
213       check_threads 1
214       echo "$phase_file -> Computing motion mask..."
215       compute_motion_mask > $mask_log_dir/motion_mask_$phase_file.log
216     done
217
218     # multi-threaded post-processing of motion mask calcs
219     for i in $( seq 0 $((${#phase_nbs[@]} - 1))); do
220       phase_nb=${phase_nbs[$i]}
221       phase_file=${phase_files[$i]}
222
223       check_threads $MAX_THREADS 
224       mm_postprocessing &
225     done
226
227     # rename tmp mask directory after mask creation
228     check_threads 1
229     mv -f $mask_dir_tmp $mask_dir
230   fi
231
232   echo
233   echo "-------- Motion mask done ! ---------"
234   end=`date`
235   echo "start: $start"
236   echo "end: $end"
237   echo
238 }
239
240
241 #################
242 # main  #
243 #################
244
245 if [ $# != 3 ]; then
246   echo "Usage: $0 CT_4D RESAMPLE_SPACING RESAMPLE_ALGORITHM"
247   exit -1
248 fi
249
250 #
251 # variables exported in this scope
252 #
253 # mask_dir: directory where all masks are kept
254 #
255
256 if [ $1 != "using-as-lib" ]; then
257   motion_mask $1 $2 $3
258 fi