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);
92 // Create a struct to store options. I use two step to allow to
93 // fill the args values with de default and then check
94 // automatically the options.
95 ArgsInfoType args_info;
96 std::vector<char> writable(tmpfilename.size() + 1);
97 std::copy(tmpfilename.begin(), tmpfilename.end(), writable.begin());
98 char ** argv = new char*[1];
99 argv[0] = new char[1];
100 cmdline_parser_clitkRelativePosition2(1, argv, &args_info, 1, 1, 0);
101 args_info.input_given = 1;
102 args_info.input_arg = new char[1];
103 args_info.output_given = 1;
104 args_info.output_arg = new char[1];
105 cmdline_parser_clitkRelativePosition_configfile(&writable[0], &args_info, 0, 0, 1);
108 mArgsInfoList.push_back(args_info);
110 // Delete the temporary file
111 std::remove(tmpfilename.c_str());
115 // Set the main input name
118 //--------------------------------------------------------------------
121 //--------------------------------------------------------------------
122 template <class TImageType>
124 clitk::RelativePositionList<TImageType>::
125 GenerateInputRequestedRegion()
128 itk::ImageToImageFilter<ImageType, ImageType>::GenerateInputRequestedRegion();
129 // Get input pointers and set requested region to common region
130 ImagePointer input1 = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(0));
131 input1->SetRequestedRegion(input1->GetLargestPossibleRegion());
133 //--------------------------------------------------------------------
137 //--------------------------------------------------------------------
138 template <class TImageType>
140 clitk::RelativePositionList<TImageType>::
141 GenerateOutputInformation() {
144 m_working_input = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(0));
146 // Loop on RelativePositionList of operations
147 std::string s = GetInputName();
148 for(uint i=0; i<mArgsInfoList.size(); i++) {
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?"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";
161 typename RelPosFilterType::Pointer relPosFilter;
163 // Is it slice by slice or 3D ?
164 if (mArgsInfoList[i].sliceBySlice_flag) {
165 typename SliceRelPosFilterType::Pointer f = SliceRelPosFilterType::New();
167 SetFilterOptions(relPosFilter, mArgsInfoList[i]);
169 // Set SbS specific options
170 f->SetUniqueConnectedComponentBySliceFlag(mArgsInfoList[i].uniqueCCL_flag);
171 f->SetObjectCCLSelectionFlag(mArgsInfoList[i].uniqueObjectCCL_flag);
172 f->IgnoreEmptySliceObjectFlagOn();
173 //f->SetObjectCCLSelectionDimension(0);
174 //f->SetObjectCCLSelectionDirection(-1);
175 //f->SetAutoCropFlag(false);
177 if (mArgsInfoList[i].verboseOptions_flag) f->PrintOptions();
180 relPosFilter = clitk::AddRelativePositionConstraintToLabelImageFilter<ImageType>::New();
181 SetFilterOptions(relPosFilter, mArgsInfoList[i]);
183 if (mArgsInfoList[i].verboseOptions_flag) relPosFilter->PrintOptions();
187 relPosFilter->SetInput(m_working_input);
190 relPosFilter->Update();
191 m_working_input = relPosFilter->GetOutput();
192 StopCurrentStep<ImageType>(m_working_input);
195 //--------------------------------------------------------------------
198 //--------------------------------------------------------------------
199 template <class TImageType>
201 clitk::RelativePositionList<TImageType>::
204 // Final Step -> set output
205 this->GraftOutput(m_working_input);
207 //--------------------------------------------------------------------
210 //--------------------------------------------------------------------
211 template <class TImageType>
213 clitk::RelativePositionList<TImageType>::
214 SetFilterOptions(typename RelPosFilterType::Pointer filter, ArgsInfoType & options) {
216 if (options.orientation_given > 1) {
217 clitkExceptionMacro("Error in the RelPos options. I need a single --orientation (for the moment)."
218 << " Current options are for obj = '" << options.object_arg
219 << "', threshold = " << options.threshold_arg << std::endl);
222 ImagePointer object = GetAFDB()->template GetImage<ImageType>(options.object_arg);
223 filter->SetInputObject(object);
224 filter->WriteStepFlagOff();
225 filter->SetVerboseImageSizeFlag(GetVerboseImageSizeFlag());
226 filter->SetFuzzyThreshold(options.threshold_arg);
227 filter->SetInverseOrientationFlag(options.inverse_flag); // MUST BE BEFORE AddOrientationTypeString
229 if (options.orientation_given == 1) {
230 for(uint i=0; i<options.orientation_given; i++)
231 filter->AddOrientationTypeString(options.orientation_arg[i]);
234 if (options.angle1_given && options.angle2_given) {
235 filter->AddAnglesInDeg(options.angle1_arg, options.angle2_arg);
238 clitkExceptionMacro("Error in the RelPos options. I need --orientation or (--angle1 and --angle2)."
239 << " Current options are for obj = '" << options.object_arg
240 << "', threshold = " << options.threshold_arg << std::endl);
243 filter->SetIntermediateSpacing(options.spacing_arg);
244 if (options.spacing_arg == -1) filter->IntermediateSpacingFlagOff();
245 else filter->IntermediateSpacingFlagOn();
246 filter->SetVerboseStepFlag(options.verboseStep_flag);
247 filter->SetAutoCropFlag(!options.noAutoCrop_flag);
249 //--------------------------------------------------------------------