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 ======================================================================-====*/
24 #include <QApplication>
26 #include <QMutexLocker>
28 #include "vtkVOXImageWriter.h"
29 #include <vtkImageData.h>
31 #include "clitkCommon.h"
32 #include "vvSlicerManager.h"
33 #include "vvDeformableRegistration.h"
36 #include "vvImageReader.h"
38 vvDeformableRegistration::vvDeformableRegistration(vvImage::Pointer image,unsigned int ref,\
39 unsigned int iter, unsigned int nthread,double a, double s,std::string output_f,unsigned int stop) :
48 output_filename(output_f),
53 void vvDeformableRegistration::abort()
56 std::system("killall deformableregistration");
57 std::system("killall clitkVFMerge");
60 unsigned int vvDeformableRegistration::getProgress()
62 QMutexLocker locker(&progress_mutex);
63 unsigned int retval=progress;
67 void vvDeformableRegistration::cleanup(int frame_number) //remove temporary files
69 std::string temp_dir=mTempPath.toStdString();
70 for (int i=0;i<frame_number;i++)
72 std::stringstream filename;
73 filename << temp_dir << "/deformation_" << i << ".vf";
74 std::system((std::string("rm ") + filename.str()).c_str());
76 for (int i=0;i<frame_number;i++)
78 std::stringstream filename;
79 filename << temp_dir << "/temp_" << i << ".vox";
80 std::system(("rm " + filename.str()).c_str());
82 std::stringstream filename;
84 std::system(("rm -r " + filename.str()).c_str());
87 void vvDeformableRegistration::partial_run(int low_index,int high_index,int refimage,std::string ref_file)
89 std::string temp_dir=mTempPath.toStdString();
93 for (int i=low_index;i<high_index;i++)
99 std::stringstream filename;
100 std::stringstream registration_command;
101 filename << temp_dir << "/temp_" << i << ".vox";
102 std::stringstream output_vf;
103 output_vf << temp_dir << "/deformation_" << i << ".vf";
104 registration_command << "deformableregistration -r " << ref_file
105 << " -d " << filename.str() << " -o " << output_vf.str()
106 << " --alpha=" << alpha
107 << " --sigma=" << sigma
108 << " --stop=" << stop
109 << " --iter=" << nb_iter;
110 if (i>low_index && i-1 != refimage) //if possible, use the previous computations to speed up the process
112 std::stringstream old_vf;
113 old_vf << temp_dir << "/deformation_" << i-1 << ".vf";
114 registration_command << " --vf=" << old_vf.str();
116 DD(registration_command.str());
117 std::system(registration_command.str().c_str());
118 progress_mutex.lock();
120 progress_mutex.unlock();
124 void vvDeformableRegistration::run()
126 clock_t start,finish;
128 vtkVOXImageWriter * vox = vtkVOXImageWriter::New();
129 std::stringstream command;
130 std::string ref_file;
131 mTempPath=QDir::tempPath()+QString("/vv-")+QString::number(qApp->applicationPid());
133 DD(temp_qt_dir.mkpath(mTempPath));
134 std::string temp_dir=mTempPath.toStdString();
136 std::vector<vtkImageData*> images=mImage->GetVTKImages();
137 for (unsigned int i=0;i<images.size();i++)
139 std::stringstream filename;
140 filename << temp_dir << "/temp_" << i << ".vox";
141 vox->SetInput(images[i]);
142 vox->SetFileName(filename.str().c_str());
144 ref_file=filename.str();
149 int reg_per_thread=static_cast<int>(images.size()-1)/n_thread;
150 int remainder=static_cast<int>(images.size()-1) - reg_per_thread*n_thread;
151 #pragma omp parallel for num_threads(n_thread) schedule(static)
152 for (int i=0;i<static_cast<int>(n_thread);i++)
155 int remainder_shift=((i<remainder)?i:remainder);
156 unsigned int start_image=i*reg_per_thread+remainder_shift;
157 unsigned int end_image=((i+1)*reg_per_thread+remainder_shift+((i<remainder)?1:0));
158 if (end_image<=refimage)
159 partial_run(start_image,end_image,refimage,ref_file);
160 else if (start_image<=refimage)
161 partial_run(start_image,end_image+1,refimage,ref_file);
163 partial_run(start_image+1,end_image+1,refimage,ref_file);
167 cleanup(images.size());
171 int computed_vf=(refimage==0)?1:0; //index of an image that isn't the reference image
172 command << "clitkZeroVF -i " << temp_dir << "/deformation_" << computed_vf << ".vf -o " << temp_dir <<
173 "/deformation_" << refimage << ".vf";
174 DD(command.str()); //create zero VF for the ref image
175 std::system(command.str().c_str());
177 command << "clitkVFMerge ";
178 for (unsigned int i=0;i<images.size();i++) command << temp_dir << "/deformation_" << i << ".vf ";
179 command << " --xorigin " << images[0]->GetOrigin()[0];
180 command << " --yorigin " << images[0]->GetOrigin()[1];
181 command << " --zorigin " << images[0]->GetOrigin()[2];
182 command << " -o " << output_filename << std::endl;
184 std::system(command.str().c_str());
185 cleanup(images.size());
188 std::system(("rm " + output_filename).c_str());
191 vvImageReader reader;
192 reader.SetInputFilename(output_filename);
193 reader.Update(VECTORFIELD);
195 DD((finish - start)/static_cast<double>(CLOCKS_PER_SEC));
196 mOutput=reader.GetOutput();