SMILX  1.01
milxQtRegistrationWindow.cpp
1 #include "milxQtRegistrationWindow.h"
2 #include <QCheckBox>
3 #include <QPushButton>
4 #include <QLineEdit>
5 #include <QLabel>
6 #include <QVBoxLayout>
7 #include <QGroupBox>
8 
9 
10 /*
11  Constructor
12 */
13 milxQtRegistrationWindow::milxQtRegistrationWindow(QWidget * theParent) : QDialog(theParent)
14 {
15  MainWindow = qobject_cast<milxQtMain *>(theParent);
18  workInProgress = false;
19  computeAverage = false;
20  openResults = false;
21  initUI();
22  createConnections();
23 
24 #ifdef USE_ELASTIX
25  // This needs to be setup once for elastix to work properly
26  int ret = elx::xoutSetup("", false, false);
27  if (ret)
28  {
29  QMessageBox msgBox(QMessageBox::Critical, "Elastix Initialisation Error", "Error while initializing Elastix logging system. Elastix registration might fail.", QMessageBox::NoButton);
30  msgBox.exec();
31  }
32 #endif
33 }
34 
35 /*
36  Destructor
37 */
39 {
40  // Free the list of images
41  qDeleteAll(images);
42  images.clear();
43 
44  // Free the advanced options window
45  delete(advancedOptionsWindow);
46 
47  // Destroy regAlgos
48  delete(regAlgos);
49 }
50 
51 // Initialise the user interface
53 {
54  // Setup window
55  ui.setupUi(this);
56  setWindowModality(Qt::ApplicationModal);
57  setWindowTitle(tr("Registration option"));
58 
59  // Set up the list of algorithms
60  QStringList algoList;
61  algoList << "Affine (ITK)" << "Demon (ITK)";
62 
63 #ifdef USE_NIFTI_REG
64  algoList << "F3D (Nifti)" << "Aladin (Nifti)";
65 #endif
66 
67 #ifdef USE_ELASTIX
68  algoList << "Affine (Elastix)" << "BSpline (Elastix)";
69 #endif
70 
71  this->ui.comboBoxAlgo->addItems(algoList);
72 
73  // If we don't have nifti we can't compute the atlas and we can't compute the deformation field
74 #ifndef USE_NIFTI_REG
75  this->ui.checkBoxCreateAtlas->setVisible(false);
76  this->ui.checkBoxDeformationF->setVisible(false);
77  this->ui.checkBoxSimilarities->setVisible(false);
78 #endif
79 }
80 
81 // Return the current algorithm selected in the combo box
83 {
84  if (ui.comboBoxAlgo->currentText().compare("Affine (ITK)") == 0) return AffineItk;
85  else if (ui.comboBoxAlgo->currentText().compare("Demon (ITK)") == 0) return DemonItk;
86  else if (ui.comboBoxAlgo->currentText().compare("F3D (Nifti)") == 0) return F3DNifti;
87  else if (ui.comboBoxAlgo->currentText().compare("Aladin (Nifti)") == 0) return AladinNifti;
88  else if (ui.comboBoxAlgo->currentText().compare("Affine (Elastix)") == 0) return ElastixAffine;
89  else if (ui.comboBoxAlgo->currentText().compare("BSpline (Elastix)") == 0) return ElastixBSpline;
90 
91  return None;
92 }
93 
94 // Change the algorithm selected (and change the interface accordingly)
95 void milxQtRegistrationWindow::setAlgo(RegType regType)
96 {
97  // Reset interface
98  // Set the output directory
99  if (this->ui.inputDirectoryBrowser->text() == "")
100  {
101  this->ui.inputDirectoryBrowser->setText(getDefaultOutputFolder());
102  }
103 
104  // Set the current algo selected
105  this->ui.comboBoxAlgo->setCurrentIndex(regType);
106 
107  // With ITK we don't have advanced options (hide the button)
108  if (regType == AffineItk || regType == DemonItk)
109  {
110  this->ui.btnAdvancedOptions->setVisible(false);
111  }
112  else
113  {
114  this->ui.btnAdvancedOptions->setVisible(true);
115  }
116 
117  // By default we don't show the deformation field for Nifti F3D
118  if (regType == F3DNifti)
119  {
120  this->ui.checkBoxDeformationF->setVisible(true);
121  this->ui.checkBoxDeformationF->setEnabled(true);
122  this->ui.checkBoxDeformationF->setChecked(false);
123  }
124  // Otherwise we disable this field
125  else
126  {
127  this->ui.checkBoxDeformationF->setVisible(false);
128  this->ui.checkBoxDeformationF->setEnabled(false);
129  this->ui.checkBoxDeformationF->setChecked(false);
130  }
133 }
134 
135 
136 // Update the list of images in the combolist
138 {
139  // If we have work in progress we don't update the image list until completed
140  if (workInProgress) {
141  return;
142  }
143 
144  // We disconnect the event to avoid calling it while updateing the reference combo-box
145  disconnect(this->ui.comboBoxRef, SIGNAL(currentIndexChanged(int)), this, SLOT(referenceComboChange(int)));
146 
147  // Update the parameters of images before displaying them
148  this->updateParameters();
149 
150  // If we have two images
151  if (images.size() >= 2)
152  {
153  // At least one image should be checked
154  // We search if one image is already checked
155  bool oneImageChecked = false;
156  for (int i = 0; i < images.size(); i++)
157  {
158  if (images[i]->isChecked()) {
159  oneImageChecked = true;
160  break;
161  }
162  }
163 
164  // If no image checked, we check the first available
165  if (oneImageChecked == false)
166  {
167  for (int i = 0; i < images.size(); i++)
168  {
169  if (!images[i]->isRef()) {
170  images[i]->setChecked(true);
171  break;
172  }
173  }
174  }
175  }
176 
177  // Clear the combos
178  this->ui.comboBoxRef->clear();
179  this->ui.listWidget->clear();
180 
181  // Add each image to the list
182  for (int i = 0; i < images.size(); i++)
183  {
184  QString itemName = images[i]->getPath();
185 
186  // Add to the reference combobox
187  this->ui.comboBoxRef->addItem(itemName);
188 
189  // Add to the image list
190  QListWidgetItem* item = new QListWidgetItem(itemName);
191  item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
192 
193  // Is the item checked ?
194  if (images[i]->isChecked()) {
195  item->setCheckState(Qt::Checked);
196  } else {
197  item->setCheckState(Qt::Unchecked);
198  }
199 
200  // Is the item the reference (then disable it)
201  if (images[i]->isRef()) {
202  item->setFlags(item->flags() ^ Qt::ItemIsEnabled);
203  this->ui.comboBoxRef->setCurrentIndex(i);
204  }
205 
206 
207  this->ui.listWidget->addItem(item);
208  }
209 
210 
211  connect(this->ui.comboBoxRef, SIGNAL(currentIndexChanged(int)), this, SLOT(referenceComboChange(int)));
212 }
213 
214 // Update the list of open images that we can use for the registration
216 {
217  QWidgetList windows;
218  windows = MainWindow->getListOfWindows();
219 
221  for (int i = 0; i < MainWindow->getNumberOfWindows(); i ++)
222  {
223  milxQtImage *img = MainWindow->nextImage();
224  // We only handle float images
225  if (img->isFloatingPointImage())
226  {
227  // If the image is not in the list we add the image
228  if (!isImageInList(img->getName()))
229  addImage(new milxQtRegistration(this, img, MainWindow));
230  }
231  }
232 }
233 
234 // Check if the image is in the list
236 {
237  // We look is the image is already in the list
238  bool inlist = false;
239 
240  for (int j = 0; j < images.size(); j++)
241  {
242  if (images[j]->getPath() == path)
243  {
244  inlist = true;
245  break;
246  }
247  }
248  return inlist;
249 }
250 
251 // Disable the user interface
253 {
254  // Disable all the fields
255  this->ui.checkBoxDeformationF->setDisabled(true);
256  this->ui.comboBoxAlgo->setDisabled(true);
257  this->ui.comboBoxRef->setDisabled(true);
258  this->ui.btnOk->setDisabled(true);
259  this->ui.listWidget->setDisabled(true);
260  this->ui.btnAdvancedOptions->setDisabled(true);
261  this->ui.checkBoxCreateAtlas->setDisabled(true);
262  this->ui.checkBoxOpenResults->setDisabled(true);
263  this->ui.btnAddImage->setDisabled(true);
264  this->ui.btnBrowse->setDisabled(true);
265  this->ui.btnSelectAll->setDisabled(true);
266  this->ui.btnUnselectAll->setDisabled(true);
267  this->ui.clearList->setDisabled(true);
268  this->ui.checkBoxSimilarities->setDisabled(true);
269 
270  // Disable checkboxes
271  for (int row = 0; row < this->ui.listWidget->count(); row++)
272  {
273  QListWidgetItem *item = this->ui.listWidget->item(row);
274  item->setFlags(item->flags() ^ Qt::ItemIsEnabled);
275  }
276 }
277 
278 // Enable the user interface
280 {
281  // Disable all the fields
282  this->ui.checkBoxDeformationF->setDisabled(false);
283  this->ui.comboBoxAlgo->setDisabled(false);
284  this->ui.comboBoxRef->setDisabled(false);
285  this->ui.btnOk->setDisabled(false);
286  this->ui.listWidget->setDisabled(false);
287  this->ui.btnAdvancedOptions->setDisabled(false);
288  this->ui.checkBoxCreateAtlas->setDisabled(false);
289  this->ui.checkBoxOpenResults->setDisabled(false);
290  this->ui.btnAddImage->setDisabled(false);
291  this->ui.btnBrowse->setDisabled(false);
292  this->ui.btnSelectAll->setDisabled(false);
293  this->ui.btnUnselectAll->setDisabled(false);
294  this->ui.clearList->setDisabled(false);
295  this->ui.checkBoxSimilarities->setDisabled(false);
296 
297  // Disable checkboxes
298  for (int row = 0; row < this->ui.listWidget->count(); row++)
299  {
300  QListWidgetItem *item = this->ui.listWidget->item(row);
301  item->setFlags(item->flags() ^ Qt::ItemIsEnabled);
302  }
303 
304  setAlgo(this->getCurrentAlgo());
305 }
306 
307 // get the parameters of Itk Affine registration
309 {
311  return params;
312 }
313 
314 
315 // get the parameters of Itk Demon registration
317 {
319  return params;
320 }
321 
322 // get the parameters of Nifti F3D registration
324 {
326  params.cpp2Def = this->ui.checkBoxDeformationF->isChecked();
327  return params;
328 }
329 
330 // get the parameters of a Nifti Aladin registration
332 {
334  return params;
335 }
336 
337 // get the parameters of Elastix Affine registration
339 {
341  return params;
342 }
343 
344 // get the parameters of Elastix BSpline registration
346 {
348  return params;
349 }
350 
352 {
353  QString outputFoldPath;
354 
355  // we try to find the reference image
356  int indexRef;
357  for (indexRef = 0; indexRef < images.size(); indexRef++)
358  {
359  if (images[indexRef]->isRef() == true)
360  {
361  break;
362  }
363  }
364 
365  // If we have images opened
366  // the default path is the reference image path + regoutput
367  if (images.size() != 0)
368  {
369  outputFoldPath = QDir(QFileInfo(images[indexRef]->getPath()).absolutePath() + "/regoutput").absolutePath();
370  }
371  else
372  {
373  // Otherwise If no image are opened
374  // By default it will create a folder on the desktop
375  outputFoldPath = QDir(QDesktopServices::storageLocation(QDesktopServices::DesktopLocation) + "/regoutput").absolutePath();
376  }
377 
378  return outputFoldPath;
379 }
380 
381 // update images parameters
383 {
384  // If no image to update, return
385  if (images.size() == 0) return;
386 
387  // Get the registration type
388  RegType type = this->getCurrentAlgo();
389 
390  // Get the reference image
391  int refIndex = this->ui.comboBoxRef->currentIndex();
392  milxQtRegistration * ref = NULL;
393  if (refIndex >= 0 && refIndex < images.size())
394  {
395  ref = images[refIndex];
396  ref->setIsRef(true);
397  }
398 
399  // If we have to compute similarities
400  bool computeSimilarities = false;
401  if (this->ui.checkBoxSimilarities->isChecked())
402  {
403  computeSimilarities = true;
404  }
405 
406  // Get the output folder
407  QString outFolder = this->ui.inputDirectoryBrowser->text();
408  if (!QDir(outFolder).exists())
409  {
410  outFolder = "";
411  }
412 
413  // Do we need to open the results
414  openResults = this->ui.checkBoxOpenResults->isChecked();
415 
416  // Update the parameters of the registration for each image
417  for (int i = 0; i < this->ui.listWidget->count(); i++)
418  {
419  // We look if the image is checked
420  QListWidgetItem *item = this->ui.listWidget->item(i);
421  if ((item->flags() & Qt::ItemIsEnabled) && item->checkState())
422  {
423  images[i]->setChecked(true);
424  }
425  else
426  {
427  images[i]->setChecked(false);
428  }
429 
430  // We set the reference image
431  images[i]->setReference(ref);
432 
433  // We set the output folder
434  images[i]->setOutputFolder(QDir(outFolder).absolutePath());
435 
436  // We look the type of the registration
437  images[i]->setRegType(type);
438 
439  // We set if we need to open the results of the registration
440  images[i]->setOpenResults(openResults);
441 
442  // We update the parameters of the registration
443  if (type == AffineItk)
444  {
445  images[i]->setParams(getParamsAffineItk());
446  }
447  else if (type == DemonItk)
448  {
449  images[i]->setParams(getParamsDemonItk());
450  }
451  else if (type == AladinNifti)
452  {
453  images[i]->setParams(getParamsAladinNifti());
454  }
455  else if (type == F3DNifti)
456  {
457  images[i]->setParams(getParamsF3DNifti());
458  }
459  else if (type == ElastixAffine)
460  {
461  images[i]->setParams(getParamsElastixAffine());
462  }
463  else if (type == ElastixBSpline)
464  {
465  images[i]->setParams(getParamsElastixBSpline());
466  }
467 
468  // We set if we have to compute the similarities
469  images[i]->setComputeSimilarities(computeSimilarities);
470  }
471 }
472 
473 
474 // Create connections with the user interface
475 void milxQtRegistrationWindow::createConnections()
476 {
477  connect(this->ui.comboBoxRef, SIGNAL(currentIndexChanged(int)), this, SLOT(referenceComboChange(int)));
478  connect(this->ui.comboBoxAlgo, SIGNAL(currentIndexChanged(int)), this, SLOT(algoComboChange(int)));
479  connect(this->ui.btnAdvancedOptions, SIGNAL(clicked()), this, SLOT(advancedOptionsClicked()));
480  connect(this->ui.btnAddImage, SIGNAL(clicked()), this, SLOT(addImageClicked()));
481  connect(this->ui.btnSelectAll, SIGNAL(clicked()), this, SLOT(selectAllClicked()));
482  connect(this->ui.btnUnselectAll, SIGNAL(clicked()), this, SLOT(unselectAllClicked()));
483  connect(this->ui.btnBrowse, SIGNAL(clicked()), this, SLOT(browseBtnClicked()));
484  connect(this->ui.clearList, SIGNAL(clicked()), this, SLOT(clearList()));
485 
486 #ifdef USE_NIFTI_REG
487  connect(this->regAlgos, SIGNAL(averageCompleted()), this, SLOT(averageComputed()));
488 #endif
489 
490  connect(this->regAlgos, SIGNAL(error(QString, QString)), this, SLOT(regError(QString, QString)));
491 }
492 
493 // Add a new image to the list
495 {
496  if (images.size() == 0)
497  {
498  image->setIsRef(true);
499  }
500 
501  images.append(image);
502  connect(image, SIGNAL(done()), this, SLOT(regComplete()));
503  connect(image, SIGNAL(error(QString, QString)), this, SLOT(regError(QString, QString)));
504 }
505 
506 
507 /*
508  SLOTS
509 */
510 
511 // The average (Atlas) has been computed
512 void milxQtRegistrationWindow::averageComputed()
513 {
514  // Do we need to open the results
515  if (openResults)
516  {
517  MainWindow->loadFile(this->atlasPath);
518  }
519 
520  // All the work has been completed
521  workCompleted();
522 }
523 
524 
525 // Button Clear List clicked
526 void milxQtRegistrationWindow::clearList()
527 {
528  // Free the list of images
529  qDeleteAll(images);
530  images.clear();
531 
532  // Update list
533  this->updateImageListCombo();
534 }
535 
536 
537 // Button add image clicked
538 void milxQtRegistrationWindow::addImageClicked()
539 {
540  QFileDialog fileOpener;
541  fileOpener.setFileMode(QFileDialog::ExistingFiles);
542  QStringList filenames = fileOpener.getOpenFileNames(this, "Add File(s)", QString(), "Nifti (*.nii *.nii.gz)");
543 
544  for (int i = 0; i < filenames.size(); i++)
545  {
546  if (!isImageInList(filenames[i]))
547  {
548  addImage(new milxQtRegistration(this, filenames[i], MainWindow));
549  }
550  }
551 
553 
554 }
555 
556 // Button select all clicked
557 void milxQtRegistrationWindow::selectAllClicked()
558 {
559  for (int row = 0; row < this->ui.listWidget->count(); row++)
560  {
561  QListWidgetItem *item = this->ui.listWidget->item(row);
562 
563  if ((item->flags() & Qt::ItemIsEnabled))
564  {
565  item->setCheckState(Qt::Checked);
566  }
567  }
568 }
569 
570 // Button unselect all clicked
571 void milxQtRegistrationWindow::unselectAllClicked()
572 {
573  for (int row = 0; row < this->ui.listWidget->count(); row++)
574  {
575  QListWidgetItem *item = this->ui.listWidget->item(row);
576 
577  if ((item->flags() & Qt::ItemIsEnabled))
578  {
579  item->setCheckState(Qt::Unchecked);
580  }
581  }
582 }
583 
584 // Button browse clicked
585 void milxQtRegistrationWindow::browseBtnClicked()
586 {
587  QFileDialog dialog;
588  dialog.setFileMode(QFileDialog::Directory);
589  dialog.setOption(QFileDialog::ShowDirsOnly);
590  QString folder = dialog.getExistingDirectory(this, tr("Select an output folder"));
591  if (!folder.isEmpty())
592  {
593  this->ui.inputDirectoryBrowser->setText(folder);
594  }
595 }
596 
597 // Advanced option button pushed
598 void milxQtRegistrationWindow::advancedOptionsClicked()
599 {
601  advancedOptionsWindow->show();
602 }
603 
604 
605 // Algo combo box changed
606 void milxQtRegistrationWindow::algoComboChange(int newIndex)
607 {
608  if (newIndex == AffineItk)
609  {
610  setAlgo(AffineItk);
611  }
612  else if (newIndex == DemonItk)
613  {
614  setAlgo(DemonItk);
615  }
616  else if (newIndex == AladinNifti)
617  {
618  setAlgo(AladinNifti);
619  }
620  else if (newIndex == F3DNifti)
621  {
622  setAlgo(F3DNifti);
623  }
624  else if (newIndex == ElastixAffine)
625  {
626  setAlgo(ElastixAffine);
627  }
628  else if (newIndex == ElastixBSpline)
629  {
630  setAlgo(ElastixBSpline);
631  }
632 
633 }
634 
635 // Reference combo box changed
636 void milxQtRegistrationWindow::referenceComboChange(int newIndex)
637 {
638  // Set the current image as reference
639  for (int i = 0; i < images.size(); i++)
640  {
641  images[i]->setIsRef(false);
642 
643  if (i == newIndex)
644  {
645  images[i]->setIsRef(true);
646  }
647  }
648 
649  // We update the image list
651 }
652 
653 // Btn Ok clicked
654 void milxQtRegistrationWindow::accept()
655 {
656  // Check if we have at least two images
657  if (images.size() < 2) {
658  // Message box: Error we need at least two images
659  QMessageBox msgBox(QMessageBox::Critical, "Registration", "Error you need at least two images (a reference and and image to register).", QMessageBox::NoButton);
660  msgBox.exec();
661  return;
662  }
663 
664  // Check if the directory is valid and exist, otherwise we ask to create it
665  QString outputDir = this->ui.inputDirectoryBrowser->text();
666  if (!QFile::exists(outputDir))
667  {
668  // If the directory doesn't exist we ask if we should create it
669  QMessageBox::StandardButton reply;
670  reply = QMessageBox::question(this, "Directory Creation", "The directory \"" + outputDir + "\" doesn't exist, do you want to create it ?", QMessageBox::Yes | QMessageBox::No);
671  if (reply == QMessageBox::Yes)
672  {
673  QDir().mkdir(outputDir);
674  }
675  }
676 
677  // If the directory is invalid and still doesn't exist, error message
678  if (!QDir(outputDir).exists())
679  {
680  QMessageBox msgBox(QMessageBox::Critical, "Registration", "Error the output directory path doesn't exist or is invalid.", QMessageBox::NoButton);
681  msgBox.exec();
682  return;
683  }
684 
685  // Check if we have at least one image checked
686  bool oneImageChecked = false;
687  for (int i = 0; i < images.size(); i++)
688  {
689  if (images[i]->isChecked() == true) {
690  oneImageChecked = true;
691  break;
692  }
693  }
694 
695  if (!oneImageChecked)
696  {
697  // Message box: Error one image must be checked
698  QMessageBox msgBox(QMessageBox::Critical, "Registration", "Error, at least one image should be checked", QMessageBox::NoButton);
699  msgBox.exec();
700  return;
701  }
702 
703  // Update the parameters
704  this->updateParameters();
705 
706  // Disable the form
707  this->disableUI();
708 
709  // Hide the windows
710  this->hide();
711 
712  // Do we have to compute the average of the registered image
713  computeAverage = this->ui.checkBoxCreateAtlas->isChecked();
714 
715  // Perform the registration
716  this->performRegistrations();
717 }
718 
719 // Btn Cancel clicked
720 void milxQtRegistrationWindow::reject()
721 {
722  // Close and hide
723  this->close();
724  this->hide();
725 }
726 
727 // A registration has been completed
728 void milxQtRegistrationWindow::regComplete()
729 {
730  // Perform the next registration
732 }
733 
734 // An error happenned during the registration
735 void milxQtRegistrationWindow::regError(QString functionName, QString errorMsg)
736 {
737  // Show an error message
738  QMessageBox msgBox(QMessageBox::Critical, "Registration error in function " + functionName, errorMsg, QMessageBox::NoButton);
739  msgBox.exec();
740 
741  // If it's the average function, all the work is done
742  if (functionName == "average()" || functionName == "computeAtlas()") {
743  // Remove the atlas file it failed
744  if (QFile::exists(atlasPath))
745  {
746  QFile::remove(atlasPath);
747  }
748 
749  // Work is done
750  workCompleted();
751  }
752 
753  // Perform the next registration
755 }
756 
757 // Perform the next registration
759 {
760  int i;
761 
762  workInProgress = true;
763  int test = images.size();
764  for (i = 0; i < images.size(); i++)
765  {
766  if (images[i]->isChecked())
767  {
768  images[i]->startRegistration();
769  break;
770  }
771  }
772 
773 
774  // If all the registration are done
775  if (i == images.size())
776  {
777 
778 #ifdef USE_NIFTI_REG
779  // If we have to write the similarities
780  if (this->ui.checkBoxSimilarities->isChecked())
781  {
782 
783  writeSimilarities();
784  }
785 #endif
786 
787 
788  // If we have to compute the average
789  if (computeAverage)
790  {
791 #ifdef USE_NIFTI_REG
792  computeAtlas();
793 #endif
794  }
795  else
796  {
797  // The work is completed
798  workCompleted();
799  }
800  }
801 
802 }
803 
804 
805 #ifdef USE_NIFTI_REG
806 
807 // Write the similarities file
808 void milxQtRegistrationWindow::writeSimilarities()
809 {
810  // Find the reference images
811  int indexRef = 0;
812  for (indexRef = 0; indexRef < images.size(); indexRef++)
813  {
814  if (images[indexRef]->isRef())
815  {
816  break;
817  }
818  }
819 
820  // Write the similarity file before the registration (i == 0) and after the registration (i == 1)
821  for (int i = 0; i < 2; i++)
822  {
823  // Create the file
824 
825  QString similarityFile;
826 
827  if (i == 0)
828  similarityFile = images[indexRef]->createSimilarityFileBefore();
829  else if (i == 1)
830  similarityFile = images[indexRef]->createSimilarityFileAfter();
831 
832  // Write the CSV
833  QFile file(similarityFile);
834 
835  if (file.open(QIODevice::ReadWrite))
836  {
837  QTextStream stream(&file);
838  // Create the header
839  stream << "Reference;Registered Image;Output Image;Computation Time;NMI;SSD;NCC;LNCC\n";
840 
841  // Loop through the images
842  for (int j = 0; j < images.size(); j++)
843  {
844  if (images[j]->isWorkDone() || images[j]->isChecked())
845  {
846  milxQtSimilarities similarities;
847 
848  if (i == 0)
849  similarities = images[j]->similarities_before;
850  else if (i == 1)
851  similarities = images[j]->similarities_after;
852 
853  // Write results in textfile
854  stream << images[indexRef]->getPath() << ";";
855  stream << images[j]->getPath() << ";";
856  stream << images[j]->getOutputPath() << ";";
857 
858  if (i == 0)
859  stream << "0;";
860  else if (i == 1)
861  stream << images[j]->getDuration() << ";";
862 
863 
864  stream << similarities.nmi << ";";
865  stream << similarities.ssd << ";";
866  stream << similarities.ncc << ";";
867  stream << similarities.lncc;
868  stream << "\n";
869  }
870  }
871 
872  file.close();
873  }
874  }
875 }
876 
877 
878 // compute the average of all the registrations
879 void milxQtRegistrationWindow::computeAtlas()
880 {
881  // Get the list of images and find the reference image
882  QStringList filenames;
883  milxQtRegistration * ref;
884 
885  for (int i = 0; i < images.size(); i++)
886  {
887  if (images[i]->isWorkDone())
888  {
889  filenames.append(images[i]->getOutputPath());
890  }
891 
892  if (images[i]->isRef())
893  {
894  ref = images[i];
895  }
896  }
897 
898  // Create the outputfile for the atlas (the output filename will contain the name of the reference)
899  atlasPath = ref->createAtlasFile();
900  if (atlasPath == "")
901  {
902  regError("computeAtlas()", "Unable to create the atlas file");
903  return;
904  }
905 
906  // Start the computation
907  regAlgos->average_async(atlasPath, filenames);
908 }
909 #endif
910 
911 // everything has been completed
913 {
914  workInProgress = false;
915  this->enableUI();
916 
917  // Message box: registration completed
918  QMessageBox msgBox(QMessageBox::Information, "Registration", "Registration completed !", QMessageBox::NoButton);
919  msgBox.exec();
920 
921  // Reset images
922  for (int i = 0; i < images.size(); i++)
923  {
924  images[i]->reset();
925  }
926 
927  // If the files were not opened in SMILI we open the output folder
928  if (!this->ui.checkBoxOpenResults->isChecked())
929  {
930  QString folder = QDir(this->ui.inputDirectoryBrowser->text()).absolutePath();
931  QDesktopServices::openUrl(QUrl::fromLocalFile(folder));
932  }
933 }
void updateOpenImages()
Update the list of open images in SMILI.
bool isFloatingPointImage()
Returns true if image is a floating point (float) image.
Definition: milxQtImage.h:592
Contain all the values of similarity measurement.
Contain all the informations and functions required to register an image.
bool computeAverage
Do we need to compute the average of the registrations.
QString getDefaultOutputFolder()
Return the default output folder.
void enableUI()
Enable the user interface.
void regError(QString functionName, QString errorMsg)
An error happened during the registration or average function.
milxQtRegistrationParams getParamsDemonItk()
Return the parameters for a Itk Demon registration.
bool workInProgress
Is there any work in progress.
bool isImageInList(QString path)
Is the image already listed in our list of images.
milxQtRegistrationParams getParamsAladinNifti()
Return the parameters for an Nifti Aladin registration.
milxQtRegistrationAlgos * regAlgos
reg algorithm to compute average
void workCompleted()
Everything has been completed.
This class represents the MILX Qt Image Display object using VTK.
Definition: milxQtImage.h:118
void updateImageListCombo()
Update the list of images in the combo box.
milxQtRegistrationParams getParamsAladinNifti()
Get the advanced parameter of a Nifti Aladin registration.
milxQtRegistrationAdvancedOptions * advancedOptionsWindow
Advanced options window.
void updateParameters()
Update images parameters, set the values of the form to images.
RegType getCurrentAlgo()
Return the current algorithm selected in the combo box.
int getNumberOfWindows()
Return the number of windows in the current tab.
Definition: milxQtMain.h:603
void reset(RegType algo)
Reset the advanced form to the algorithm in parameter.
virtual ~milxQtRegistrationWindow()
The standard destructor.
milxQtRegistrationParams getParamsElastixBSpline()
Return the parameters for a Elastix BSpline registration.
void performRegistrations()
Perform the next registration.
This class is the advanced options form for the registration.
QString createAtlasFile()
Create the file for the atlas and return the filepath.
double ncc
Normalized Cross Correlation.
milxQtRegistrationWindow(QWidget *theParent)
The standard constructor.
bool loadFile(const QString &filename)
Opens a file for viewing in the current tab.
Definition: milxQtMain.cpp:529
milxQtRegistrationParams getParamsF3DNifti()
Return the parameters for a Nifti F3D registration.
void setAlgo(RegType regType)
Set the type of algorithm and change the form accordingly (display the correct fields) ...
double ssd
Sum Squared Difference.
milxQtRegistrationParams getParamsElastixAffine()
Get the advanced parameters of an Elastix Affine registration.
milxQtImage * nextImage()
Get the next image opened in the current tab.
QString getName()
Returns the name of the data.
Definition: milxQtWindow.h:67
QWidgetList getListOfWindows()
Get a list of widgets/windows that are in the current tab.
Definition: milxQtMain.h:595
milxQtRegistrationParams getParamsElastixBSpline()
Get the advanced parameters of an Elastix BSpline registration.
double nmi
Normalize mutual information.
milxQtRegistrationParams getParamsElastixAffine()
Return the parameters for a Elastix Affine registration.
milxQtMain * MainWindow
Main window of SMILIX.
double lncc
Localy Normalized Cross Correlation.
void setIsRef(bool)
Set the image as the reference.
void disableUI()
Disable the user interface.
void initialiseWindowTraversal()
Initialise the window iterator to the first window opened.
Definition: milxQtMain.h:629
void addImage(milxQtRegistration *)
Add an image to our list of images.
QString atlasPath
Path to the outputed atlas.
This class represents the MILX Qt Main Window object using Qt.
Definition: milxQtMain.h:85
milxQtRegistrationParams getParamsF3DNifti()
Get the advanced parameter of a Nifti F3D registration.
QList< milxQtRegistration * > images
List of images for the combobox and list of selectable images.
milxQtRegistrationParams getParamsAffineItk()
Return the parameters for a Itk Affine registration.
Ui::dlgRegistrationWindow ui
User interface.
bool openResults
Store if we need to open the results.
void initUI()
The standard constructor.