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 ======================================================================-====*/
20 //--------------------------------------------------------------------
21 template <class TImageType>
22 clitk::RelativePositionList<TImageType>::
23 RelativePositionList() {
25 //--------------------------------------------------------------------
28 //--------------------------------------------------------------------
29 template <class TImageType>
31 clitk::RelativePositionList<TImageType>::
32 Read(std::string filename) {
34 The goal here is to read a text file that contains options for the
35 RelativePosition filter. The text file contains options in the
36 same form of the config file of the clitkRelativePosition tool. In
37 this text file, each time a "object" option is found, a new set of
38 options is considered.
43 openFileForReading(is, filename);
45 // Read input -> the structure name that will be used as input
51 FATAL("while reading RelativePositionList file. This file must start with 'input = '");
56 FATAL("while reading RelativePositionList file. This file must start with 'input = '");
63 // Create a temporary filename
64 char n[] = "tmp_clitkRelativePosition_XXXXXX";
65 mkstemp(n); // tmpnam(n);
66 std::string tmpfilename(n);
68 // Loop on the file text ; Every time we see a "object" token, we
72 std::ostringstream ss;
73 // first part of ss is the last 'object = ' found, stored in s
80 if (s.find("object") != std::string::npos) stop=true;
81 else ss << s << std::endl;
85 std::string text = ss.str();
86 if (text.size() > 10) { // if too small, it is not a list of option
88 openFileForWriting(os, tmpfilename);
90 os << "input = nothing" << std::endl;
91 os << "output = nothing" << std::endl;
94 // Create a struct to store options. I use two step to allow to
95 // fill the args values with de default and then check
96 // automatically the options.
97 ArgsInfoType args_info;
98 std::vector<char> writable(tmpfilename.size() + 1);
99 std::copy(tmpfilename.begin(), tmpfilename.end(), writable.begin());
100 char ** argv = new char*[1];
101 argv[0] = new char[1];
102 struct cmdline_parser_clitkRelativePosition_params params;
104 params.initialize = 1;
105 params.check_required = 0;
106 cmdline_parser_clitkRelativePosition_configfile(&writable[0], &args_info, 1, 1, 1);
107 mArgsInfoList.push_back(args_info);
109 // Delete the temporary file
110 std::remove(tmpfilename.c_str());
114 // Set the main input name
117 //--------------------------------------------------------------------
120 //--------------------------------------------------------------------
121 template <class TImageType>
123 clitk::RelativePositionList<TImageType>::
124 GenerateInputRequestedRegion()
127 itk::ImageToImageFilter<ImageType, ImageType>::GenerateInputRequestedRegion();
128 // Get input pointers and set requested region to common region
129 ImagePointer input1 = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(0));
130 input1->SetRequestedRegion(input1->GetLargestPossibleRegion());
132 //--------------------------------------------------------------------
136 //--------------------------------------------------------------------
137 template <class TImageType>
139 clitk::RelativePositionList<TImageType>::
140 GenerateOutputInformation() {
143 m_working_input = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(0));
145 // Loop on RelativePositionList of operations
146 std::string s = GetInputName();
147 for(uint i=0; i<mArgsInfoList.size(); i++) {
148 // clitk::PrintMemory(true, "Start");
149 std::string text = "["+s+"] limits ";
150 if (mArgsInfoList[i].orientation_given) text += std::string(mArgsInfoList[i].orientation_arg[0])+" ";
151 else text = text+"("+toString(mArgsInfoList[i].angle1_arg)+" "+
152 toString(mArgsInfoList[i].angle2_arg)+" "+
153 (mArgsInfoList[i].inverse_flag?"true":"false")+") ";
154 text = text+mArgsInfoList[i].object_arg+" "+toString(mArgsInfoList[i].threshold_arg);
155 if (mArgsInfoList[i].sliceBySlice_flag) {
156 text += " slice by slice";
159 text += " spacing=" + toString(mArgsInfoList[i].spacing_arg);
162 typename RelPosFilterType::Pointer relPosFilter;
164 // Is it slice by slice or 3D ?
165 if (mArgsInfoList[i].sliceBySlice_flag) {
166 typename SliceRelPosFilterType::Pointer f = SliceRelPosFilterType::New();
168 SetFilterOptions(relPosFilter, mArgsInfoList[i]);
170 // Set SbS specific options
171 f->SetUniqueConnectedComponentBySliceFlag(mArgsInfoList[i].uniqueCCL_flag);
172 f->SetObjectCCLSelectionFlag(mArgsInfoList[i].uniqueObjectCCL_flag);
173 f->IgnoreEmptySliceObjectFlagOn();
174 //f->SetObjectCCLSelectionDimension(0);
175 //f->SetObjectCCLSelectionDirection(-1);
176 //f->SetAutoCropFlag(false);
178 if (mArgsInfoList[i].verboseOptions_flag) f->PrintOptions();
181 relPosFilter = clitk::AddRelativePositionConstraintToLabelImageFilter<ImageType>::New();
182 SetFilterOptions(relPosFilter, mArgsInfoList[i]);
184 if (mArgsInfoList[i].verboseOptions_flag) relPosFilter->PrintOptions();
188 relPosFilter->SetInput(m_working_input);
191 relPosFilter->Update();
192 m_working_input = relPosFilter->GetOutput();
193 StopCurrentStep<ImageType>(m_working_input);
194 // clitk::PrintMemory(true, "End");
197 //--------------------------------------------------------------------
200 //--------------------------------------------------------------------
201 template <class TImageType>
203 clitk::RelativePositionList<TImageType>::
206 // Final Step -> set output
207 this->GraftOutput(m_working_input);
209 //--------------------------------------------------------------------
212 //--------------------------------------------------------------------
213 template <class TImageType>
215 clitk::RelativePositionList<TImageType>::
216 SetFilterOptions(typename RelPosFilterType::Pointer filter, ArgsInfoType & options) {
218 if (options.orientation_given > 1) {
219 clitkExceptionMacro("Error in the RelPos options. I need a single --orientation (for the moment)."
220 << " Current options are for obj = '" << options.object_arg
221 << "', threshold = " << options.threshold_arg << std::endl);
224 ImagePointer object = GetAFDB()->template GetImage<ImageType>(options.object_arg);
225 filter->SetInputObject(object);
226 filter->WriteStepFlagOff();
227 filter->SetVerboseImageSizeFlag(GetVerboseImageSizeFlag());
228 filter->SetFuzzyThreshold(options.threshold_arg);
229 filter->SetInverseOrientationFlag(options.inverse_flag); // MUST BE BEFORE AddOrientationTypeString
231 if (options.orientation_given == 1) {
232 for(uint i=0; i<options.orientation_given; i++)
233 filter->AddOrientationTypeString(options.orientation_arg[i]);
236 if (options.angle1_given && options.angle2_given) {
237 filter->AddAnglesInDeg(options.angle1_arg, options.angle2_arg);
240 clitkExceptionMacro("Error in the RelPos options. I need --orientation or (--angle1 and --angle2)."
241 << " Current options are for obj = '" << options.object_arg
242 << "', threshold = " << options.threshold_arg << std::endl);
245 filter->SetIntermediateSpacing(options.spacing_arg);
246 if (options.spacing_arg == -1) filter->IntermediateSpacingFlagOff();
247 else filter->IntermediateSpacingFlagOn();
248 filter->SetVerboseStepFlag(options.verboseStep_flag);
249 filter->SetAutoCropFlag(!options.noAutoCrop_flag);
251 //--------------------------------------------------------------------