]> Creatis software - clitk.git/blob - scripts/create_midP_masks-2.0.sh
Motion mask without resampling
[clitk.git] / scripts / create_midP_masks-2.0.sh
1 #! /bin/bash 
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 #   abort_on_error clitkExtractPatient $?
25
26   clitkSetBackground -i $phase_file -o $mask_dir_tmp/patient_$phase_nb.mhd --mask $mask_dir_tmp/patient_mask_$phase_nb.mhd --outsideValue -1000
27 #   abort_on_error clitkSetBackground $?
28 }
29
30 extract_bones()
31 {
32   if [ x = x$ExtractBonesLower1 ]; then
33     ExtractBonesLower1=120
34   fi
35   if [ x = x$ExtractBonesLower2 ]; then
36     ExtractBonesLower2=80
37   fi
38   echo "$phase_file -> Extracting bones..."
39   clitkImageConvert -i $phase_file -o $mask_dir_tmp/float_$phase_nb.mhd -t float
40   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
41 }
42
43 extract_lungs()
44 {
45   echo "$phase_file -> Extracting lungs..."  
46   clitkExtractLung -i $phase_file -o $mask_dir_tmp/lungs_$phase_nb.mhd -a $afdb_file --noAutoCrop --doNotSeparateLungs
47 }
48
49
50
51 resample()
52 {
53   echo "$phase_file -> Resampling..."
54   clitkResampleImage -i $mask_dir_tmp/patient_$phase_nb.mhd -o $mask_dir_tmp/patient_$phase_nb.mhd --spacing $resample_spacing --interp $resample_algo
55   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
56 }
57
58 compute_motion_mask()
59 {
60   if [ x = x$MotionMaskOffsetDetect ]; then
61     MotionMaskOffsetDetect="0,-5,0"
62   fi
63   if [ x = x$FillingLevel ]; then
64     FillingLevel=94
65   fi
66
67   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 
68   #--monitor=$mask_dir_tmp/monitor_$phase_nb.mhd
69 }
70
71 create_banded_mask()
72 {
73   input=$1
74   input_mask=$2
75   output=$3
76   output_mask=$4
77   radius=$5
78
79   input_dir=`dirname $input`
80   input_base=`basename $input`
81
82   # first band
83   clitkMorphoMath -i $input_mask -o $input_dir/extra1_$input_base --type 1 --radius $radius
84   clitkImageArithm -i $input_dir/extra1_$input_base -j $input_mask -o $input_dir/band1_$input_base -t 7
85   clitkBinarizeImage -i $input_dir/band1_$input_base -o $input_dir/band1_$input_base -l 1 -u 1 --fg 100 --mode both
86   clitkImageConvert -i $input_dir/band1_$input_base -o $input_dir/short_band1_$input_base -t short
87   
88   # second band
89   clitkMorphoMath -i $input_dir/extra1_$input_base -o $input_dir/extra2_$input_base --type 1 --radius $radius
90   clitkImageArithm -i $input_dir/extra2_$input_base -j $input_dir/extra1_$input_base -o $input_dir/band2_$input_base -t 7
91   clitkBinarizeImage -i $input_dir/band2_$input_base -o $input_dir/band2_$input_base -l 1 -u 1 --fg 200 --mode both
92   clitkImageConvert -i $input_dir/band2_$input_base -o $input_dir/short_band2_$input_base -t short
93   
94   # combine bands with masks
95   clitkImageArithm -i $input_mask -j $input_dir/band1_$input_base -o $output_mask -t 0
96   clitkImageArithm -i $output_mask -j $input_dir/band2_$input_base -o $output_mask -t 0
97   # combine bands with image
98   clitkCombineImage -i $input_dir/short_band1_$input_base -j $input -m $input_dir/band1_$input_base -o $output
99   clitkCombineImage -i $input_dir/short_band2_$input_base -j $output -m $input_dir/band2_$input_base -o $output
100
101   # clean-up
102   rm `echo $input_dir/extra?_$input_base | sed 's:.mhd:.*:g'`
103   rm `echo $input_dir/band?_$input_base | sed 's:.mhd:.*:g'`
104   rm `echo $input_dir/short_band?_$input_base | sed 's:.mhd:.*:g'`
105 }
106
107 create_registration_masks()
108 {
109   # extract inside and outside lung regions from the patient image, 
110   # using the motion mask computed previously
111   echo "$phase_file -> Setting Background..."
112   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
113   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
114
115   # the registration masks for inside (and outside) region correspond
116   # to the motion mask (and its complement) plus extra grey value bands,
117   # obtained with morphological dilations.
118   # 
119   echo "$phase_file -> Creating registration masks..."
120   # inside
121   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
122   # outside 
123   clitkExtractPatient -i $mask_dir_tmp/outside_$phase_nb.mhd -o $mask_dir_tmp/mm_outside_$phase_nb.mhd --noAutoCrop
124   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
125 }
126
127 mm_preprocessing()
128 {
129   extract_patient
130   # extract_bones
131   extract_lungs
132   # remove_tmp_masks 1
133   if [ $resample_spacing -ne 0 ] ; then 
134     resample
135   fi
136 }
137
138 mm_postprocessing()
139 {
140   # remove_tmp_masks 2
141   # remove_tmp_masks 3
142   create_registration_masks
143 }
144
145 motion_mask()
146 {
147   #set cmd line variables
148   mhd4d=$1
149   if [ $# -eq 3 ] ; then
150     resample_spacing=$2
151     resample_algo=$3
152   else
153     resample_spacing=0
154     resample_algo=0
155   fi
156
157   dir=`dirname $1`
158   cd $dir
159     
160   # import variables specific to each patient
161   if test -e ./variables; then
162     source ./variables
163   fi
164
165   #set other global variables
166   if [ $resample_spacing -ne 0 ] ; then
167     mask_dir="MASK-${resample_spacing}mm-$resample_algo"
168   else
169     mask_dir="MASK"
170   fi
171   mask_dir_tmp="tmp.$mask_dir"
172   extract_4d_phases $mhd4d
173
174   echo
175   echo "------------ Motion mask from create_midP_masks.sh ------------"
176   start=`date`
177   echo "start: $start"
178   echo
179
180   # the motion masks are first created in a tmp directory. this directory is 
181   # later going to be renamed to the final motion mask directory. concurrent
182   # executions trying to create the same set of masks will be blocked until
183   # the first execution finishes. naturally, these other executions will not
184   # recreate the masks. so first we try to create the tmp directory. 
185   # if the creation fails, it means that another execution is
186   # already creating the masks, so this execution will be blocked. the
187   # execution is unblocked only when the creation of masks is finished and
188   # the mask directory is renamed.
189   #
190   # ATTENTION: RP - 08/02/2011
191   # robustness issue: tmp directory may exist but may be empty or 
192   # incomplete. the solution is to check per file, but I'll leave it like 
193   # this for the moment.
194   do_mm=0
195   if [ $(ls -d $mask_dir 2> /dev/null | wc -l) -eq 0 ]; then
196     mkdir $mask_dir_tmp 2> /dev/null
197     return_mkdir=$?
198     if [ $return_mkdir == 0 ]; then
199       do_mm=1 
200     else
201       while [[ $(ls -d $mask_dir 2> /dev/null | wc -l) -eq 0 ]]; do
202         echo "waiting creation of motion masks..."
203         sleep 2
204       done
205       echo "finished waiting"
206     fi  
207   fi
208   
209 #   do_mm=1
210 #   mask_dir_tmp=$mask_dir
211   if [ $do_mm == 1 ]; then
212     mask_log_dir=$mask_dir_tmp/LOG
213     mkdir -p $mask_log_dir
214
215     # multi-threaded pre-processing for motion mask calcs
216     pids=( )
217     for i in $( seq 0 $((${#phase_nbs[@]} - 1))); do
218       phase_nb=${phase_nbs[$i]}
219       phase_file=${phase_files[$i]}
220       afdb_file=`echo $phase_file | sed 's/mhd/afdb/'`
221
222       check_threads $MAX_THREADS
223       mm_preprocessing &
224       pids=( "${pids[@]}" "$!" )
225     done
226
227     wait_pids ${pids[@]}
228     for ret in $ret_codes; do
229       abort_on_error mm_preprocessing $ret clean_up_masks
230     done
231
232     # single-threaded motion mask calc
233     for i in $( seq 0 $((${#phase_nbs[@]} - 1))); do
234       phase_nb=${phase_nbs[$i]}
235       phase_file=${phase_files[$i]}
236
237       check_threads 1
238       echo "$phase_file -> Computing motion mask..."
239       compute_motion_mask > $mask_log_dir/motion_mask_$phase_file.log
240       abort_on_error compute_motion_mask $? clean_up_masks
241     done
242
243     # multi-threaded post-processing of motion mask calcs
244     pids=( )
245     for i in $( seq 0 $((${#phase_nbs[@]} - 1))); do
246       phase_nb=${phase_nbs[$i]}
247       phase_file=${phase_files[$i]}
248
249       check_threads $MAX_THREADS 
250       mm_postprocessing &
251       pids=( "${pids[@]}" "$!" )
252     done
253   
254     wait_pids ${pids[@]}
255     for ret in $ret_codes; do
256       abort_on_error mm_postprocessing $ret clean_up_masks
257     done
258
259
260     # rename tmp mask directory after mask creation
261     check_threads 1
262     mv -f $mask_dir_tmp $mask_dir
263   fi
264
265   echo
266   echo "-------- Motion mask done ! ---------"
267   end=`date`
268   echo "start: $start"
269   echo "end: $end"
270   echo
271 }
272
273
274 #################
275 # main  #
276 #################
277
278 if [ $# -ne 3 -a $# -ne 1 ]; then
279   echo "Usage: $0 CT_4D [RESAMPLE_SPACING RESAMPLE_ALGORITHM]"
280   exit -1
281 fi
282
283 #
284 # variables exported in this scope
285 #
286 # mask_dir: directory where all masks are kept
287 #
288
289 if [ $1 != "using-as-lib" ]; then
290   if [ $# -eq 3 ] ; then
291     motion_mask $1 $2 $3
292   else
293     motion_mask $1
294   fi
295 fi