]> Creatis software - clitk.git/blob - vv/vvSegmentationDialog.cxx
removed headers
[clitk.git] / vv / vvSegmentationDialog.cxx
1 #ifndef _vvSegmentationDialog_CXX
2 #define _vvSegmentationDialog_CXX
3 #include <QtGui>
4 #include <Qt>
5
6 #include "vvSegmentationDialog.h"
7 #include "vvProgressDialog.h"
8 #include "vvImageWriter.h"
9 #include "vvLandmarks.h"
10 #include "vvInteractorStyleNavigator.h"
11 #include "vvSlicer.h"
12
13 #include "vtkMarchingCubes.h"
14 #include "vtkMarchingSquares.h"
15 #include "vtkImageClip.h"
16 #include "vtkCamera.h"
17 #include "vtkRenderer.h"
18 #include "vtkProperty.h"
19 #include "vtkLookupTable.h"
20 #include "vtkClipPolyData.h"
21 #include "vtkImageToPolyDataFilter.h"
22 #include "vtkLookupTable.h"
23 #include "vtkDoubleArray.h"
24 #include "vtkPointData.h"
25 #include "vtkCellData.h"
26 #include "vtkImageMapToWindowLevelColors.h"
27 #include "vtkImageContinuousErode3D.h"
28 #include "vtkImageContinuousDilate3D.h"
29 #include "vtkImageLogic.h"
30 #include "vtkInteractorStyleTrackballCamera.h"
31 #include "vtkImageSeedConnectivity.h"
32 #include "vtkConnectivityFilter.h"
33 #include "vtkPolyData.h"
34 #include <vtkPolyDataMapper.h>
35 #include <vtkImageData.h>
36 #include "vtkInformation.h"
37 #include "vtkInformationVector.h"
38 #include "vtkStreamingDemandDrivenPipeline.h"
39 #include <vtkPolyDataWriter.h>
40
41 #include <QMessageBox>
42
43 //====================================================================
44 vvSegmentationDialog::vvSegmentationDialog(QWidget * parent, Qt::WindowFlags f)
45         :QDialog(parent,f), Ui::vvSegmentationDialog() {
46
47     // initialization
48     setupUi(this);
49     mManager = new vvSlicerManager(1);
50
51     mClipper = vtkImageClip::New();
52     mSquares1 = vtkMarchingSquares::New();
53     mSquaresMapper1 = vtkPolyDataMapper::New();
54     mSquaresActor1 = vtkActor::New();
55
56     mSquares2 = vtkMarchingSquares::New();
57     mSquaresMapper2 = vtkPolyDataMapper::New();
58     mSquaresActor2 = vtkActor::New();
59
60     //m3DMapper = vtkPolyDataMapper::New();
61     //m3DActor = vtkActor::New();
62     m3DExtractor = vtkMarchingCubes::New();
63     m3DMappers.clear();
64     m3DActors.clear();
65
66     mBinaireImages.clear();
67     mKernelValue = 2;
68
69     connect(clipping1Slider,SIGNAL(valueChanged(int)),this,SLOT(clippingvaluechanged(int)));
70     connect(clipping2Slider,SIGNAL(valueChanged(int)),this,SLOT(clippingvaluechanged(int)));
71     connect(binaryButton,SIGNAL(clicked()),this,SLOT(BinariseSurface()));
72     connect(saveButton,SIGNAL(clicked()),this,SLOT(Save()));
73     connect(erodeButton,SIGNAL(clicked()),this,SLOT(Erode()));
74     connect(dilateButton,SIGNAL(clicked()),this,SLOT(Dilate()));
75     connect(dimButton,SIGNAL(clicked()),this,SLOT(ChangeDimRendering()));
76     connect(kernelSpinBox,SIGNAL(valueChanged(int)),this,SLOT(KernelValueChanged(int)));
77
78     binaryButton->setEnabled(0);
79     erodeButton->setEnabled(0);
80     dilateButton->setEnabled(0);
81     infoLabel->setText("Select Up and Down threshold before clicking binarise !");
82 }
83
84 vvSegmentationDialog::~vvSegmentationDialog()
85 {
86     mClipper->Delete();
87
88     mSquaresActor1->Delete();
89     mSquaresMapper1->Delete();
90     mSquares1->Delete();
91
92     mSquaresActor2->Delete();
93     mSquaresMapper2->Delete();
94     mSquares2->Delete();
95
96     //m3DMapper->Delete();
97     //m3DActor->Delete();
98     m3DExtractor->Delete();
99
100     for (unsigned int i = 0; i < mBinaireImages.size(); i++)
101         mBinaireImages[i]->Delete();
102
103     for (unsigned int i = 0; i < m3DActors.size(); i++)
104         m3DActors[i]->Delete();
105
106     for (unsigned int i = 0; i < m3DMappers.size(); i++)
107         m3DMappers[i]->Delete();
108
109     delete mManager;
110 }
111
112 //----------------------------------------------------------------------------
113 // This templated function executes the filter for any type of data.
114 // Handles the one input operations
115 template <class T>
116 void vvImageBinarize(vtkImageData *in1Data, T *in1Ptr,
117                      int outExt[6],int clampMin, int clampMax)
118 {
119     int idxR, idxY, idxZ;
120     int maxY, maxZ;
121     vtkIdType inIncX, inIncY, inIncZ;
122     int rowLength;
123
124     // find the region to loop over
125     rowLength =
126         (outExt[1] - outExt[0]+1)*in1Data->GetNumberOfScalarComponents();
127     // What a pain. Maybe I should just make another filter.
128
129     maxY = outExt[3] - outExt[2];
130     maxZ = outExt[5] - outExt[4];
131
132     // Get increments to march through data
133     in1Data->GetContinuousIncrements(outExt, inIncX, inIncY, inIncZ);
134
135     for (idxZ = 0; idxZ <= maxZ; idxZ++)
136     {
137         for (idxY = 0; idxY <= maxY; idxY++)
138         {
139             for (idxR = 0; idxR < rowLength; idxR++)
140             {
141                 if (static_cast<double>(*in1Ptr) > clampMin && static_cast<double>(*in1Ptr) <= clampMax)
142                     *in1Ptr = static_cast<T>(1);
143                 else
144                     *in1Ptr = static_cast<T>(0);
145                 in1Ptr++;
146             }
147             in1Ptr += inIncY;
148         }
149         in1Ptr += inIncZ;
150     }
151 }
152
153 void vvSegmentationDialog::SetImage(vvImage::Pointer image)
154 {
155
156     QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
157     mManager->SetImage(image);
158     mManager->SetSlicerWindow(0,viewWidget->GetRenderWindow());
159     vvInteractorStyleNavigator* style = vvInteractorStyleNavigator::New();
160     mManager->SetInteractorStyleNavigator(0,style);
161     style->Delete();
162
163     double range[2];
164     mManager->GetImage()->GetScalarRange(range);
165     mManager->GetSlicer(0)->SetColorWindow(range[1]-range[0]);
166     mManager->GetSlicer(0)->SetColorLevel((range[1]+range[0])/2);
167
168     clipping1Slider->setMinimum(range[0]);
169     clipping1Slider->setMaximum(range[1]);
170     clipping2Slider->setMinimum(range[0]);
171     clipping2Slider->setMaximum(range[1]);
172     clipping1Slider->setValue(range[0]);
173     clipping2Slider->setValue(range[1]);
174
175     mClipper->SetInput(mManager->GetSlicer(0)->GetInput());
176     mSquares1->SetValue(0,clipping1Slider->value());
177     mSquares2->SetValue(0,clipping2Slider->value());
178     mSquares1->SetInput(mClipper->GetOutput());
179     mSquares2->SetInput(mClipper->GetOutput());
180
181     mSquaresMapper1->SetInput(mSquares1->GetOutput());
182     mSquaresMapper2->SetInput(mSquares2->GetOutput());
183     mSquaresMapper1->ScalarVisibilityOff();
184     mSquaresMapper2->ScalarVisibilityOff();
185
186     mSquaresActor1->SetMapper(mSquaresMapper1);
187     mSquaresActor2->SetMapper(mSquaresMapper2);
188     mSquaresActor1->GetProperty()->SetColor(1.0,0,0);
189     mSquaresActor2->GetProperty()->SetColor(0,0,1.0);
190     mSquaresActor1->SetPickable(0);
191     mSquaresActor2->SetPickable(0);
192
193     mManager->GetSlicer(0)->GetRenderer()->AddActor(mSquaresActor1);
194     mManager->GetSlicer(0)->GetRenderer()->AddActor(mSquaresActor2);
195
196     mSquares1->Update();
197     mSquares2->Update();
198
199     UpdateSlice(0,mManager->GetSlicer(0)->GetSlice());
200
201     connect(mManager,SIGNAL(UpdateTSlice(int,int)),this,SLOT(UpdateSlice(int, int)));
202     connect(mManager,SIGNAL(UpdateSlice(int,int)),this,SLOT(UpdateSlice(int, int)));
203     connect(mManager,SIGNAL(UpdateSliceRange(int,int,int,int,int)),this,SLOT(UpdateSlice(int, int)));
204     connect(mManager,SIGNAL(LandmarkAdded()),this,SLOT(InsertSeed()));
205     QApplication::restoreOverrideCursor();
206 }
207
208 void vvSegmentationDialog::UpdateSlice(int slicer,int slices)
209 {
210     int slice = mManager->GetSlicer(0)->GetSlice();
211     int tslice = mManager->GetSlicer(0)->GetTSlice();
212     mClipper->SetInput(mManager->GetSlicer(0)->GetInput());
213     int* extent = mManager->GetSlicer(0)->GetImageActor()->GetDisplayExtent();
214     mClipper->SetOutputWholeExtent(extent[0],extent[1],extent[2],extent[3],extent[4],extent[5]);
215     int i;
216     for (i = 0; i < 6;i = i+2)
217     {
218         if (extent[i] == extent[i+1])
219         {
220             break;
221         }
222     }
223
224     switch (i)
225     {
226     case 0:
227         if (mManager->GetSlicer(0)->GetRenderer()->GetActiveCamera()->GetPosition()[0] > slice)
228         {
229             mSquaresActor1->SetPosition(1,0,0);
230             mSquaresActor2->SetPosition(1,0,0);
231         }
232         else
233         {
234             mSquaresActor1->SetPosition(-1,0,0);
235             mSquaresActor2->SetPosition(-1,0,0);
236         }
237         break;
238     case 2:
239         if (mManager->GetSlicer(0)->GetRenderer()->GetActiveCamera()->GetPosition()[1] > slice)
240         {
241             mSquaresActor1->SetPosition(0,1,0);
242             mSquaresActor2->SetPosition(0,1,0);
243         }
244         else
245         {
246             mSquaresActor1->SetPosition(0,-1,0);
247             mSquaresActor2->SetPosition(0,-1,0);
248         }
249         break;
250     case 4:
251         if (mManager->GetSlicer(0)->GetRenderer()->GetActiveCamera()->GetPosition()[2] > slice)
252         {
253             mSquaresActor1->SetPosition(0,0,1);
254             mSquaresActor2->SetPosition(0,0,1);
255         }
256         else
257         {
258             mSquaresActor1->SetPosition(0,0,-1);
259             mSquaresActor2->SetPosition(0,0,-1);
260         }
261         break;
262     }
263     mSquares1->Update();
264     mSquares2->Update();
265
266     if (m3DActors.size())
267     {
268         for (unsigned int i =0; i < m3DActors.size(); i++)
269         {
270             if (m3DActors[i]->GetVisibility())
271             {
272                 m3DActors[i]->VisibilityOff();
273             }
274         }
275         std::cout << "display " << tslice << " on " << m3DActors.size()  << std::endl;
276         m3DActors[tslice]->VisibilityOn();
277     }
278
279     mManager->Render();
280 }
281
282
283 void vvSegmentationDialog::clippingvaluechanged(int value)
284 {
285     binaryButton->setEnabled(1);
286     int min = (clipping1Slider->value() < clipping2Slider->value() ) ?
287               clipping1Slider->value():clipping2Slider->value();
288     int max = (clipping1Slider->value() > clipping2Slider->value() ) ?
289               clipping1Slider->value():clipping2Slider->value();
290     mSquares1->SetValue(0,min);
291     mSquares2->SetValue(0,max);
292
293     QString textMin = "<b> Min : </b>";
294     textMin += QString::number(min);
295     QString textMax = "\n <b> Max : </b>";
296     textMax += QString::number(max);
297     minLabel->setText(textMin);
298     maxLabel->setText(textMax);
299
300     if (mSquares1->GetInput())
301     {
302         mSquares1->Update();
303         mSquares2->Update();
304         mManager->Render();
305     }
306 }
307
308
309 void vvSegmentationDialog::BinariseSurface()
310 {
311     infoLabel->setText("Click erode then space on desired organ !");
312
313     QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
314     int clampMin = (clipping1Slider->value() < clipping2Slider->value() ) ?
315                    clipping1Slider->value():clipping2Slider->value();
316     int clampMax = (clipping1Slider->value() > clipping2Slider->value() ) ?
317                    clipping1Slider->value():clipping2Slider->value();
318     vtkImageData* outputImage = vtkImageData::New();
319
320     for (unsigned int numImage = 0; numImage < mManager->GetSlicer(0)->GetImage()->GetVTKImages().size(); numImage++)
321     {
322         vtkImageData* image = mManager->GetSlicer(0)->GetImage()->GetVTKImages()[numImage];
323         int ext[6];
324         image->GetWholeExtent(ext);
325         void *in1Ptr;
326         in1Ptr = image->GetScalarPointerForExtent(ext);
327
328         switch (image->GetScalarType())
329         {
330             vtkTemplateMacro(
331                 vvImageBinarize(image, static_cast<VTK_TT *>(in1Ptr),
332                                 ext,clampMin,clampMax));
333         default:
334             std::cerr << "Error, unknown pixel format : " << image->GetScalarTypeAsString() << std::endl;
335             return;
336         }
337
338         outputImage->Initialize();
339         outputImage->SetExtent(ext);
340         outputImage->SetOrigin(image->GetOrigin());
341         outputImage->SetSpacing(image->GetSpacing());
342         outputImage->SetScalarTypeToUnsignedChar();
343         outputImage->CopyAndCastFrom(image,ext);
344         outputImage->Update();
345
346         image->DeepCopy(outputImage);
347         image->UpdateInformation();
348         image->PropagateUpdateExtent();
349
350         vtkImageData* imageBin = vtkImageData::New();
351         imageBin->DeepCopy(image);
352         imageBin->Update();
353         mBinaireImages.push_back(imageBin);
354     }
355
356     outputImage->Delete();
357     erodeButton->setEnabled(1);
358     QApplication::restoreOverrideCursor();
359     mManager->SetColorWindow(2);
360     mManager->SetColorLevel(0.5);
361     mManager->Render();
362 }
363
364 void vvSegmentationDialog::Erode()
365 {
366     QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
367     vtkImageContinuousErode3D* erode = vtkImageContinuousErode3D::New();
368     erode->SetKernelSize(mKernelValue,mKernelValue,mKernelValue);
369     for (unsigned int numImage = 0; numImage < mManager->GetSlicer(0)->GetImage()->GetVTKImages().size(); numImage++)
370     {
371         vtkImageData* image = mManager->GetSlicer(0)->GetImage()->GetVTKImages()[numImage];
372         erode->SetInput(image);
373         erode->Update();
374         image->DeepCopy(erode->GetOutput());
375         image->Update();
376     }
377     erode->Delete();
378     dilateButton->setEnabled(1);
379     mManager->Render();
380     QApplication::restoreOverrideCursor();
381 }
382
383 void vvSegmentationDialog::Dilate()
384 {
385     QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
386     vtkImageContinuousDilate3D* dilate = vtkImageContinuousDilate3D::New();
387     vtkImageLogic* And = vtkImageLogic::New();
388     And->SetOperationToAnd();
389     dilate->SetKernelSize(mKernelValue,mKernelValue,mKernelValue);
390     for (unsigned int numImage = 0; numImage < mManager->GetSlicer(0)->GetImage()->GetVTKImages().size(); numImage++)
391     {
392         vtkImageData* image = mManager->GetSlicer(0)->GetImage()->GetVTKImages()[numImage];
393         dilate->SetInput(image);
394         vtkImageData* mask = mBinaireImages[numImage];
395         And->SetInput1(dilate->GetOutput());
396         And->SetInput2(mask);
397         And->Update();
398         image->DeepCopy(And->GetOutput());
399         image->Update();
400     }
401     And->Delete();
402     dilate->Delete();
403     mManager->Render();
404     QApplication::restoreOverrideCursor();
405 }
406
407 void vvSegmentationDialog::InsertSeed()
408 {
409     QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
410     int point4D[4];
411     point4D[0] = mManager->GetLandmarks()->GetCoordinates(
412                      mManager->GetLandmarks()->GetNumberOfPoints()-1)[0];
413     point4D[1] = mManager->GetLandmarks()->GetCoordinates(
414                      mManager->GetLandmarks()->GetNumberOfPoints()-1)[1];
415     point4D[2] = mManager->GetLandmarks()->GetCoordinates(
416                      mManager->GetLandmarks()->GetNumberOfPoints()-1)[2];
417     point4D[3] = mManager->GetLandmarks()->GetCoordinates(
418                      mManager->GetLandmarks()->GetNumberOfPoints()-1)[3];
419
420     point4D[0] = point4D[0]/mManager->GetSlicer(0)->GetImage()->GetVTKImages()[0]->GetSpacing()[0];
421     point4D[1] = point4D[1]/mManager->GetSlicer(0)->GetImage()->GetVTKImages()[0]->GetSpacing()[1];
422     point4D[2] = point4D[2]/mManager->GetSlicer(0)->GetImage()->GetVTKImages()[0]->GetSpacing()[2];
423
424     vtkImageSeedConnectivity* seed = vtkImageSeedConnectivity::New();
425     seed->SetInputConnectValue(1);
426     seed->SetOutputConnectedValue(1);
427     seed->SetOutputUnconnectedValue(0);
428     seed->AddSeed(point4D[0],point4D[1],point4D[2]);
429
430     for (unsigned int numImage = 0; numImage < mManager->GetSlicer(0)->GetImage()->GetVTKImages().size(); numImage++)
431     {
432         vtkImageData* image = mManager->GetSlicer(0)->GetImage()->GetVTKImages()[numImage];
433         seed->SetInput(image);
434         seed->Update();
435         image->DeepCopy(seed->GetOutput());
436         image->Update();
437     }
438
439     seed->Delete();
440     QApplication::restoreOverrideCursor();
441 }
442
443 void vvSegmentationDialog::ChangeDimRendering()
444 {
445     QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
446
447     if (dimButton->text() == "3D")
448     {
449         if (m3DActors.size() == 0)
450         {
451             m3DExtractor->SetValue(0,0.5);
452             for (unsigned int numImage = 0; numImage < mManager->GetSlicer(0)->GetImage()->GetVTKImages().size(); numImage++)
453             {
454                 vtkActor* actor = vtkActor::New();
455                 m3DExtractor->SetInput(mManager->GetSlicer(0)->GetImage()->GetVTKImages()[numImage]);
456                 m3DExtractor->Update();
457
458                 vtkPolyDataMapper* mapper = vtkPolyDataMapper::New();
459                 mapper->SetInput(m3DExtractor->GetOutput());
460                 m3DMappers.push_back(mapper);
461
462                 actor->SetMapper(mapper);
463                 actor->GetProperty()->SetColor(1.0,0.7,0.2);
464                 actor->VisibilityOff();
465
466                 mManager->GetSlicer(0)->GetRenderer()->AddActor(actor);
467                 m3DActors.push_back(actor);
468             }
469         }
470
471         mManager->GetSlicer(0)->GetRenderer()->SetBackground(0.5,0.6,0.9);
472         m3DActors[0]->VisibilityOn();
473
474         vtkInteractorStyleTrackballCamera* style = vtkInteractorStyleTrackballCamera::New();
475         mManager->SetInteractorStyleNavigator(0,style);
476         style->Delete();
477
478         mManager->GetSlicer(0)->GetImageActor()->VisibilityOff();
479         mSquaresActor1->VisibilityOff();
480         mSquaresActor2->VisibilityOff();
481         mManager->Render();
482         dimButton->setText("2D");
483     }
484     else
485     {
486         mManager->GetSlicer(0)->GetRenderer()->SetBackground(0.0,0.0,0.0);
487         vvInteractorStyleNavigator* style = vvInteractorStyleNavigator::New();
488         mManager->SetInteractorStyleNavigator(0,style);
489         style->Delete();
490
491         mManager->GetSlicer(0)->SetSliceOrientation(2);
492         m3DActors[mManager->GetSlicer(0)->GetTSlice()]->VisibilityOff();
493
494         mManager->GetSlicer(0)->GetImageActor()->VisibilityOn();
495         mSquaresActor1->VisibilityOn();
496         mSquaresActor2->VisibilityOn();
497         dimButton->setText("3D");
498     }
499     QApplication::restoreOverrideCursor();
500 }
501
502 void vvSegmentationDialog::KernelValueChanged(int kernel)
503 {
504     mKernelValue = kernel;
505 }
506
507 void vvSegmentationDialog::Save()
508 {
509     if (dimButton->text() == "2D") //If in *3D* mode, save the mesh
510     {
511         QString fileName = QFileDialog::getSaveFileName(this,
512                 tr("Save Mesh As"),
513                 QDir::home().dirName(),
514                 "Mesh Files (*.vtk *.vtp)");
515         if (!fileName.isEmpty())
516         {
517             vtkSmartPointer<vtkPolyDataWriter> w = vtkSmartPointer<vtkPolyDataWriter>::New();
518             w->SetInput(m3DExtractor->GetOutput());
519             w->SetFileName(fileName.toStdString().c_str());
520             w->Write();
521         }
522     }
523     else {
524         QStringList OutputListeFormat;
525         OutputListeFormat.clear();
526         int dimension = mManager->GetDimension();
527         if (dimension == 1)
528         {
529             OutputListeFormat.push_back(".mhd");
530         }
531         if (dimension == 2)
532         {
533             OutputListeFormat.push_back(".bmp");
534             OutputListeFormat.push_back(".png");
535             OutputListeFormat.push_back(".jpeg");
536             OutputListeFormat.push_back(".tif");
537             OutputListeFormat.push_back(".mhd");
538             OutputListeFormat.push_back(".hdr");
539             OutputListeFormat.push_back(".vox");
540         }
541         else if (dimension == 3)
542         {
543             OutputListeFormat.push_back(".mhd");
544             OutputListeFormat.push_back(".hdr");
545             OutputListeFormat.push_back(".vox");
546         }
547         else if (dimension == 4)
548         {
549             OutputListeFormat.push_back(".mhd");
550         }
551         QString Extensions = "AllFiles(*.*)";
552         for (int i = 0; i < OutputListeFormat.count(); i++)
553         {
554             Extensions += ";;Images ( *";
555             Extensions += OutputListeFormat[i];
556             Extensions += ")";
557         }
558         QString fileName = QFileDialog::getSaveFileName(this,
559                 tr("Save As"),
560                 QDir::home().dirName(),
561                 Extensions);
562         if (!fileName.isEmpty())
563         {
564             std::string fileformat = vtksys::SystemTools::GetFilenameLastExtension(fileName.toStdString());
565             if (OutputListeFormat.contains(
566                         fileformat.c_str()))
567             {
568                 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
569                 vvProgressDialog progress("Saving "+fileName.toStdString());
570                 qApp->processEvents();
571                 vvImageWriter *writer = new vvImageWriter;
572                 writer->SetOutputFileName(fileName.toStdString());
573                 writer->SetInput(mManager->GetSlicer(0)->GetImage());
574                 writer->Update(dimension,"unsigned_char");
575                 QApplication::restoreOverrideCursor();
576                 if (writer->GetLastError().size())
577                 {
578                     QString error = "Saving did not succeed\n";
579                     error += writer->GetLastError().c_str();
580                     QMessageBox::information(this,tr("Saving Problem"),error);
581                     Save();
582                 }
583             }
584             else
585             {
586                 QString error = fileformat.c_str();
587                 if (error.isEmpty())
588                     error += "no file format specified !";
589                 else
590                     error += " format unknown !!!\n";
591                 QMessageBox::information(this,tr("Saving Problem"),error);
592                 Save();
593             }
594         }
595     }
596 }
597
598 #endif /* end #define _vvSegmentationDialog_CXX */
599