00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "QmitkBasicImageProcessingView.h"
00019
00020
00021 #include <qlabel.h>
00022 #include <qspinbox.h>
00023 #include <qpushbutton.h>
00024 #include <qcheckbox.h>
00025 #include <qgroupbox.h>
00026 #include <qradiobutton.h>
00027 #include <qmessagebox.h>
00028
00029
00030 #include <berryISelectionService.h>
00031 #include <berryIWorkbenchWindow.h>
00032
00033
00034 #include "QmitkStdMultiWidget.h"
00035 #include "QmitkDataNodeSelectionProvider.h"
00036 #include "mitkDataNodeObject.h"
00037
00038
00039 #include "mitkNodePredicateDataType.h"
00040 #include "mitkNodePredicateDimension.h"
00041 #include "mitkNodePredicateAnd.h"
00042 #include "mitkImageTimeSelector.h"
00043 #include "mitkVectorImageMapper2D.h"
00044 #include "mitkProperties.h"
00045
00046
00047 #include "mitkImageCast.h"
00048 #include "mitkITKImageImport.h"
00049
00050
00051 #include <itkVectorImage.h>
00052
00053
00054 #include <itkBinaryBallStructuringElement.h>
00055 #include <itkGrayscaleDilateImageFilter.h>
00056 #include <itkGrayscaleErodeImageFilter.h>
00057 #include <itkGrayscaleMorphologicalOpeningImageFilter.h>
00058 #include <itkGrayscaleMorphologicalClosingImageFilter.h>
00059
00060
00061 #include <itkMedianImageFilter.h>
00062 #include <itkDiscreteGaussianImageFilter.h>
00063 #include <itkTotalVariationDenoisingImageFilter.h>
00064
00065
00066 #include <itkBinaryThresholdImageFilter.h>
00067
00068
00069 #include <itkInvertIntensityImageFilter.h>
00070
00071
00072 #include <itkGradientMagnitudeRecursiveGaussianImageFilter.h>
00073 #include <itkLaplacianImageFilter.h>
00074 #include <itkSobelEdgeDetectionImageFilter.h>
00075
00076
00077 #include <itkResampleImageFilter.h>
00078 #include <itkNearestNeighborInterpolateImageFunction.h>
00079
00080
00081 #include <itkAddImageFilter.h>
00082 #include <itkSubtractImageFilter.h>
00083 #include <itkMultiplyImageFilter.h>
00084 #include <itkDivideImageFilter.h>
00085
00086
00087 #include <itkOrImageFilter.h>
00088 #include <itkAndImageFilter.h>
00089 #include <itkXorImageFilter.h>
00090
00091
00092
00093 typedef itk::Image<short, 3> ImageType;
00094 typedef itk::Image<double, 3> FloatImageType;
00095 typedef itk::Image<itk::Vector<float,3>, 3> VectorImageType;
00096
00097 typedef itk::BinaryBallStructuringElement<ImageType::PixelType, 3> BallType;
00098 typedef itk::GrayscaleDilateImageFilter<ImageType, ImageType, BallType> DilationFilterType;
00099 typedef itk::GrayscaleErodeImageFilter<ImageType, ImageType, BallType> ErosionFilterType;
00100 typedef itk::GrayscaleMorphologicalOpeningImageFilter<ImageType, ImageType, BallType> OpeningFilterType;
00101 typedef itk::GrayscaleMorphologicalClosingImageFilter<ImageType, ImageType, BallType> ClosingFilterType;
00102
00103 typedef itk::MedianImageFilter< ImageType, ImageType > MedianFilterType;
00104 typedef itk::DiscreteGaussianImageFilter< ImageType, ImageType> GaussianFilterType;
00105 typedef itk::TotalVariationDenoisingImageFilter<FloatImageType, FloatImageType> TotalVariationFilterType;
00106 typedef itk::TotalVariationDenoisingImageFilter<VectorImageType, VectorImageType> VectorTotalVariationFilterType;
00107
00108 typedef itk::BinaryThresholdImageFilter< ImageType, ImageType > ThresholdFilterType;
00109 typedef itk::InvertIntensityImageFilter< ImageType, ImageType > InversionFilterType;
00110
00111 typedef itk::GradientMagnitudeRecursiveGaussianImageFilter< ImageType, ImageType > GradientFilterType;
00112 typedef itk::LaplacianImageFilter< FloatImageType, FloatImageType > LaplacianFilterType;
00113 typedef itk::SobelEdgeDetectionImageFilter< FloatImageType, FloatImageType > SobelFilterType;
00114
00115 typedef itk::ResampleImageFilter< ImageType, FloatImageType > ResampleImageFilterType;
00116
00117 typedef itk::AddImageFilter< ImageType, ImageType, ImageType > AddFilterType;
00118 typedef itk::SubtractImageFilter< ImageType, ImageType, ImageType > SubtractFilterType;
00119 typedef itk::MultiplyImageFilter< ImageType, ImageType, ImageType > MultiplyFilterType;
00120 typedef itk::DivideImageFilter< ImageType, ImageType, FloatImageType > DivideFilterType;
00121
00122 typedef itk::OrImageFilter< ImageType, ImageType > OrImageFilterType;
00123 typedef itk::AndImageFilter< ImageType, ImageType > AndImageFilterType;
00124 typedef itk::XorImageFilter< ImageType, ImageType > XorImageFilterType;
00125
00126
00127 QmitkBasicImageProcessing::QmitkBasicImageProcessing()
00128 : QmitkFunctionality(),
00129 m_Controls(NULL),
00130 m_SelectedImageNode(NULL),
00131 m_TimeStepperAdapter(NULL),
00132 m_SelectionListener(NULL)
00133 {
00134 }
00135
00136 QmitkBasicImageProcessing::~QmitkBasicImageProcessing()
00137 {
00138
00139
00140
00141 }
00142
00143 void QmitkBasicImageProcessing::CreateQtPartControl(QWidget *parent)
00144 {
00145 if (m_Controls == NULL)
00146 {
00147 m_Controls = new Ui::QmitkBasicImageProcessingViewControls;
00148 m_Controls->setupUi(parent);
00149 this->CreateConnections();
00150
00151
00152
00153
00154 mitk::NodePredicateDimension::Pointer dimensionPredicate = mitk::NodePredicateDimension::New(3);
00155 mitk::NodePredicateDataType::Pointer imagePredicate = mitk::NodePredicateDataType::New("Image");
00156 m_Controls->m_ImageSelector2->SetDataStorage(this->GetDefaultDataStorage());
00157 m_Controls->m_ImageSelector2->SetPredicate(mitk::NodePredicateAnd::New(dimensionPredicate, imagePredicate));
00158 }
00159 m_Controls->gbTwoImageOps->hide();
00160
00161 m_SelectedImageNode = mitk::DataStorageSelection::New(this->GetDefaultDataStorage(), false);
00162 }
00163
00164 void QmitkBasicImageProcessing::CreateConnections()
00165 {
00166 if ( m_Controls )
00167 {
00168 connect( (QObject*)(m_Controls->cbWhat1), SIGNAL( activated(int) ), this, SLOT( SelectAction(int) ) );
00169 connect( (QObject*)(m_Controls->btnDoIt), SIGNAL(clicked()),(QObject*) this, SLOT(StartButtonClicked()));
00170
00171 connect( (QObject*)(m_Controls->cbWhat2), SIGNAL( activated(int) ), this, SLOT( SelectAction2(int) ) );
00172 connect( (QObject*)(m_Controls->btnDoIt2), SIGNAL(clicked()),(QObject*) this, SLOT(StartButton2Clicked()));
00173
00174 connect( (QObject*)(m_Controls->rBOneImOp), SIGNAL( clicked() ), this, SLOT( ChangeGUI() ) );
00175 connect( (QObject*)(m_Controls->rBTwoImOp), SIGNAL( clicked() ), this, SLOT( ChangeGUI() ) );
00176 }
00177
00178 m_TimeStepperAdapter = new QmitkStepperAdapter((QObject*) m_Controls->sliceNavigatorTime,
00179 GetActiveStdMultiWidget()->GetTimeNavigationController()->GetTime(), "sliceNavigatorTimeFromBIP");
00180 }
00181
00182 void QmitkBasicImageProcessing::Activated()
00183 {
00184 QmitkFunctionality::Activated();
00185
00186 this->m_Controls->cbWhat1->clear();
00187 this->m_Controls->cbWhat1->insertItem( NOACTIONSELECTED, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Please select operation", 0, QApplication::UnicodeUTF8) ));
00188 this->m_Controls->cbWhat1->insertItem( CATEGORY_DENOISING, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "--- Denoising ---", 0, QApplication::UnicodeUTF8) ));
00189 this->m_Controls->cbWhat1->insertItem( GAUSSIAN, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Gaussian", 0, QApplication::UnicodeUTF8) ));
00190 this->m_Controls->cbWhat1->insertItem( MEDIAN, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Median", 0, QApplication::UnicodeUTF8) ));
00191 this->m_Controls->cbWhat1->insertItem( TOTALVARIATION, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Total Variation", 0, QApplication::UnicodeUTF8) ));
00192 this->m_Controls->cbWhat1->insertItem( CATEGORY_MORPHOLOGICAL, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "--- Morphological ---", 0, QApplication::UnicodeUTF8) ));
00193 this->m_Controls->cbWhat1->insertItem( DILATION, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Dilation", 0, QApplication::UnicodeUTF8) ));
00194 this->m_Controls->cbWhat1->insertItem( EROSION, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Erosion", 0, QApplication::UnicodeUTF8) ));
00195 this->m_Controls->cbWhat1->insertItem( OPENING, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Opening", 0, QApplication::UnicodeUTF8) ));
00196 this->m_Controls->cbWhat1->insertItem( CLOSING, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Closing", 0, QApplication::UnicodeUTF8) ));
00197 this->m_Controls->cbWhat1->insertItem( CATEGORY_EDGE_DETECTION, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "--- Edge Detection ---", 0, QApplication::UnicodeUTF8) ));
00198 this->m_Controls->cbWhat1->insertItem( GRADIENT, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Gradient", 0, QApplication::UnicodeUTF8) ));
00199 this->m_Controls->cbWhat1->insertItem( LAPLACIAN, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Laplacian (2nd Derivative)", 0, QApplication::UnicodeUTF8) ));
00200 this->m_Controls->cbWhat1->insertItem( SOBEL, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Sobel Operator", 0, QApplication::UnicodeUTF8) ));
00201 this->m_Controls->cbWhat1->insertItem( CATEGORY_MISC, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "--- Misc ---", 0, QApplication::UnicodeUTF8) ));
00202 this->m_Controls->cbWhat1->insertItem( THRESHOLD, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Threshold", 0, QApplication::UnicodeUTF8) ));
00203 this->m_Controls->cbWhat1->insertItem( INVERSION, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Image Inversion", 0, QApplication::UnicodeUTF8) ));
00204 this->m_Controls->cbWhat1->insertItem( DOWNSAMPLING, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Downsampling", 0, QApplication::UnicodeUTF8) ));
00205
00206 this->m_Controls->cbWhat2->clear();
00207 this->m_Controls->cbWhat2->insertItem( TWOIMAGESNOACTIONSELECTED, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Please select on operation", 0, QApplication::UnicodeUTF8) ) );
00208 this->m_Controls->cbWhat2->insertItem( CATEGORY_ARITHMETIC, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "--- Arithmetric operations ---", 0, QApplication::UnicodeUTF8) ) );
00209 this->m_Controls->cbWhat2->insertItem( ADD, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Add to Image 1:", 0, QApplication::UnicodeUTF8) ) );
00210 this->m_Controls->cbWhat2->insertItem( SUBTRACT, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Subtract from Image 1:", 0, QApplication::UnicodeUTF8) ) );
00211 this->m_Controls->cbWhat2->insertItem( MULTIPLY, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Multiply with Image 1:", 0, QApplication::UnicodeUTF8) ) );
00212 this->m_Controls->cbWhat2->insertItem( DIVIDE, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Divide Image 1 by:", 0, QApplication::UnicodeUTF8) ) );
00213 this->m_Controls->cbWhat2->insertItem( CATEGORY_BOOLEAN, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "--- Boolean operations ---", 0, QApplication::UnicodeUTF8) ) );
00214 this->m_Controls->cbWhat2->insertItem( AND, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "AND", 0, QApplication::UnicodeUTF8) ) );
00215 this->m_Controls->cbWhat2->insertItem( OR, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "OR", 0, QApplication::UnicodeUTF8) ) );
00216 this->m_Controls->cbWhat2->insertItem( XOR, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "XOR", 0, QApplication::UnicodeUTF8) ) );
00217
00218 }
00219
00220
00221 void QmitkBasicImageProcessing::OnSelectionChanged(std::vector<mitk::DataNode*> nodes)
00222 {
00223
00224 if (!nodes.empty())
00225 {
00226
00227 this->ResetOneImageOpPanel();
00228 m_Controls->sliceNavigatorTime->setEnabled(false);
00229 m_Controls->leImage1->setText("Select an Image in Data Manager");
00230 m_Controls->tlWhat1->setEnabled(false);
00231 m_Controls->cbWhat1->setEnabled(false);
00232 m_Controls->tlWhat2->setEnabled(false);
00233 m_Controls->cbWhat2->setEnabled(false);
00234
00235 m_SelectedImageNode->RemoveAllNodes();
00236
00237 mitk::DataNode* _DataNode = nodes.front();
00238 *m_SelectedImageNode = _DataNode;
00239
00240 mitk::Image::Pointer tempImage = dynamic_cast<mitk::Image*>(m_SelectedImageNode->GetNode()->GetData());
00241
00242
00243 if( tempImage.IsNull() || (tempImage->IsInitialized() == false) )
00244 {
00245 m_Controls->leImage1->setText("Not an image.");
00246 return;
00247 }
00248
00249
00250 if( tempImage->GetDimension() < 3)
00251 {
00252 m_Controls->leImage1->setText("2D images are not supported.");
00253 return;
00254 }
00255
00256
00257 m_Controls->leImage1->setText(QString(m_SelectedImageNode->GetNode()->GetName().c_str()));
00258
00259
00260 if ( tempImage->GetDimension() > 3 )
00261 {
00262 m_Controls->sliceNavigatorTime->setEnabled(true);
00263 m_Controls->tlTime->setEnabled(true);
00264 }
00265 m_Controls->tlWhat1->setEnabled(true);
00266 m_Controls->cbWhat1->setEnabled(true);
00267 m_Controls->tlWhat2->setEnabled(true);
00268 m_Controls->cbWhat2->setEnabled(true);
00269 }
00270 }
00271
00272 void QmitkBasicImageProcessing::ChangeGUI()
00273 {
00274 if(m_Controls->rBOneImOp->isChecked())
00275 {
00276 m_Controls->gbTwoImageOps->hide();
00277 m_Controls->gbOneImageOps->show();
00278 }
00279 else if(m_Controls->rBTwoImOp->isChecked())
00280 {
00281 m_Controls->gbOneImageOps->hide();
00282 m_Controls->gbTwoImageOps->show();
00283 }
00284 }
00285
00286 void QmitkBasicImageProcessing::ResetOneImageOpPanel()
00287 {
00288 m_Controls->tlParam1->setText("Param1");
00289 m_Controls->tlParam2->setText("Param2");
00290
00291 m_Controls->cbWhat1->setCurrentIndex(0);
00292
00293 m_Controls->tlTime->setEnabled(false);
00294
00295 this->ResetParameterPanel();
00296
00297 m_Controls->btnDoIt->setEnabled(false);
00298 m_Controls->cbHideOrig->setEnabled(false);
00299 }
00300
00301 void QmitkBasicImageProcessing::ResetParameterPanel()
00302 {
00303 m_Controls->tlParam->setEnabled(false);
00304 m_Controls->tlParam1->setEnabled(false);
00305 m_Controls->tlParam2->setEnabled(false);
00306
00307 m_Controls->sbParam1->setEnabled(false);
00308 m_Controls->sbParam2->setEnabled(false);
00309 m_Controls->sbParam1->setValue(0);
00310 m_Controls->sbParam2->setValue(0);
00311 }
00312
00313 void QmitkBasicImageProcessing::ResetTwoImageOpPanel()
00314 {
00315 m_Controls->cbWhat2->setCurrentIndex(0);
00316
00317 m_Controls->tlImage2->setEnabled(false);
00318 m_Controls->m_ImageSelector2->setEnabled(false);
00319
00320 m_Controls->btnDoIt2->setEnabled(false);
00321 }
00322
00323 void QmitkBasicImageProcessing::SelectAction(int action)
00324 {
00325 if ( ! m_SelectedImageNode->GetNode() ) return;
00326
00327
00328 this->ResetParameterPanel();
00329 m_Controls->btnDoIt->setEnabled(false);
00330 m_Controls->cbHideOrig->setEnabled(false);
00331
00332 QString text1 = "No Parameters";
00333 QString text2 = "No Parameters";
00334
00335
00336 switch (action)
00337 {
00338 case 2:
00339 {
00340 m_SelectedAction = GAUSSIAN;
00341 m_Controls->tlParam1->setEnabled(true);
00342 m_Controls->sbParam1->setEnabled(true);
00343 text1 = "&Variance:";
00344
00345 m_Controls->sbParam1->setMinimum( 0 );
00346 m_Controls->sbParam1->setMaximum( 200 );
00347 m_Controls->sbParam1->setValue( 2 );
00348 break;
00349 }
00350
00351 case 3:
00352 {
00353 m_SelectedAction = MEDIAN;
00354 m_Controls->tlParam1->setEnabled(true);
00355 m_Controls->sbParam1->setEnabled(true);
00356 text1 = "&Radius:";
00357 m_Controls->sbParam1->setMinimum( 0 );
00358 m_Controls->sbParam1->setMaximum( 200 );
00359 m_Controls->sbParam1->setValue( 3 );
00360 break;
00361 }
00362
00363 case 4:
00364 {
00365 m_SelectedAction = TOTALVARIATION;
00366 m_Controls->tlParam1->setEnabled(true);
00367 m_Controls->sbParam1->setEnabled(true);
00368 m_Controls->tlParam2->setEnabled(true);
00369 m_Controls->sbParam2->setEnabled(true);
00370 text1 = "Number Iterations:";
00371 text2 = "Regularization\n(Lambda/1000):";
00372 m_Controls->sbParam1->setMinimum( 1 );
00373 m_Controls->sbParam1->setMaximum( 1000 );
00374 m_Controls->sbParam1->setValue( 40 );
00375 m_Controls->sbParam2->setMinimum( 0 );
00376 m_Controls->sbParam2->setMaximum( 100000 );
00377 m_Controls->sbParam2->setValue( 1 );
00378 break;
00379 }
00380
00381 case 6:
00382 {
00383 m_SelectedAction = DILATION;
00384 m_Controls->tlParam1->setEnabled(true);
00385 m_Controls->sbParam1->setEnabled(true);
00386 text1 = "&Radius:";
00387 m_Controls->sbParam1->setMinimum( 0 );
00388 m_Controls->sbParam1->setMaximum( 200 );
00389 m_Controls->sbParam1->setValue( 3 );
00390 break;
00391 }
00392
00393 case 7:
00394 {
00395 m_SelectedAction = EROSION;
00396 m_Controls->tlParam1->setEnabled(true);
00397 m_Controls->sbParam1->setEnabled(true);
00398 text1 = "&Radius:";
00399 m_Controls->sbParam1->setMinimum( 0 );
00400 m_Controls->sbParam1->setMaximum( 200 );
00401 m_Controls->sbParam1->setValue( 3 );
00402 break;
00403 }
00404
00405 case 8:
00406 {
00407 m_SelectedAction = OPENING;
00408 m_Controls->tlParam1->setEnabled(true);
00409 m_Controls->sbParam1->setEnabled(true);
00410 text1 = "&Radius:";
00411 m_Controls->sbParam1->setMinimum( 0 );
00412 m_Controls->sbParam1->setMaximum( 200 );
00413 m_Controls->sbParam1->setValue( 3 );
00414 break;
00415 }
00416
00417 case 9:
00418 {
00419 m_SelectedAction = CLOSING;
00420 m_Controls->tlParam1->setEnabled(true);
00421 m_Controls->sbParam1->setEnabled(true);
00422 text1 = "&Radius:";
00423 m_Controls->sbParam1->setMinimum( 0 );
00424 m_Controls->sbParam1->setMaximum( 200 );
00425 m_Controls->sbParam1->setValue( 3 );
00426 break;
00427 }
00428
00429 case 11:
00430 {
00431 m_SelectedAction = GRADIENT;
00432 m_Controls->tlParam1->setEnabled(true);
00433 m_Controls->sbParam1->setEnabled(true);
00434 text1 = "Sigma of Gaussian Kernel:\n(in Image Spacing Units)";
00435 m_Controls->sbParam1->setMinimum( 0 );
00436 m_Controls->sbParam1->setMaximum( 200 );
00437 m_Controls->sbParam1->setValue( 2 );
00438 break;
00439 }
00440
00441 case 12:
00442 {
00443 m_SelectedAction = LAPLACIAN;
00444 break;
00445 }
00446
00447 case 13:
00448 {
00449 m_SelectedAction = SOBEL;
00450 break;
00451 }
00452
00453 case 15:
00454 {
00455 m_SelectedAction = THRESHOLD;
00456 m_Controls->tlParam1->setEnabled(true);
00457 m_Controls->sbParam1->setEnabled(true);
00458 m_Controls->tlParam2->setEnabled(true);
00459 m_Controls->sbParam2->setEnabled(true);
00460 text1 = "Lower threshold:";
00461 text2 = "Upper threshold:";
00462 m_Controls->sbParam1->setMinimum( -100000 );
00463 m_Controls->sbParam1->setMaximum( 100000 );
00464 m_Controls->sbParam1->setValue( 0 );
00465 m_Controls->sbParam2->setMinimum( -100000 );
00466 m_Controls->sbParam2->setMaximum( 100000 );
00467 m_Controls->sbParam2->setValue( 300 );
00468 break;
00469 }
00470
00471 case 16:
00472 {
00473 m_SelectedAction = INVERSION;
00474 break;
00475 }
00476
00477 case 17:
00478 {
00479 m_SelectedAction = DOWNSAMPLING;
00480 m_Controls->tlParam1->setEnabled(true);
00481 m_Controls->sbParam1->setEnabled(true);
00482 text1 = "Downsampling by Factor:";
00483 m_Controls->sbParam1->setMinimum( 1 );
00484 m_Controls->sbParam1->setMaximum( 100 );
00485 m_Controls->sbParam1->setValue( 2 );
00486 break;
00487 }
00488
00489 default: return;
00490 }
00491
00492 m_Controls->tlParam->setEnabled(true);
00493 m_Controls->tlParam1->setText(text1);
00494 m_Controls->tlParam2->setText(text2);
00495
00496 m_Controls->btnDoIt->setEnabled(true);
00497 m_Controls->cbHideOrig->setEnabled(true);
00498 }
00499
00500 void QmitkBasicImageProcessing::StartButtonClicked()
00501 {
00502 if(!m_SelectedImageNode->GetNode()) return;
00503
00504 this->BusyCursorOn();
00505
00506 mitk::Image::Pointer newImage;
00507
00508 try
00509 {
00510 newImage = dynamic_cast<mitk::Image*>(m_SelectedImageNode->GetNode()->GetData());
00511 }
00512 catch ( std::exception &e )
00513 {
00514 QString exceptionString = "An error occured during image loading:\n";
00515 exceptionString.append( e.what() );
00516 QMessageBox::warning( NULL, "Basic Image Processing", exceptionString , QMessageBox::Ok, QMessageBox::NoButton );
00517 this->BusyCursorOff();
00518 return;
00519 }
00520
00521
00522 if ( (! newImage) || (newImage->IsInitialized() == false) )
00523 {
00524 this->BusyCursorOff();
00525
00526 QMessageBox::warning( NULL, "Basic Image Processing", "Input image is broken or not initialized. Returning.", QMessageBox::Ok, QMessageBox::NoButton );
00527 return;
00528 }
00529
00530
00531 if(newImage->GetDimension() > 3)
00532 {
00533 mitk::ImageTimeSelector::Pointer timeSelector = mitk::ImageTimeSelector::New();
00534 timeSelector->SetInput(newImage);
00535 timeSelector->SetTimeNr( ((QmitkSliderNavigatorWidget*)m_Controls->sliceNavigatorTime)->GetPos() );
00536 timeSelector->Update();
00537 newImage = timeSelector->GetOutput();
00538 }
00539
00540
00541
00542
00543 ImageType::Pointer itkImage = ImageType::New();
00544 VectorImageType::Pointer itkVecImage = VectorImageType::New();
00545
00546 int isVectorImage = newImage->GetPixelType().GetNumberOfComponents();
00547
00548 if(isVectorImage > 1)
00549 {
00550 CastToItkImage( newImage, itkVecImage );
00551 }
00552 else
00553 {
00554 CastToItkImage( newImage, itkImage );
00555 }
00556
00557 std::stringstream nameAddition("");
00558
00559 int param1 = m_Controls->sbParam1->value();
00560 int param2 = m_Controls->sbParam2->value();
00561
00562 try{
00563
00564 switch (m_SelectedAction)
00565 {
00566
00567 case GAUSSIAN:
00568 {
00569 GaussianFilterType::Pointer gaussianFilter = GaussianFilterType::New();
00570 gaussianFilter->SetInput( itkImage );
00571 gaussianFilter->SetVariance( param1 );
00572 gaussianFilter->UpdateLargestPossibleRegion();
00573 newImage = mitk::ImportItkImage(gaussianFilter->GetOutput());
00574 nameAddition << "_Gaussian_var_" << param1;
00575 std::cout << "Gaussian filtering successful." << std::endl;
00576 break;
00577 }
00578
00579 case MEDIAN:
00580 {
00581 MedianFilterType::Pointer medianFilter = MedianFilterType::New();
00582 MedianFilterType::InputSizeType size;
00583 size.Fill(param1);
00584 medianFilter->SetRadius( size );
00585 medianFilter->SetInput(itkImage);
00586 medianFilter->UpdateLargestPossibleRegion();
00587 newImage = mitk::ImportItkImage(medianFilter->GetOutput());
00588 nameAddition << "_Median_radius_" << param1;
00589 std::cout << "Median Filtering successful." << std::endl;
00590 break;
00591 }
00592
00593 case TOTALVARIATION:
00594 {
00595 if(isVectorImage > 1)
00596 {
00597 VectorTotalVariationFilterType::Pointer TVFilter
00598 = VectorTotalVariationFilterType::New();
00599 TVFilter->SetInput( itkVecImage.GetPointer() );
00600 TVFilter->SetNumberIterations(param1);
00601 TVFilter->SetLambda(double(param2)/1000.);
00602 TVFilter->UpdateLargestPossibleRegion();
00603
00604 newImage = mitk::ImportItkImage(TVFilter->GetOutput());
00605 }
00606 else
00607 {
00608 FloatImageType::Pointer fImage = FloatImageType::New();
00609 CastToItkImage( newImage, fImage );
00610 TotalVariationFilterType::Pointer TVFilter
00611 = TotalVariationFilterType::New();
00612 TVFilter->SetInput( fImage.GetPointer() );
00613 TVFilter->SetNumberIterations(param1);
00614 TVFilter->SetLambda(double(param2)/1000.);
00615 TVFilter->UpdateLargestPossibleRegion();
00616
00617 newImage = mitk::ImportItkImage(TVFilter->GetOutput());
00618 }
00619
00620 nameAddition << "_TV_Iter_" << param1 << "_L_" << param2;
00621 std::cout << "Total Variation Filtering successful." << std::endl;
00622 break;
00623 }
00624
00625 case DILATION:
00626 {
00627 BallType binaryBall;
00628 binaryBall.SetRadius( param1 );
00629 binaryBall.CreateStructuringElement();
00630
00631 DilationFilterType::Pointer dilationFilter = DilationFilterType::New();
00632 dilationFilter->SetInput( itkImage );
00633 dilationFilter->SetKernel( binaryBall );
00634 dilationFilter->UpdateLargestPossibleRegion();
00635 newImage = mitk::ImportItkImage(dilationFilter->GetOutput());
00636 nameAddition << "_Dilated_by_" << param1;
00637 std::cout << "Dilation successful." << std::endl;
00638 break;
00639 }
00640
00641 case EROSION:
00642 {
00643 BallType binaryBall;
00644 binaryBall.SetRadius( param1 );
00645 binaryBall.CreateStructuringElement();
00646
00647 ErosionFilterType::Pointer erosionFilter = ErosionFilterType::New();
00648 erosionFilter->SetInput( itkImage );
00649 erosionFilter->SetKernel( binaryBall );
00650 erosionFilter->UpdateLargestPossibleRegion();
00651 newImage = mitk::ImportItkImage(erosionFilter->GetOutput());
00652 nameAddition << "_Eroded_by_" << param1;
00653 std::cout << "Erosion successful." << std::endl;
00654 break;
00655 }
00656
00657 case OPENING:
00658 {
00659 BallType binaryBall;
00660 binaryBall.SetRadius( param1 );
00661 binaryBall.CreateStructuringElement();
00662
00663 OpeningFilterType::Pointer openFilter = OpeningFilterType::New();
00664 openFilter->SetInput( itkImage );
00665 openFilter->SetKernel( binaryBall );
00666 openFilter->UpdateLargestPossibleRegion();
00667 newImage = mitk::ImportItkImage(openFilter->GetOutput());
00668 nameAddition << "_Opened_by_" << param1;
00669 std::cout << "Opening successful." << std::endl;
00670 break;
00671 }
00672
00673 case CLOSING:
00674 {
00675 BallType binaryBall;
00676 binaryBall.SetRadius( param1 );
00677 binaryBall.CreateStructuringElement();
00678
00679 ClosingFilterType::Pointer closeFilter = ClosingFilterType::New();
00680 closeFilter->SetInput( itkImage );
00681 closeFilter->SetKernel( binaryBall );
00682 closeFilter->UpdateLargestPossibleRegion();
00683 newImage = mitk::ImportItkImage(closeFilter->GetOutput());
00684 nameAddition << "_Closed_by_" << param1;
00685 std::cout << "Closing successful." << std::endl;
00686 break;
00687 }
00688
00689 case GRADIENT:
00690 {
00691 GradientFilterType::Pointer gradientFilter = GradientFilterType::New();
00692 gradientFilter->SetInput( itkImage );
00693 gradientFilter->SetSigma( param1 );
00694 gradientFilter->UpdateLargestPossibleRegion();
00695 newImage = mitk::ImportItkImage(gradientFilter->GetOutput());
00696 nameAddition << "_Gradient_sigma_" << param1;
00697 std::cout << "Gradient calculation successful." << std::endl;
00698 break;
00699 }
00700
00701 case LAPLACIAN:
00702 {
00703 FloatImageType::Pointer fImage = FloatImageType::New();
00704 CastToItkImage( newImage, fImage );
00705 LaplacianFilterType::Pointer laplacianFilter = LaplacianFilterType::New();
00706 laplacianFilter->SetInput( fImage );
00707 laplacianFilter->UpdateLargestPossibleRegion();
00708 newImage = mitk::ImportItkImage(laplacianFilter->GetOutput());
00709 nameAddition << "_Second_Derivative";
00710 std::cout << "Laplacian filtering successful." << std::endl;
00711 break;
00712 }
00713
00714 case SOBEL:
00715 {
00716 FloatImageType::Pointer fImage = FloatImageType::New();
00717 CastToItkImage( newImage, fImage );
00718 SobelFilterType::Pointer sobelFilter = SobelFilterType::New();
00719 sobelFilter->SetInput( fImage );
00720 sobelFilter->UpdateLargestPossibleRegion();
00721 newImage = mitk::ImportItkImage(sobelFilter->GetOutput());
00722 nameAddition << "_Sobel";
00723 std::cout << "Edge Detection successful." << std::endl;
00724 break;
00725 }
00726
00727 case THRESHOLD:
00728 {
00729 ThresholdFilterType::Pointer thFilter = ThresholdFilterType::New();
00730 thFilter->SetLowerThreshold(param1 < param2 ? param1 : param2);
00731 thFilter->SetUpperThreshold(param2 > param1 ? param2 : param1);
00732 thFilter->SetInsideValue(1);
00733 thFilter->SetOutsideValue(0);
00734 thFilter->SetInput(itkImage);
00735 thFilter->UpdateLargestPossibleRegion();
00736 newImage = mitk::ImportItkImage(thFilter->GetOutput());
00737 nameAddition << "_Threshold";
00738 std::cout << "Thresholding successful." << std::endl;
00739 break;
00740 }
00741
00742 case INVERSION:
00743 {
00744 InversionFilterType::Pointer invFilter = InversionFilterType::New();
00745 mitk::ScalarType min = newImage->GetScalarValueMin();
00746 mitk::ScalarType max = newImage->GetScalarValueMax();
00747 invFilter->SetMaximum( max + min );
00748 invFilter->SetInput(itkImage);
00749 invFilter->UpdateLargestPossibleRegion();
00750 newImage = mitk::ImportItkImage(invFilter->GetOutput());
00751 nameAddition << "_Inverted";
00752 std::cout << "Image inversion successful." << std::endl;
00753 break;
00754 }
00755
00756 case DOWNSAMPLING:
00757 {
00758 ResampleImageFilterType::Pointer downsampler = ResampleImageFilterType::New();
00759 downsampler->SetInput( itkImage );
00760
00761 typedef itk::NearestNeighborInterpolateImageFunction< ImageType, double > InterpolatorType;
00762 InterpolatorType::Pointer interpolator = InterpolatorType::New();
00763 downsampler->SetInterpolator( interpolator );
00764
00765 downsampler->SetDefaultPixelValue( 0 );
00766
00767 ResampleImageFilterType::SpacingType spacing = itkImage->GetSpacing();
00768 spacing *= (double) param1;
00769 downsampler->SetOutputSpacing( spacing );
00770
00771 downsampler->SetOutputOrigin( itkImage->GetOrigin() );
00772 downsampler->SetOutputDirection( itkImage->GetDirection() );
00773
00774 ResampleImageFilterType::SizeType size = itkImage->GetLargestPossibleRegion().GetSize();
00775 for ( int i = 0; i < 3; ++i )
00776 {
00777 size[i] /= param1;
00778 }
00779 downsampler->SetSize( size );
00780 downsampler->UpdateLargestPossibleRegion();
00781
00782 newImage = mitk::ImportItkImage(downsampler->GetOutput());
00783 nameAddition << "_Downsampled_by_" << param1;
00784 std::cout << "Downsampling successful." << std::endl;
00785 break;
00786 }
00787
00788 default:
00789 this->BusyCursorOff();
00790 return;
00791 }
00792 }
00793 catch (...)
00794 {
00795 this->BusyCursorOff();
00796 QMessageBox::warning(NULL, "Warning", "Problem when applying filter operation. Check your input...");
00797 return;
00798 }
00799
00800 newImage->DisconnectPipeline();
00801
00802
00803 mitk::LevelWindow levelwindow;
00804 levelwindow.SetAuto( newImage );
00805 mitk::LevelWindowProperty::Pointer levWinProp = mitk::LevelWindowProperty::New();
00806 levWinProp->SetLevelWindow( levelwindow );
00807
00808
00809 std::string name = m_SelectedImageNode->GetNode()->GetName();
00810 if (name.find(".pic.gz") == name.size() -7 )
00811 {
00812 name = name.substr(0,name.size() -7);
00813 }
00814 name.append( nameAddition.str() );
00815
00816
00817 mitk::DataNode::Pointer result = mitk::DataNode::New();
00818 result->SetProperty( "levelwindow", levWinProp );
00819 result->SetProperty( "name", mitk::StringProperty::New( name.c_str() ) );
00820 result->SetData( newImage );
00821
00822
00823 if(isVectorImage > 1)
00824 {
00825 mitk::VectorImageMapper2D::Pointer mapper =
00826 mitk::VectorImageMapper2D::New();
00827 result->SetMapper(1,mapper);
00828 }
00829
00830
00831 this->ResetOneImageOpPanel();
00832
00833
00834 GetDefaultDataStorage()->Add( result, m_SelectedImageNode->GetNode() );
00835 if ( m_Controls->cbHideOrig->isChecked() == true )
00836 m_SelectedImageNode->GetNode()->SetProperty( "visible", mitk::BoolProperty::New(false) );
00837
00838
00839
00840 mitk::RenderingManager::GetInstance()->RequestUpdateAll();
00841 this->BusyCursorOff();
00842 }
00843
00844 void QmitkBasicImageProcessing::SelectAction2(int operation)
00845 {
00846
00847 switch (operation)
00848 {
00849 case 2:
00850 m_SelectedOperation = ADD;
00851 break;
00852 case 3:
00853 m_SelectedOperation = SUBTRACT;
00854 break;
00855 case 4:
00856 m_SelectedOperation = MULTIPLY;
00857 break;
00858 case 5:
00859 m_SelectedOperation = DIVIDE;
00860 break;
00861 case 7:
00862 m_SelectedOperation = AND;
00863 break;
00864 case 8:
00865 m_SelectedOperation = OR;
00866 break;
00867 case 9:
00868 m_SelectedOperation = XOR;
00869 break;
00870 default:
00871 this->ResetTwoImageOpPanel();
00872 return;
00873 }
00874 m_Controls->tlImage2->setEnabled(true);
00875 m_Controls->m_ImageSelector2->setEnabled(true);
00876 m_Controls->btnDoIt2->setEnabled(true);
00877 }
00878
00879 void QmitkBasicImageProcessing::StartButton2Clicked()
00880 {
00881 mitk::Image::Pointer newImage1 = dynamic_cast<mitk::Image*>
00882 (m_SelectedImageNode->GetNode()->GetData());
00883 mitk::Image::Pointer newImage2 = dynamic_cast<mitk::Image*>
00884 (m_Controls->m_ImageSelector2->GetSelectedNode()->GetData());
00885
00886
00887 if( (!newImage1) || (!newImage2) || (newImage1->IsInitialized() == false) || (newImage2->IsInitialized() == false) )
00888 {
00889 itkGenericExceptionMacro(<< "At least one of the input images are broken or not initialized. Returning");
00890 return;
00891 }
00892
00893 this->BusyCursorOn();
00894 this->ResetTwoImageOpPanel();
00895
00896
00897 int time = ((QmitkSliderNavigatorWidget*)m_Controls->sliceNavigatorTime)->GetPos();
00898 if(time>=0)
00899 {
00900 mitk::ImageTimeSelector::Pointer timeSelector = mitk::ImageTimeSelector::New();
00901
00902 timeSelector->SetInput(newImage1);
00903 timeSelector->SetTimeNr( time );
00904 timeSelector->UpdateLargestPossibleRegion();
00905 newImage1 = timeSelector->GetOutput();
00906 newImage1->DisconnectPipeline();
00907
00908 timeSelector->SetInput(newImage2);
00909 timeSelector->SetTimeNr( time );
00910 timeSelector->UpdateLargestPossibleRegion();
00911 newImage2 = timeSelector->GetOutput();
00912 newImage2->DisconnectPipeline();
00913 }
00914
00915
00916 this->ResetTwoImageOpPanel();
00917
00918 ImageType::Pointer itkImage1 = ImageType::New();
00919 ImageType::Pointer itkImage2 = ImageType::New();
00920
00921 CastToItkImage( newImage1, itkImage1 );
00922 CastToItkImage( newImage2, itkImage2 );
00923
00924
00925 newImage2 = NULL;
00926
00927 std::string nameAddition = "";
00928
00929 try
00930 {
00931 switch (m_SelectedOperation)
00932 {
00933 case ADD:
00934 {
00935 AddFilterType::Pointer addFilter = AddFilterType::New();
00936 addFilter->SetInput1( itkImage1 );
00937 addFilter->SetInput2( itkImage2 );
00938 addFilter->UpdateLargestPossibleRegion();
00939 newImage1 = mitk::ImportItkImage(addFilter->GetOutput());
00940 nameAddition = "_Added";
00941 }
00942 break;
00943
00944 case SUBTRACT:
00945 {
00946 SubtractFilterType::Pointer subFilter = SubtractFilterType::New();
00947 subFilter->SetInput1( itkImage1 );
00948 subFilter->SetInput2( itkImage2 );
00949 subFilter->UpdateLargestPossibleRegion();
00950 newImage1 = mitk::ImportItkImage(subFilter->GetOutput());
00951 nameAddition = "_Subtracted";
00952 }
00953 break;
00954
00955 case MULTIPLY:
00956 {
00957 MultiplyFilterType::Pointer multFilter = MultiplyFilterType::New();
00958 multFilter->SetInput1( itkImage1 );
00959 multFilter->SetInput2( itkImage2 );
00960 multFilter->UpdateLargestPossibleRegion();
00961 newImage1 = mitk::ImportItkImage(multFilter->GetOutput());
00962 nameAddition = "_Multiplied";
00963 }
00964 break;
00965
00966 case DIVIDE:
00967 {
00968 DivideFilterType::Pointer divFilter = DivideFilterType::New();
00969 divFilter->SetInput1( itkImage1 );
00970 divFilter->SetInput2( itkImage2 );
00971 divFilter->UpdateLargestPossibleRegion();
00972 newImage1 = mitk::ImportItkImage<FloatImageType>(divFilter->GetOutput());
00973 nameAddition = "_Divided";
00974 }
00975 break;
00976
00977 case AND:
00978 {
00979 AndImageFilterType::Pointer andFilter = AndImageFilterType::New();
00980 andFilter->SetInput1( itkImage1 );
00981 andFilter->SetInput2( itkImage2 );
00982 andFilter->UpdateLargestPossibleRegion();
00983 newImage1 = mitk::ImportItkImage(andFilter->GetOutput());
00984 nameAddition = "_AND";
00985 break;
00986 }
00987
00988 case OR:
00989 {
00990 OrImageFilterType::Pointer orFilter = OrImageFilterType::New();
00991 orFilter->SetInput1( itkImage1 );
00992 orFilter->SetInput2( itkImage2 );
00993 orFilter->UpdateLargestPossibleRegion();
00994 newImage1 = mitk::ImportItkImage(orFilter->GetOutput());
00995 nameAddition = "_OR";
00996 break;
00997 }
00998
00999 case XOR:
01000 {
01001 XorImageFilterType::Pointer xorFilter = XorImageFilterType::New();
01002 xorFilter->SetInput1( itkImage1 );
01003 xorFilter->SetInput2( itkImage2 );
01004 xorFilter->UpdateLargestPossibleRegion();
01005 newImage1 = mitk::ImportItkImage(xorFilter->GetOutput());
01006 nameAddition = "_XOR";
01007 break;
01008 }
01009
01010 default:
01011 std::cout << "Something went wrong..." << std::endl;
01012 this->BusyCursorOff();
01013 return;
01014 }
01015 }
01016 catch (...)
01017 {
01018 this->BusyCursorOff();
01019 QMessageBox::warning(NULL, "Warning", "Problem when applying arithmetic operation to two images. Check dimensions of input images.");
01020 return;
01021 }
01022
01023
01024 newImage1->DisconnectPipeline();
01025 itkImage1 = NULL;
01026 itkImage2 = NULL;
01027
01028
01029 mitk::LevelWindow levelwindow;
01030 levelwindow.SetAuto( newImage1 );
01031 mitk::LevelWindowProperty::Pointer levWinProp = mitk::LevelWindowProperty::New();
01032 levWinProp->SetLevelWindow( levelwindow );
01033 std::string name = m_SelectedImageNode->GetNode()->GetName();
01034 if (name.find(".pic.gz") == name.size() -7 )
01035 {
01036 name = name.substr(0,name.size() -7);
01037 }
01038
01039
01040 mitk::DataNode::Pointer result = mitk::DataNode::New();
01041 result->SetProperty( "levelwindow", levWinProp );
01042 result->SetProperty( "name", mitk::StringProperty::New( (name + nameAddition ).c_str() ));
01043 result->SetData( newImage1 );
01044 GetDefaultDataStorage()->Add( result, m_SelectedImageNode->GetNode() );
01045
01046
01047 m_SelectedImageNode->GetNode()->SetProperty( "visible", mitk::BoolProperty::New(false) );
01048 m_Controls->m_ImageSelector2->GetSelectedNode()->SetProperty( "visible", mitk::BoolProperty::New(false) );
01049
01050
01051 mitk::RenderingManager::GetInstance()->RequestUpdateAll();
01052 this->BusyCursorOff();
01053 }
01054