1 #ifndef _vvSegmentationDialog_CXX
2 #define _vvSegmentationDialog_CXX
6 #include "vvSegmentationDialog.h"
7 #include "vvProgressDialog.h"
8 #include "vvImageWriter.h"
9 #include "vvLandmarks.h"
10 #include "vvInteractorStyleNavigator.h"
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>
41 #include <QMessageBox>
43 //====================================================================
44 vvSegmentationDialog::vvSegmentationDialog(QWidget * parent, Qt::WindowFlags f)
45 :QDialog(parent,f), Ui::vvSegmentationDialog() {
49 mManager = new vvSlicerManager(1);
51 mClipper = vtkImageClip::New();
52 mSquares1 = vtkMarchingSquares::New();
53 mSquaresMapper1 = vtkPolyDataMapper::New();
54 mSquaresActor1 = vtkActor::New();
56 mSquares2 = vtkMarchingSquares::New();
57 mSquaresMapper2 = vtkPolyDataMapper::New();
58 mSquaresActor2 = vtkActor::New();
60 //m3DMapper = vtkPolyDataMapper::New();
61 //m3DActor = vtkActor::New();
62 m3DExtractor = vtkMarchingCubes::New();
66 mBinaireImages.clear();
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)));
78 binaryButton->setEnabled(0);
79 erodeButton->setEnabled(0);
80 dilateButton->setEnabled(0);
81 infoLabel->setText("Select Up and Down threshold before clicking binarise !");
84 vvSegmentationDialog::~vvSegmentationDialog()
88 mSquaresActor1->Delete();
89 mSquaresMapper1->Delete();
92 mSquaresActor2->Delete();
93 mSquaresMapper2->Delete();
96 //m3DMapper->Delete();
98 m3DExtractor->Delete();
100 for (unsigned int i = 0; i < mBinaireImages.size(); i++)
101 mBinaireImages[i]->Delete();
103 for (unsigned int i = 0; i < m3DActors.size(); i++)
104 m3DActors[i]->Delete();
106 for (unsigned int i = 0; i < m3DMappers.size(); i++)
107 m3DMappers[i]->Delete();
112 //----------------------------------------------------------------------------
113 // This templated function executes the filter for any type of data.
114 // Handles the one input operations
116 void vvImageBinarize(vtkImageData *in1Data, T *in1Ptr,
117 int outExt[6],int clampMin, int clampMax)
119 int idxR, idxY, idxZ;
121 vtkIdType inIncX, inIncY, inIncZ;
124 // find the region to loop over
126 (outExt[1] - outExt[0]+1)*in1Data->GetNumberOfScalarComponents();
127 // What a pain. Maybe I should just make another filter.
129 maxY = outExt[3] - outExt[2];
130 maxZ = outExt[5] - outExt[4];
132 // Get increments to march through data
133 in1Data->GetContinuousIncrements(outExt, inIncX, inIncY, inIncZ);
135 for (idxZ = 0; idxZ <= maxZ; idxZ++)
137 for (idxY = 0; idxY <= maxY; idxY++)
139 for (idxR = 0; idxR < rowLength; idxR++)
141 if (static_cast<double>(*in1Ptr) > clampMin && static_cast<double>(*in1Ptr) <= clampMax)
142 *in1Ptr = static_cast<T>(1);
144 *in1Ptr = static_cast<T>(0);
153 void vvSegmentationDialog::SetImage(vvImage::Pointer image)
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);
164 mManager->GetImage()->GetScalarRange(range);
165 mManager->GetSlicer(0)->SetColorWindow(range[1]-range[0]);
166 mManager->GetSlicer(0)->SetColorLevel((range[1]+range[0])/2);
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]);
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());
181 mSquaresMapper1->SetInput(mSquares1->GetOutput());
182 mSquaresMapper2->SetInput(mSquares2->GetOutput());
183 mSquaresMapper1->ScalarVisibilityOff();
184 mSquaresMapper2->ScalarVisibilityOff();
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);
193 mManager->GetSlicer(0)->GetRenderer()->AddActor(mSquaresActor1);
194 mManager->GetSlicer(0)->GetRenderer()->AddActor(mSquaresActor2);
199 UpdateSlice(0,mManager->GetSlicer(0)->GetSlice());
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();
208 void vvSegmentationDialog::UpdateSlice(int slicer,int slices)
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]);
216 for (i = 0; i < 6;i = i+2)
218 if (extent[i] == extent[i+1])
227 if (mManager->GetSlicer(0)->GetRenderer()->GetActiveCamera()->GetPosition()[0] > slice)
229 mSquaresActor1->SetPosition(1,0,0);
230 mSquaresActor2->SetPosition(1,0,0);
234 mSquaresActor1->SetPosition(-1,0,0);
235 mSquaresActor2->SetPosition(-1,0,0);
239 if (mManager->GetSlicer(0)->GetRenderer()->GetActiveCamera()->GetPosition()[1] > slice)
241 mSquaresActor1->SetPosition(0,1,0);
242 mSquaresActor2->SetPosition(0,1,0);
246 mSquaresActor1->SetPosition(0,-1,0);
247 mSquaresActor2->SetPosition(0,-1,0);
251 if (mManager->GetSlicer(0)->GetRenderer()->GetActiveCamera()->GetPosition()[2] > slice)
253 mSquaresActor1->SetPosition(0,0,1);
254 mSquaresActor2->SetPosition(0,0,1);
258 mSquaresActor1->SetPosition(0,0,-1);
259 mSquaresActor2->SetPosition(0,0,-1);
266 if (m3DActors.size())
268 for (unsigned int i =0; i < m3DActors.size(); i++)
270 if (m3DActors[i]->GetVisibility())
272 m3DActors[i]->VisibilityOff();
275 std::cout << "display " << tslice << " on " << m3DActors.size() << std::endl;
276 m3DActors[tslice]->VisibilityOn();
283 void vvSegmentationDialog::clippingvaluechanged(int value)
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);
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);
300 if (mSquares1->GetInput())
309 void vvSegmentationDialog::BinariseSurface()
311 infoLabel->setText("Click erode then space on desired organ !");
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();
320 for (unsigned int numImage = 0; numImage < mManager->GetSlicer(0)->GetImage()->GetVTKImages().size(); numImage++)
322 vtkImageData* image = mManager->GetSlicer(0)->GetImage()->GetVTKImages()[numImage];
324 image->GetWholeExtent(ext);
326 in1Ptr = image->GetScalarPointerForExtent(ext);
328 switch (image->GetScalarType())
331 vvImageBinarize(image, static_cast<VTK_TT *>(in1Ptr),
332 ext,clampMin,clampMax));
334 std::cerr << "Error, unknown pixel format : " << image->GetScalarTypeAsString() << std::endl;
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();
346 image->DeepCopy(outputImage);
347 image->UpdateInformation();
348 image->PropagateUpdateExtent();
350 vtkImageData* imageBin = vtkImageData::New();
351 imageBin->DeepCopy(image);
353 mBinaireImages.push_back(imageBin);
356 outputImage->Delete();
357 erodeButton->setEnabled(1);
358 QApplication::restoreOverrideCursor();
359 mManager->SetColorWindow(2);
360 mManager->SetColorLevel(0.5);
364 void vvSegmentationDialog::Erode()
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++)
371 vtkImageData* image = mManager->GetSlicer(0)->GetImage()->GetVTKImages()[numImage];
372 erode->SetInput(image);
374 image->DeepCopy(erode->GetOutput());
378 dilateButton->setEnabled(1);
380 QApplication::restoreOverrideCursor();
383 void vvSegmentationDialog::Dilate()
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++)
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);
398 image->DeepCopy(And->GetOutput());
404 QApplication::restoreOverrideCursor();
407 void vvSegmentationDialog::InsertSeed()
409 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
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];
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];
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]);
430 for (unsigned int numImage = 0; numImage < mManager->GetSlicer(0)->GetImage()->GetVTKImages().size(); numImage++)
432 vtkImageData* image = mManager->GetSlicer(0)->GetImage()->GetVTKImages()[numImage];
433 seed->SetInput(image);
435 image->DeepCopy(seed->GetOutput());
440 QApplication::restoreOverrideCursor();
443 void vvSegmentationDialog::ChangeDimRendering()
445 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
447 if (dimButton->text() == "3D")
449 if (m3DActors.size() == 0)
451 m3DExtractor->SetValue(0,0.5);
452 for (unsigned int numImage = 0; numImage < mManager->GetSlicer(0)->GetImage()->GetVTKImages().size(); numImage++)
454 vtkActor* actor = vtkActor::New();
455 m3DExtractor->SetInput(mManager->GetSlicer(0)->GetImage()->GetVTKImages()[numImage]);
456 m3DExtractor->Update();
458 vtkPolyDataMapper* mapper = vtkPolyDataMapper::New();
459 mapper->SetInput(m3DExtractor->GetOutput());
460 m3DMappers.push_back(mapper);
462 actor->SetMapper(mapper);
463 actor->GetProperty()->SetColor(1.0,0.7,0.2);
464 actor->VisibilityOff();
466 mManager->GetSlicer(0)->GetRenderer()->AddActor(actor);
467 m3DActors.push_back(actor);
471 mManager->GetSlicer(0)->GetRenderer()->SetBackground(0.5,0.6,0.9);
472 m3DActors[0]->VisibilityOn();
474 vtkInteractorStyleTrackballCamera* style = vtkInteractorStyleTrackballCamera::New();
475 mManager->SetInteractorStyleNavigator(0,style);
478 mManager->GetSlicer(0)->GetImageActor()->VisibilityOff();
479 mSquaresActor1->VisibilityOff();
480 mSquaresActor2->VisibilityOff();
482 dimButton->setText("2D");
486 mManager->GetSlicer(0)->GetRenderer()->SetBackground(0.0,0.0,0.0);
487 vvInteractorStyleNavigator* style = vvInteractorStyleNavigator::New();
488 mManager->SetInteractorStyleNavigator(0,style);
491 mManager->GetSlicer(0)->SetSliceOrientation(2);
492 m3DActors[mManager->GetSlicer(0)->GetTSlice()]->VisibilityOff();
494 mManager->GetSlicer(0)->GetImageActor()->VisibilityOn();
495 mSquaresActor1->VisibilityOn();
496 mSquaresActor2->VisibilityOn();
497 dimButton->setText("3D");
499 QApplication::restoreOverrideCursor();
502 void vvSegmentationDialog::KernelValueChanged(int kernel)
504 mKernelValue = kernel;
507 void vvSegmentationDialog::Save()
509 if (dimButton->text() == "2D") //If in *3D* mode, save the mesh
511 QString fileName = QFileDialog::getSaveFileName(this,
513 QDir::home().dirName(),
514 "Mesh Files (*.vtk *.vtp)");
515 if (!fileName.isEmpty())
517 vtkSmartPointer<vtkPolyDataWriter> w = vtkSmartPointer<vtkPolyDataWriter>::New();
518 w->SetInput(m3DExtractor->GetOutput());
519 w->SetFileName(fileName.toStdString().c_str());
524 QStringList OutputListeFormat;
525 OutputListeFormat.clear();
526 int dimension = mManager->GetDimension();
529 OutputListeFormat.push_back(".mhd");
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");
541 else if (dimension == 3)
543 OutputListeFormat.push_back(".mhd");
544 OutputListeFormat.push_back(".hdr");
545 OutputListeFormat.push_back(".vox");
547 else if (dimension == 4)
549 OutputListeFormat.push_back(".mhd");
551 QString Extensions = "AllFiles(*.*)";
552 for (int i = 0; i < OutputListeFormat.count(); i++)
554 Extensions += ";;Images ( *";
555 Extensions += OutputListeFormat[i];
558 QString fileName = QFileDialog::getSaveFileName(this,
560 QDir::home().dirName(),
562 if (!fileName.isEmpty())
564 std::string fileformat = vtksys::SystemTools::GetFilenameLastExtension(fileName.toStdString());
565 if (OutputListeFormat.contains(
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())
578 QString error = "Saving did not succeed\n";
579 error += writer->GetLastError().c_str();
580 QMessageBox::information(this,tr("Saving Problem"),error);
586 QString error = fileformat.c_str();
588 error += "no file format specified !";
590 error += " format unknown !!!\n";
591 QMessageBox::information(this,tr("Saving Problem"),error);
598 #endif /* end #define _vvSegmentationDialog_CXX */