]> Creatis software - clitk.git/blob - vv/vvToolCropImage.cxx
Merge branch 'master' 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     UpdateExtent();
106   }
107   vvToolWidgetBase::closeEvent(event);
108 }
109 //------------------------------------------------------------------------------
110
111
112 //------------------------------------------------------------------------------
113 bool vvToolCropImage::close()
114 {
115   return vvToolWidgetBase::close();
116 }
117 //------------------------------------------------------------------------------
118
119
120 //------------------------------------------------------------------------------
121 void vvToolCropImage::reject()
122 {
123   for(int i=0; i<mExtentSize; i++) mReducedExtent[i] = mInitialExtent[i];
124   UpdateExtent();
125   return vvToolWidgetBase::reject();
126 }
127 //------------------------------------------------------------------------------
128
129
130 //------------------------------------------------------------------------------
131 void vvToolCropImage::sliderValueChanged(int dim)
132 {
133   int dimMin = dim;
134   if(dim%2==0){//case we are minimum
135     mSliders[dim+1]->setMinimum(mSliders[dim]->value());
136   }else {
137     mSliders[--dimMin]->setMaximum(mSliders[dim]->value());
138   }
139   mReducedExtent[dim] = mSliders[dim]->value() + mInitialExtent[dimMin];
140   UpdateExtent();
141 }
142 //------------------------------------------------------------------------------
143
144
145 //------------------------------------------------------------------------------
146 void vvToolCropImage::UpdateExtent()
147 {
148   for(int i=0; i<mCurrentSlicerManager->GetNumberOfSlicers(); i++) {
149     mCurrentSlicerManager->GetSlicer(i)->SetReducedExtent(mReducedExtent);
150     mCurrentSlicerManager->GetSlicer(i)->ForceUpdateDisplayExtent();
151     mCurrentSlicerManager->GetSlicer(i)->Render();
152   }
153 }
154 //------------------------------------------------------------------------------
155
156
157 //------------------------------------------------------------------------------
158 void vvToolCropImage::InputIsSelected(vvSlicerManager * slicer)
159 {
160   // Change interface according to number of dimension
161   mExtentSize = 2*slicer->GetDimension();
162    if (slicer->GetDimension()<4) {
163      mTLabel1->setHidden(true);
164      mTLabel2->setHidden(true);
165      tminSlider->setHidden(true);
166      tmaxSlider->setHidden(true);
167      spin_tmin->setHidden(true);
168      spin_tmax->setHidden(true);
169      mLabelTimeCropping->setHidden(true);
170    }
171   if (slicer->GetDimension()<3) {
172     mZLabel1->setHidden(true);
173     mZLabel2->setHidden(true);
174     zminSlider->setHidden(true);
175     zmaxSlider->setHidden(true);
176     spin_zmin->setHidden(true);
177     spin_zmax->setHidden(true);
178   }
179 #if VTK_MAJOR_VERSION <= 5
180   int *a = mCurrentImage->GetFirstVTKImageData()->GetWholeExtent();
181 #else
182   int *a = mCurrentImage->GetFirstVTKImageData()->GetInformation()->Get(vtkDataObject::DATA_EXTENT());
183 #endif
184   for(int i=0; i<6; i++){
185     mInitialExtent[i] = a[i];
186     mReducedExtent[i] = a[i];
187   }
188   for(int i=0; i<mCurrentSlicerManager->GetNumberOfSlicers(); i++) {
189     mCurrentSlicerManager->GetSlicer(i)->EnableReducedExtent(true);
190     mCurrentSlicerManager->GetSlicer(i)->SetReducedExtent(mInitialExtent);
191   }
192
193 //   Set initial sliders values
194   int w_ext[6], imsize[3];
195   mCurrentSlicerManager->GetSlicer(0)->GetRegisterExtent(w_ext);
196   for(int dim=0; dim<slicer->GetDimension() && dim<3; ++dim){
197     imsize[dim] = w_ext[2*dim+1] - w_ext[2*dim] +1;
198     mSliders[dim*2]->setMaximum(imsize[dim]-1);
199     mSliders[dim*2+1]->setMaximum(imsize[dim]-1);
200     mSliders[dim*2+1]->setValue(imsize[dim]-1);
201   }
202   spin_xmin->setMaximum(imsize[0]-1);
203   spin_xmax->setMaximum(imsize[0]-1);
204   spin_xmax->setValue(imsize[0]-1);
205
206   spin_ymin->setMaximum(imsize[1]-1);
207   spin_ymax->setMaximum(imsize[1]-1);
208   spin_ymax->setValue(imsize[1]-1);
209
210   if (slicer->GetDimension() >2) {
211     spin_zmin->setMaximum(imsize[2]-1);
212     spin_zmax->setMaximum(imsize[2]-1);
213     spin_zmax->setValue(imsize[2]-1);
214   }
215
216   if (slicer->GetDimension() >3) {
217     spin_tmin->setMaximum(imsize[3]-1);
218     spin_tmax->setMaximum(imsize[3]-1);
219     spin_tmax->setValue(imsize[3]-1);
220   }
221
222   QSignalMapper* signalMapper = new QSignalMapper(this);
223   connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(sliderValueChanged(int)));
224   for(unsigned int i=0; i<mSliders.size(); ++i){
225     signalMapper->setMapping(mSliders[i], i);
226     connect(mSliders[i], SIGNAL(valueChanged(int)), signalMapper, SLOT(map()));
227   }
228   UpdateExtent();
229 }
230 //------------------------------------------------------------------------------
231
232
233 //------------------------------------------------------------------------------
234 void vvToolCropImage::autoCropValueChanged(double v)
235 {
236   //TODO
237 }
238 //------------------------------------------------------------------------------
239
240
241 //------------------------------------------------------------------------------
242 void vvToolCropImage::apply()
243 {
244   if (!mCurrentSlicerManager) close();
245   QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
246
247   // Typedef 
248   typedef args_info_clitkCropImage ArgsInfoType;
249   typedef clitk::CropImageGenericFilter CropFilterType;
250   
251   // Get options
252   ArgsInfoType mArgsInfo;
253   cmdline_parser_clitkCropImage_init(&mArgsInfo); // Initialisation to default
254   int n = mCurrentSlicerManager->GetDimension()*2;  // 2D and 3D only
255   mArgsInfo.boundingBox_given = n;
256   mArgsInfo.boundingBox_arg = new int[n];
257   
258   for(int dim=0; dim<mCurrentSlicerManager->GetDimension() && dim<3; ++dim){
259     mArgsInfo.boundingBox_arg[dim*2] = mSliders[dim*2]->value();
260     mArgsInfo.boundingBox_arg[dim*2+1] = mSliders[dim*2+1]->value();
261   }
262   if (n>6) { // 4D
263     mArgsInfo.boundingBox_arg[6] = 0;
264     mArgsInfo.boundingBox_arg[7] = mCurrentImage->GetSize()[3]-1;
265   }
266   // We MUST reset initial extend to input image before using the
267   // filter to retrieve the correct image size
268   for(int i=0; i<mExtentSize; i++) {
269     mReducedExtent[i] = mInitialExtent[i];
270   }
271   
272   UpdateExtent();
273   // Main filter
274   CropFilterType::Pointer filter = CropFilterType::New();
275   filter->SetInputVVImage(mCurrentImage);
276   filter->SetArgsInfo(mArgsInfo);
277
278   // Go ! (not threaded) 
279   try{
280     filter->Update();
281   }
282   catch(clitk::ExceptionObject & e) {
283     DD(e.what());
284     QApplication::restoreOverrideCursor();
285     delete [] mArgsInfo.boundingBox_arg;
286     close();
287   }
288   std::ostringstream croppedImageName;
289   croppedImageName << "Cropped_" << mCurrentSlicerManager->GetSlicer(0)->GetFileName() << ".mhd";
290   // Retrieve result and display it
291   vvImage::Pointer output = filter->GetOutputVVImage();
292   
293   AddImage(output,croppedImageName.str());
294   
295   // End
296   QApplication::restoreOverrideCursor();
297   delete [] mArgsInfo.boundingBox_arg;
298   close();
299 }
300 //------------------------------------------------------------------------------
301