]> Creatis software - clitk.git/blob - vv/vvToolCropImage.cxx
Merge branch 'master' of git.creatis.insa-lyon.fr:clitk into VTK6_Qt5
[clitk.git] / vv / vvToolCropImage.cxx
1 /*=========================================================================
2   Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
3
4   Authors belong to:
5   - University of LYON              http://www.universite-lyon.fr/
6   - Léon Bérard cancer center       http://www.centreleonberard.fr
7   - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
8
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.
12
13   It is distributed under dual licence
14
15   - BSD        See included LICENSE.txt file
16   - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
17 ===========================================================================**/
18
19 // vv
20 #include "vvToolCropImage.h"
21 #include "vvSlicer.h"
22
23 // clitk
24 #include "clitkCropImage_ggo.h"
25 #include "clitkCropImageGenericFilter.h"
26 #include "clitkExceptionObject.h"
27
28 // qt
29 #include <QComboBox>
30 #include <QCursor>
31 #include <QApplication>
32 #include <QMessageBox>
33 #include <QSignalMapper>
34
35 // vtk
36 #include <vtkVersion.h>
37 #include <vtkStreamingDemandDrivenPipeline.h>
38 #include <vtkInformation.h>
39 #include <vtkImageClip.h>
40 #include <vtkImageTranslateExtent.h>
41 #include <vtkImageData.h>
42 #include <vtkSmartPointer.h>
43
44 //------------------------------------------------------------------------------
45 // Create the tool and automagically (I like this word) insert it in
46 // the main window menu.
47 ADD_TOOL(vvToolCropImage);
48 //------------------------------------------------------------------------------
49
50 //same order of int* returned by VtkImageData::WholeExtent
51 enum sliderId {xmin, xmax, ymin, ymax, zmin, zmax, tmin, tmax};
52 //------------------------------------------------------------------------------
53 vvToolCropImage::vvToolCropImage(vvMainWindowBase * parent, Qt::WindowFlags f):
54   vvToolWidgetBase(parent, f),
55   vvToolBase<vvToolCropImage>(parent),
56   Ui::vvToolCropImage(),mSliders(8)
57 {
58
59   // GUI Initialization
60   Ui_vvToolCropImage::setupUi(mToolWidget);
61   mTLabel1->setHidden(true);
62   mTLabel2->setHidden(true);
63   tminSlider->setHidden(true);
64   tmaxSlider->setHidden(true);
65   spin_tmin->setHidden(true);
66   spin_tmax->setHidden(true);
67   mLabelTimeCropping->setHidden(true);
68
69   // Set how many inputs are needed for this tool
70   AddInputSelector("Select one image");
71   
72   mSliders[xmin]=xminSlider;
73   mSliders[xmax]=xmaxSlider;
74   mSliders[ymin]=yminSlider;
75   mSliders[ymax]=ymaxSlider;
76   mSliders[zmin]=zminSlider;
77   mSliders[zmax]=zmaxSlider;
78   mSliders[tmin]=tminSlider;
79   mSliders[tmax]=tmaxSlider;
80   
81   // Record initial extend
82   mReducedExtent = new int[6];
83   mInitialExtent = new int[6];
84 }
85 //------------------------------------------------------------------------------
86
87
88 //------------------------------------------------------------------------------
89 vvToolCropImage::~vvToolCropImage()
90 {
91   delete [] mReducedExtent;
92   delete [] mInitialExtent;
93 }
94 //------------------------------------------------------------------------------
95
96
97 //------------------------------------------------------------------------------
98 void vvToolCropImage::closeEvent(QCloseEvent *event)
99 {
100   if(mCurrentSlicerManager){
101 //     Reset extends
102     for(int i=0; i<6; i++){
103       mReducedExtent[i] = mInitialExtent[i];
104     }
105     for(int i=0; i<mCurrentSlicerManager->GetNumberOfSlicers(); i++)
106       mCurrentSlicerManager->GetSlicer(i)->EnableReducedExtent(false);
107     UpdateExtent();
108   }
109   vvToolWidgetBase::closeEvent(event);
110 }
111 //------------------------------------------------------------------------------
112
113
114 //------------------------------------------------------------------------------
115 bool vvToolCropImage::close()
116 {
117   return vvToolWidgetBase::close();
118 }
119 //------------------------------------------------------------------------------
120
121
122 //------------------------------------------------------------------------------
123 void vvToolCropImage::reject()
124 {
125   for(int i=0; i<mExtentSize; i++)
126     mReducedExtent[i] = mInitialExtent[i];
127   for(int i=0; i<mCurrentSlicerManager->GetNumberOfSlicers(); i++)
128     mCurrentSlicerManager->GetSlicer(i)->EnableReducedExtent(false);
129   UpdateExtent();
130   return vvToolWidgetBase::reject();
131 }
132 //------------------------------------------------------------------------------
133
134
135 //------------------------------------------------------------------------------
136 void vvToolCropImage::sliderValueChanged(int dim)
137 {
138   int dimMin = dim;
139   if(dim%2==0){//case we are minimum
140     mSliders[dim+1]->setMinimum(mSliders[dim]->value());
141   }else {
142     mSliders[--dimMin]->setMaximum(mSliders[dim]->value());
143   }
144   mReducedExtent[dim] = mSliders[dim]->value() + mInitialExtent[dimMin];
145   UpdateExtent();
146 }
147 //------------------------------------------------------------------------------
148
149
150 //------------------------------------------------------------------------------
151 void vvToolCropImage::UpdateExtent()
152 {
153   for(int i=0; i<mCurrentSlicerManager->GetNumberOfSlicers(); i++) {
154     mCurrentSlicerManager->GetSlicer(i)->SetReducedExtent(mReducedExtent);
155     mCurrentSlicerManager->GetSlicer(i)->ForceUpdateDisplayExtent();
156     mCurrentSlicerManager->GetSlicer(i)->Render();
157   }
158 }
159 //------------------------------------------------------------------------------
160
161
162 //------------------------------------------------------------------------------
163 void vvToolCropImage::InputIsSelected(vvSlicerManager * slicer)
164 {
165   // Change interface according to number of dimension
166   mExtentSize = 2*slicer->GetDimension();
167    if (slicer->GetDimension()<4) {
168      mTLabel1->setHidden(true);
169      mTLabel2->setHidden(true);
170      tminSlider->setHidden(true);
171      tmaxSlider->setHidden(true);
172      spin_tmin->setHidden(true);
173      spin_tmax->setHidden(true);
174      mLabelTimeCropping->setHidden(true);
175    }
176   if (slicer->GetDimension()<3) {
177     mZLabel1->setHidden(true);
178     mZLabel2->setHidden(true);
179     zminSlider->setHidden(true);
180     zmaxSlider->setHidden(true);
181     spin_zmin->setHidden(true);
182     spin_zmax->setHidden(true);
183   }
184 #if VTK_MAJOR_VERSION <= 5
185   int *a = mCurrentImage->GetFirstVTKImageData()->GetWholeExtent();
186 #else
187   int *a = mCurrentImage->GetFirstVTKImageData()->GetInformation()->Get(vtkDataObject::DATA_EXTENT());
188 #endif
189   for(int i=0; i<6; i++){
190     mInitialExtent[i] = a[i];
191     mReducedExtent[i] = a[i];
192   }
193   for(int i=0; i<mCurrentSlicerManager->GetNumberOfSlicers(); i++) {
194     mCurrentSlicerManager->GetSlicer(i)->EnableReducedExtent(true);
195     mCurrentSlicerManager->GetSlicer(i)->SetReducedExtent(mInitialExtent);
196   }
197
198 //   Set initial sliders values
199   int w_ext[6], imsize[3];
200   mCurrentSlicerManager->GetSlicer(0)->GetRegisterExtent(w_ext);
201   for(int dim=0; dim<slicer->GetDimension() && dim<3; ++dim){
202     imsize[dim] = w_ext[2*dim+1] - w_ext[2*dim] +1;
203     mSliders[dim*2]->setMaximum(imsize[dim]-1);
204     mSliders[dim*2+1]->setMaximum(imsize[dim]-1);
205     mSliders[dim*2+1]->setValue(imsize[dim]-1);
206   }
207   spin_xmin->setMaximum(imsize[0]-1);
208   spin_xmax->setMaximum(imsize[0]-1);
209   spin_xmax->setValue(imsize[0]-1);
210
211   spin_ymin->setMaximum(imsize[1]-1);
212   spin_ymax->setMaximum(imsize[1]-1);
213   spin_ymax->setValue(imsize[1]-1);
214
215   if (slicer->GetDimension() >2) {
216     spin_zmin->setMaximum(imsize[2]-1);
217     spin_zmax->setMaximum(imsize[2]-1);
218     spin_zmax->setValue(imsize[2]-1);
219   }
220
221   if (slicer->GetDimension() >3) {
222     spin_tmin->setMaximum(imsize[3]-1);
223     spin_tmax->setMaximum(imsize[3]-1);
224     spin_tmax->setValue(imsize[3]-1);
225   }
226
227   QSignalMapper* signalMapper = new QSignalMapper(this);
228   connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(sliderValueChanged(int)));
229   for(unsigned int i=0; i<mSliders.size(); ++i){
230     signalMapper->setMapping(mSliders[i], i);
231     connect(mSliders[i], SIGNAL(valueChanged(int)), signalMapper, SLOT(map()));
232   }
233   UpdateExtent();
234 }
235 //------------------------------------------------------------------------------
236
237
238 //------------------------------------------------------------------------------
239 void vvToolCropImage::autoCropValueChanged(double v)
240 {
241   //TODO
242 }
243 //------------------------------------------------------------------------------
244
245
246 //------------------------------------------------------------------------------
247 void vvToolCropImage::apply()
248 {
249   if (!mCurrentSlicerManager) close();
250   QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
251
252   // Typedef 
253   typedef args_info_clitkCropImage ArgsInfoType;
254   typedef clitk::CropImageGenericFilter CropFilterType;
255   
256   // Get options
257   ArgsInfoType mArgsInfo;
258   cmdline_parser_clitkCropImage_init(&mArgsInfo); // Initialisation to default
259   int n = mCurrentSlicerManager->GetDimension()*2;  // 2D and 3D only
260   mArgsInfo.boundingBox_given = n;
261   mArgsInfo.boundingBox_arg = new int[n];
262   
263   for(int dim=0; dim<mCurrentSlicerManager->GetDimension() && dim<3; ++dim){
264     mArgsInfo.boundingBox_arg[dim*2] = mSliders[dim*2]->value();
265     mArgsInfo.boundingBox_arg[dim*2+1] = mSliders[dim*2+1]->value();
266   }
267   if (n>6) { // 4D
268     mArgsInfo.boundingBox_arg[6] = 0;
269     mArgsInfo.boundingBox_arg[7] = mCurrentImage->GetSize()[3]-1;
270   }
271   // We MUST reset initial extend to input image before using the
272   // filter to retrieve the correct image size
273   for(int i=0; i<6; i++) {
274     mReducedExtent[i] = mInitialExtent[i];
275   }
276   
277   UpdateExtent();
278   // Main filter
279   CropFilterType::Pointer filter = CropFilterType::New();
280   filter->SetInputVVImage(mCurrentImage);
281   filter->SetArgsInfo(mArgsInfo);
282
283   // Go ! (not threaded) 
284   try{
285     filter->Update();
286   }
287   catch(clitk::ExceptionObject & e) {
288     DD(e.what());
289     QApplication::restoreOverrideCursor();
290     delete [] mArgsInfo.boundingBox_arg;
291     close();
292   }
293   std::ostringstream croppedImageName;
294   croppedImageName << "Cropped_" << mCurrentSlicerManager->GetSlicer(0)->GetFileName() << ".mhd";
295   // Retrieve result and display it
296   vvImage::Pointer output = filter->GetOutputVVImage();
297   
298   AddImage(output,croppedImageName.str());
299   
300   // End
301   QApplication::restoreOverrideCursor();
302   delete [] mArgsInfo.boundingBox_arg;
303   close();
304 }
305 //------------------------------------------------------------------------------
306