1 /*=========================================================================
2 Program: vv http://www.creatis.insa-lyon.fr/rio/vv
5 - University of LYON http://www.universite-lyon.fr/
6 - Léon Bérard cancer center http://oncora1.lyon.fnclcc.fr
7 - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
9 This software is distributed WITHOUT ANY WARRANTY; without even
10 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11 PURPOSE. See the copyright notices for more information.
13 It is distributed under dual licence
15 - BSD See included LICENSE.txt file
16 - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
17 ======================================================================-====*/
19 #include "clitkLabelImageOverlapMeasureFilter.h"
21 //--------------------------------------------------------------------
22 template <class TImageType>
23 clitk::RelativePositionList<TImageType>::
24 RelativePositionList() {
25 ComputeOverlapFlagOff();
27 //--------------------------------------------------------------------
30 //--------------------------------------------------------------------
31 template <class TImageType>
33 clitk::RelativePositionList<TImageType>::
34 SetReferenceImageForOverlapMeasure(ImagePointer ref) {
36 ComputeOverlapFlagOn();
38 //--------------------------------------------------------------------
41 //--------------------------------------------------------------------
42 template <class TImageType>
44 clitk::RelativePositionList<TImageType>::
45 Read(std::string filename) {
47 The goal here is to read a text file that contains options for the
48 RelativePosition filter. The text file contains options in the
49 same form of the config file of the clitkRelativePosition tool. In
50 this text file, each time a "object" option is found, a new set of
51 options is considered.
56 openFileForReading(is, filename);
58 // Read input -> the structure name that will be used as input
64 FATAL("while reading RelativePositionList file. This file must start with 'input = '");
69 FATAL("while reading RelativePositionList file. This file must start with 'input = '");
76 // Create a temporary filename
77 char n[] = "tmp_clitkRelativePosition_XXXXXX";
78 mkstemp(n); // tmpnam(n);
79 std::string tmpfilename(n);
81 // Loop on the file text ; Every time we see a "object" token, we
85 std::ostringstream ss;
86 // first part of ss is the last 'object = ' found, stored in s
93 if (s.find("object") != std::string::npos) stop=true;
94 else ss << s << std::endl;
98 std::string text = ss.str();
99 if (text.size() > 10) { // if too small, it is not a list of option
101 openFileForWriting(os, tmpfilename);
103 os << "input = nothing" << std::endl;
104 os << "output = nothing" << std::endl;
107 // Create a struct to store options. I use two step to allow to
108 // fill the args values with de default and then check
109 // automatically the options.
110 ArgsInfoType args_info;
111 std::vector<char> writable(tmpfilename.size() + 1);
112 std::copy(tmpfilename.begin(), tmpfilename.end(), writable.begin());
113 char ** argv = new char*[1];
114 argv[0] = new char[1];
115 struct cmdline_parser_clitkRelativePosition_params params;
117 params.initialize = 1;
118 params.check_required = 0;
119 cmdline_parser_clitkRelativePosition_configfile(&writable[0], &args_info, 1, 1, 1);
120 mArgsInfoList.push_back(args_info);
122 // Delete the temporary file
123 std::remove(tmpfilename.c_str());
127 // Set the main input name
130 //--------------------------------------------------------------------
133 //--------------------------------------------------------------------
134 template <class TImageType>
136 clitk::RelativePositionList<TImageType>::
137 GenerateInputRequestedRegion()
140 itk::ImageToImageFilter<ImageType, ImageType>::GenerateInputRequestedRegion();
141 // Get input pointers and set requested region to common region
142 ImagePointer input1 = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(0));
143 input1->SetRequestedRegion(input1->GetLargestPossibleRegion());
145 //--------------------------------------------------------------------
149 //--------------------------------------------------------------------
150 template <class TImageType>
152 clitk::RelativePositionList<TImageType>::
153 GenerateOutputInformation() {
156 m_working_input = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(0));
158 // Loop on RelativePositionList of operations
159 std::string s = GetInputName();
160 for(uint i=0; i<mArgsInfoList.size(); i++) {
161 // clitk::PrintMemory(true, "Start");
162 std::string text = "["+s+"] limits ";
163 if (mArgsInfoList[i].orientation_given) text += std::string(mArgsInfoList[i].orientation_arg[0])+" ";
164 else text = text+"("+toString(mArgsInfoList[i].angle1_arg)+" "+
165 toString(mArgsInfoList[i].angle2_arg)+" "+
166 (mArgsInfoList[i].inverse_flag?"true":"false")+") ";
167 text = text+mArgsInfoList[i].object_arg+" "+toString(mArgsInfoList[i].threshold_arg);
168 if (mArgsInfoList[i].sliceBySlice_flag) {
169 text += " slice by slice";
172 text += " spacing=" + toString(mArgsInfoList[i].spacing_arg);
175 typename RelPosFilterType::Pointer relPosFilter;
177 // Is it slice by slice or 3D ?
178 if (mArgsInfoList[i].sliceBySlice_flag) {
179 typename SliceRelPosFilterType::Pointer f = SliceRelPosFilterType::New();
181 SetFilterOptions(relPosFilter, mArgsInfoList[i]);
183 // Set SbS specific options
184 f->SetUniqueConnectedComponentBySliceFlag(mArgsInfoList[i].uniqueCCL_flag);
185 f->SetObjectCCLSelectionFlag(mArgsInfoList[i].uniqueObjectCCL_flag);
186 f->IgnoreEmptySliceObjectFlagOn();
187 //f->SetObjectCCLSelectionDimension(0);
188 //f->SetObjectCCLSelectionDirection(-1);
189 //f->SetAutoCropFlag(false);
191 if (mArgsInfoList[i].verboseOptions_flag) f->PrintOptions();
194 relPosFilter = clitk::AddRelativePositionConstraintToLabelImageFilter<ImageType>::New();
195 SetFilterOptions(relPosFilter, mArgsInfoList[i]);
197 if (mArgsInfoList[i].verboseOptions_flag) relPosFilter->PrintOptions();
201 relPosFilter->SetInput(m_working_input);
204 relPosFilter->Update();
205 m_working_input = relPosFilter->GetOutput();
206 StopCurrentStep<ImageType>(m_working_input);
208 // Compute overlap with reference if needed
209 if (GetComputeOverlapFlag()) {
210 typedef clitk::LabelImageOverlapMeasureFilter<ImageType> FilterType;
211 typename FilterType::Pointer filter = FilterType::New();
212 filter->SetInput(0, m_working_input);
213 filter->SetInput(1, m_reference);
219 //--------------------------------------------------------------------
222 //--------------------------------------------------------------------
223 template <class TImageType>
225 clitk::RelativePositionList<TImageType>::
228 // Final Step -> set output
229 this->GraftOutput(m_working_input);
231 //--------------------------------------------------------------------
234 //--------------------------------------------------------------------
235 template <class TImageType>
237 clitk::RelativePositionList<TImageType>::
238 SetFilterOptions(typename RelPosFilterType::Pointer filter, ArgsInfoType & options) {
240 if (options.orientation_given > 1) {
241 clitkExceptionMacro("Error in the RelPos options. I need a single --orientation (for the moment)."
242 << " Current options are for obj = '" << options.object_arg
243 << "', threshold = " << options.threshold_arg << std::endl);
246 ImagePointer object = GetAFDB()->template GetImage<ImageType>(options.object_arg);
247 filter->SetInputObject(object);
248 filter->WriteStepFlagOff();
249 filter->SetVerboseImageSizeFlag(GetVerboseImageSizeFlag());
250 filter->SetFuzzyThreshold(options.threshold_arg);
251 filter->SetInverseOrientationFlag(options.inverse_flag); // MUST BE BEFORE AddOrientationTypeString
253 if (options.orientation_given == 1) {
254 for(uint i=0; i<options.orientation_given; i++)
255 filter->AddOrientationTypeString(options.orientation_arg[i]);
258 if (options.angle1_given && options.angle2_given) {
259 filter->AddAnglesInDeg(options.angle1_arg, options.angle2_arg);
262 clitkExceptionMacro("Error in the RelPos options. I need --orientation or (--angle1 and --angle2)."
263 << " Current options are for obj = '" << options.object_arg
264 << "', threshold = " << options.threshold_arg << std::endl);
267 filter->SetIntermediateSpacing(options.spacing_arg);
268 if (options.spacing_arg == -1) filter->IntermediateSpacingFlagOff();
269 else filter->IntermediateSpacingFlagOn();
270 filter->SetVerboseStepFlag(options.verboseStep_flag);
271 filter->SetAutoCropFlag(!options.noAutoCrop_flag);
273 //--------------------------------------------------------------------