20 #include "milxQtRobustShapeModel.h" 23 #include <vtkPointData.h> 24 #include <vtkFloatArray.h> 25 #include <vtkDoubleArray.h> 26 #include <vtkTensor.h> 27 #include <vtkTensorGlyph.h> 28 #include <vtkSphereSource.h> 29 #include <vtkPolyDataNormals.h> 31 #include <vtkSphericalTransform.h> 32 #include <vnl/vnl_double_3.h> 33 #include <vnl/algo/vnl_scatter_3x3.h> 35 #include <vtkPNGWriter.h> 36 #include <vtkWindowToImageFilter.h> 38 #include <milxQtFile.h> 39 #include <milxQtPlot.h> 71 if(
m_RobustSSM->LoadCompactModel(filename.toStdString().c_str()))
84 size_t n = meshes->GetNumberOfItems();
89 meshes->InitTraversal();
90 for(
size_t j = 0; j < n; j ++)
92 vtkPolyData * shape = meshes->GetNextItem();
94 vtkFloatArray *weights = vtkFloatArray::New();
95 weights->SetNumberOfTuples(shape->GetNumberOfPoints());
96 weights->SetNumberOfComponents(1);
97 weights->FillComponent(0, 1.0);
101 qApp->processEvents();
110 const int n = meshes->GetNumberOfItems();
118 QDialog *casePossibilities =
new QDialog(
this);
119 QComboBox *integerValues =
new QComboBox(
this);
120 QPushButton *okButton =
new QPushButton(
this);
121 okButton->setText(
"Ok");
122 QLabel *lblMessage =
new QLabel(
this);
123 lblMessage->setText(
"Choose Case ID from possibilities.");
124 QFormLayout *formLayout =
new QFormLayout(
this);
125 formLayout->addRow(lblMessage);
126 formLayout->addRow(tr(
"&Select Case ID from first file: "), integerValues);
127 formLayout->addRow(okButton);
128 casePossibilities->setLayout(formLayout);
130 connect(okButton, SIGNAL(clicked(
bool)), casePossibilities, SLOT(accept()));
132 meshes->InitTraversal();
133 for(
int j = 0; j < n; j ++)
135 QFileInfo fi(filenames[j]);
136 QRegExp rx(
"(\\d+)", Qt::CaseSensitive, QRegExp::RegExp2);
141 while ((pos = rx.indexIn(fi.baseName(), pos)) != -1)
144 pos += rx.matchedLength();
148 if(list.size() > 1 && j == 0)
150 printInfo(
"Please choose Case ID from possibilities for first file.");
151 for(
int k = 0; k < list.size(); k ++)
152 integerValues->addItem(list[k]);
154 casePossibilities->exec();
156 index = integerValues->currentIndex();
161 caseID = list[index].toInt();
165 vtkPolyData * shape = meshes->GetNextItem();
167 vtkFloatArray *weights = vtkFloatArray::New();
168 weights->SetNumberOfTuples(shape->GetNumberOfPoints());
169 weights->SetNumberOfComponents(1);
170 weights->FillComponent(0, 1.0);
174 qApp->processEvents();
178 qDebug() <<
"Case IDs: " <<
m_caseIDs << endl;
185 const int n = meshes->GetNumberOfItems();
190 if(!atlasSurface->GetPointData()->GetScalars())
192 printError(
"No Scalars present on atlas surface. Aborting.");
196 vtkFloatArray *atlasWeights = vtkFloatArray::SafeDownCast(atlasSurface->GetPointData()->GetScalars());
203 QDialog *casePossibilities =
new QDialog(
this);
204 QComboBox *integerValues =
new QComboBox(
this);
205 QPushButton *okButton =
new QPushButton(
this);
206 okButton->setText(
"Ok");
207 QLabel *lblMessage =
new QLabel(
this);
208 lblMessage->setText(
"Choose Case ID from possibilities.");
209 QFormLayout *formLayout =
new QFormLayout(
this);
210 formLayout->addRow(lblMessage);
211 formLayout->addRow(tr(
"&Select Case ID from first file: "), integerValues);
212 formLayout->addRow(okButton);
213 casePossibilities->setLayout(formLayout);
215 connect(okButton, SIGNAL(clicked(
bool)), casePossibilities, SLOT(accept()));
225 meshes->InitTraversal();
226 for(
int j = 0; j < n; j ++)
228 QFileInfo fi(filenames[j]);
229 QRegExp rx(
"(\\d+)", Qt::CaseSensitive, QRegExp::RegExp2);
234 while ((pos = rx.indexIn(fi.baseName(), pos)) != -1)
237 pos += rx.matchedLength();
241 if(list.size() > 1 && j == 0)
243 printInfo(
"Please choose Case ID from possibilities for first file.");
244 for(
int k = 0; k < list.size(); k ++)
245 integerValues->addItem(list[k]);
247 casePossibilities->exec();
249 index = integerValues->currentIndex();
254 caseID = list[index].toInt();
258 vtkPolyData * shape = meshes->GetNextItem();
260 vtkFloatArray *weights = vtkFloatArray::New();
261 weights->DeepCopy(atlasWeights);
265 qApp->processEvents();
269 qDebug() <<
"Case IDs: " <<
m_caseIDs << endl;
281 menu->addSeparator()->setText(tr(
"View"));
296 menu->addSeparator()->setText(tr(
"Validation/Output"));
302 menu->addSeparator();
304 alignMenu = menu->addMenu(
"Procrustes Mode");
319 menu->addSeparator();
331 float precision = QInputDialog::getDouble(
this, tr(
"Please Provide the precision of the model"),
332 tr(
"Precision:"), 0.9, 0.0, 1.0, 5, &ok);
343 catch( itk::ExceptionObject & err )
345 printError(
"Exception caught while generating an SSM!");
353 double eigenSum = 0.0;
354 vtkSmartPointer<vtkFloatArray> eigenVals =
m_RobustSSM->GetPCA()->GetEigenValues();
355 printInfo(
"Eigenvalues Info - #tuples: " + QString::number(eigenVals->GetNumberOfTuples()) +
", #components: " + QString::number(eigenVals->GetNumberOfComponents()));
356 for(vtkIdType j = 0; j < eigenVals->GetNumberOfTuples(); j ++)
357 eigenSum += eigenVals->GetValue(j);
358 printInfo(
"Sum of Eigenvalues is " + QString::number(eigenSum));
363 tmpLookupTable->SetTableRange(0.0, n+1);
364 tmpLookupTable->Build();
407 bool flgNormal =
true;
417 int mode = QInputDialog::getInt(
this, tr(
"Please Provide the mode to view (1 to n)"),
418 tr(
"Mode:"), 1, 1,
m_RobustSSM->GetNumberOfModes(), 1, &ok1);
419 float modeWeight = QInputDialog::getDouble(
this, tr(
"Please Provide the weight of the mode"),
420 tr(
"Weight:"), 3.0, -50.0, 50.0, 2, &ok2);
431 msgBox.setText(
"A parameterised surface will be generated");
432 msgBox.setInformativeText(
"Do you want to display this instead of the mean surface?");
433 msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
434 msgBox.setDefaultButton(QMessageBox::No);
435 int ret = msgBox.exec();
442 vtkSmartPointer<vtkPolyData> meanShape =
m_meanModel->GetOutput();
444 meanShape->SetPoints(
m_RobustSSM->GetMeanShape()->GetPoints());
446 vtkSmartPointer<vtkPolyDataNormals> normals = vtkPolyDataNormals::New();
447 normals->SetInput(meanShape);
448 normals->ComputeCellNormalsOff();
449 normals->ComputePointNormalsOn();
450 normals->SplittingOff();
456 vtkSmartPointer<vtkFloatArray> normArray =
457 vtkFloatArray::SafeDownCast(normals->GetOutput()->GetPointData()->GetNormals());
459 vtkSmartPointer<vtkFloatArray> b = vtkFloatArray::New();
460 b->SetNumberOfValues(mode);
461 b->FillComponent(0, 0.0);
462 b->SetValue(mode-1, modeWeight);
463 printInfo(
"Generating display for mode " + QString::number(mode-1));
465 vtkSmartPointer<vtkPolyData> varShape = vtkSmartPointer<vtkPolyData>::New();
466 varShape->DeepCopy(
m_RobustSSM->GetParameterisedShape(b));
468 vtkSmartPointer<vtkFloatArray> varScalars = vtkSmartPointer<vtkFloatArray>::New();
469 varScalars->SetName(
"Variation");
470 vtkSmartPointer<vtkFloatArray> varVectors = vtkSmartPointer<vtkFloatArray>::New();
471 varVectors->SetNumberOfComponents(3);
472 vtkSmartPointer<vtkFloatArray> varShapeVectors = vtkSmartPointer<vtkFloatArray>::New();
473 varShapeVectors->SetNumberOfComponents(3);
474 vtkSmartPointer<vtkFloatArray> varTensors = vtkSmartPointer<vtkFloatArray>::New();
475 varTensors->SetNumberOfComponents(9);
478 for(
int i = 0; i < meanShape->GetNumberOfPoints(); i++)
480 vtkFloatingPointType* meanPoint = meanShape->GetPoint(i);
481 vtkFloatingPointType* varPoint = varShape->GetPoint(i);
483 vtkFloatingPointType xVal = varPoint[0] - meanPoint[0];
484 vtkFloatingPointType yVal = varPoint[1] - meanPoint[1];
485 vtkFloatingPointType zVal = varPoint[2] - meanPoint[2];
487 float normalPoint[3];
488 normArray->GetTupleValue(i, normalPoint);
489 vtkFloatingPointType var;
492 var = xVal*normalPoint[0] + yVal*normalPoint[1] + zVal*normalPoint[2];
497 var = xVal*xVal + yVal*yVal + zVal*zVal;
500 varVectors->InsertNextTuple3(xVal, yVal, zVal);
501 varShapeVectors->InsertNextTuple3(-xVal, -yVal, -zVal);
502 varScalars->InsertNextValue(var);
504 vnl_scatter_3x3<vtkFloatingPointType> C;
505 for(
int j = 0; j <
m_RobustSSM->GetNumberOfShapes(); j++)
507 vtkFloatingPointType point[3];
508 m_RobustSSM->GetPCA()->GetInput(j)->GetPoint(i, point);
510 vnl_double_3 point_vector;
511 point_vector[0] = point[0] - meanPoint[0];
512 point_vector[1] = point[1] - meanPoint[1];
513 point_vector[2] = point[2] - meanPoint[2];
515 C.add_outer_product(point_vector);
520 vtkSmartPointer<vtkTensor> tens = vtkSmartPointer<vtkTensor>::New();
521 tens->SetComponent(0,0, C(0,0));
522 tens->SetComponent(0,1, C(0,1));
523 tens->SetComponent(0,2, C(0,2));
524 tens->SetComponent(1,0, C(1,0));
525 tens->SetComponent(1,1, C(1,1));
526 tens->SetComponent(1,2, C(1,2));
527 tens->SetComponent(2,0, C(2,0));
528 tens->SetComponent(2,1, C(2,1));
529 tens->SetComponent(2,2, C(2,2));
531 varTensors->InsertNextTuple(tens->T);
534 qApp->processEvents();
537 vtkFloatingPointType maxScalar = std::numeric_limits<vtkFloatingPointType>::min();
538 for(
int i = 0; i < varScalars->GetNumberOfTuples(); i++)
540 if(varScalars->GetValue(i) > maxScalar)
541 maxScalar = varScalars->GetValue(i);
543 printInfo(
"Max sigma: " + QString::number(sqrt(maxScalar)) +
"mm.");
544 for(
int i = 0; i < varScalars->GetNumberOfTuples(); i++)
546 vtkFloatingPointType var = varScalars->GetValue(i);
547 varScalars->SetValue(i, var/maxScalar);
550 meanShape->GetPointData()->SetVectors(varVectors);
551 varShape->GetPointData()->SetVectors(varShapeVectors);
552 meanShape->GetPointData()->SetScalars(varScalars);
554 meanShape->GetPointData()->SetTensors(varTensors);
555 varShape->GetPointData()->SetTensors(varTensors);
557 if(ret == QMessageBox::Yes)
577 int mode = QInputDialog::getInt(
this, tr(
"Please Provide the mode to view (1 to n)"),
578 tr(
"Mode:"), 1, 1, n, 1, &ok1);
579 float modeWeight = QInputDialog::getDouble(
this, tr(
"Please Provide the range weight c of the mode (so that -c < x < c)"),
580 tr(
"Weight:"), 3.0, -5.0, 5.0, 2, &ok2);
581 int numberOfSurfaces = QInputDialog::getInt(
this, tr(
"Please Provide the number of surfaces to generate"),
582 tr(
"Number:"), 16, 1, 1e9, 1, &ok3);
586 if(!ok1 || !ok2 || !ok3)
590 float weightValue = -modeWeight;
591 const float weightStep = 2.0*modeWeight/(numberOfSurfaces-1);
593 vtkPolyDataCollection* meshes = vtkPolyDataCollection::New();
594 QStringList surfaceNames;
595 for(
int j = 0; j < numberOfSurfaces; j ++)
597 vtkSmartPointer<vtkFloatArray> b = vtkFloatArray::New();
598 b->SetNumberOfValues(mode);
599 b->FillComponent(0, 0.0);
600 b->SetValue(mode-1, weightValue);
601 printInfo(
"Generating surface for mode " + QString::number(mode-1));
603 vtkPolyData *shape = vtkPolyData::New();
604 shape->DeepCopy(
m_RobustSSM->GetParameterisedShape(b));
606 meshes->AddItem(shape);
607 surfaceNames.append(QString::number(weightStep));
609 weightValue += weightStep;
613 emit collectionAvailable(meshes, surfaceNames);
621 const int n =
m_SSM->GetNumberOfShapes();
622 const int noOfPoints =
m_SSM->GetShape(0)->GetNumberOfPoints();
624 printInfo(
"Generating Correspondences.");
626 vtkSmartPointer<vtkDoubleArray> maxDeviations = vtkSmartPointer<vtkDoubleArray>::New();
627 maxDeviations->SetNumberOfComponents(3);
628 maxDeviations->SetNumberOfTuples(noOfPoints);
629 maxDeviations->SetName(
"Deviations");
632 coordinate origin(0.0);
633 for(
int l = 0; l < noOfPoints; l ++)
634 maxDeviations->SetTupleValue(l, origin.data_block());
636 for(
int j = 0; j < n; j ++)
638 vtkSmartPointer<vtkPolyData> currentShape =
m_SSM->GetProcrustesAlignedSurface(j);
640 for(
int k = 0; k < n; k ++)
645 vtkSmartPointer<vtkPolyData> nextShape =
m_SSM->GetProcrustesAlignedSurface(k);
647 for(
int l = 0; l < noOfPoints; l ++)
649 coordinate currentPoint(currentShape->GetPoint(l));
650 coordinate nextPoint(nextShape->GetPoint(l));
651 coordinate maxVector(maxDeviations->GetTuple(l));
652 coordinate deviation = currentPoint - nextPoint;
654 double length = deviation.squared_magnitude();
655 double currentMaxLength = maxVector.squared_magnitude();
657 if(length > currentMaxLength)
660 maxDeviations->SetTupleValue(l, deviation.data_block());
664 qApp->processEvents();
687 vtkSmartPointer<vtkTable> table = vtkSmartPointer<vtkTable>::New();
688 vtkSmartPointer<vtkFloatArray> values =
m_RobustSSM->GetPCA()->GetEvals();
691 for(
int j = 0; j < 3; j ++)
693 vtkSmartPointer<vtkDoubleArray> column = vtkSmartPointer<vtkDoubleArray>::New();
694 for(
int k = 0; k < values->GetNumberOfTuples(); k ++)
695 column->InsertNextValue(0.0);
696 table->AddColumn(column);
698 printDebug(
"Compactness Table is " + QString::number(table->GetNumberOfRows()) +
"x" + QString::number(table->GetNumberOfColumns()));
701 table->GetColumn(0)->SetName(
"Mode");
702 table->GetColumn(1)->SetName(
"Value");
703 table->GetColumn(2)->SetName(
"Precision");
707 for (
int j = 0; j < values->GetNumberOfTuples(); j++)
708 total += values->GetValue(j);
709 printInfo(
"Total of eigenvalues is " + QString::number(total));
713 for (
int j = 0; j < values->GetNumberOfTuples(); j++)
715 compactness += values->GetValue(j)/total;
717 table->SetValue(j, 0, j+1);
718 table->SetValue(j, 1, values->GetValue(j));
719 table->SetValue(j, 2, compactness);
721 qApp->processEvents();
727 plot->setPlotType2D(0, 2);
728 plot->setName(
"Compactness of the Shape Model");
731 plot->SetSource(table);
732 plot->generatePlot();
746 int n = QInputDialog::getInt(
this, tr(
"Please Provide the number of random shapes to use"),
747 tr(
"Number of Random Shapes:"), 30, 2, 1000000, 1, &ok);
752 vtkSmartPointer<vtkTable> table = vtkSmartPointer<vtkTable>::New();
755 for(
int j = 0; j < 3; j ++)
757 vtkSmartPointer<vtkDoubleArray> column = vtkSmartPointer<vtkDoubleArray>::New();
758 for(
int k = 0; k < n; k ++)
759 column->InsertNextValue(0.0);
760 table->AddColumn(column);
762 printDebug(
"Specificity Table is " + QString::number(table->GetNumberOfRows()) +
"x" + QString::number(table->GetNumberOfColumns()));
765 table->GetColumn(0)->SetName(
"Shape");
766 table->GetColumn(1)->SetName(
"Minimum RMSE");
767 table->GetColumn(2)->SetName(
"Specificity");
771 for(
int i = 0; i < n; i++)
773 vtkSmartPointer<vtkFloatArray> b = vtkSmartPointer<vtkFloatArray>::New();
774 b->SetNumberOfComponents(1);
775 b->SetNumberOfTuples(
m_RobustSSM->GetNumberOfModes());
776 for(
int j = 0; j <
m_RobustSSM->GetNumberOfModes(); j++)
777 b->SetTuple1(j, rand()%35/10 - 1.75);
779 vtkSmartPointer<vtkPolyData> shape =
m_RobustSSM->GetParameterisedShape(b);
780 double minSumSquares = std::numeric_limits<double>::max();
781 for(
int k = 0; k <
m_RobustSSM->GetNumberOfShapes(); k ++)
784 if(value < minSumSquares)
785 minSumSquares = value;
787 specific += minSumSquares;
789 table->SetValue(i, 0, i);
790 table->SetValue(i, 1, minSumSquares);
791 table->SetValue(i, 2, specific);
793 qApp->processEvents();
796 printInfo(
"Specificity Score: " + QString::number(specific));
802 plot->setPlotType2D(0, 1);
803 plot->setName(
"Specificity of the Shape Model");
806 plot->SetSource(table);
807 plot->generatePlot();
818 vtkSmartPointer<vtkTable> table = vtkSmartPointer<vtkTable>::New();
821 for(
int j = 0; j < 2; j ++)
823 vtkSmartPointer<vtkDoubleArray> column = vtkSmartPointer<vtkDoubleArray>::New();
824 for(
int k = 0; k <
m_RobustSSM->GetNumberOfShapes(); k ++)
825 column->InsertNextValue(0.0);
826 table->AddColumn(column);
828 printDebug(
"Generalisability Table is " + QString::number(table->GetNumberOfRows()) +
"x" + QString::number(table->GetNumberOfColumns()));
831 table->GetColumn(0)->SetName(
"Shape");
832 table->GetColumn(1)->SetName(
"Reconstruction Error");
836 for(
int i = 0; i <
m_RobustSSM->GetNumberOfShapes(); i++)
839 vtkPolyData *shape = vtkPolyData::New();
841 vtkFloatArray *weights = vtkFloatArray::New();
846 vtkSmartPointer<vtkFloatArray> b = vtkSmartPointer<vtkFloatArray>::New();
847 b->SetNumberOfComponents(1);
848 b->SetNumberOfTuples(
m_RobustSSM->GetNumberOfModes());
849 b->FillComponent(0, 0.0);
851 vtkSmartPointer<vtkMatrix4x4> matrix = vtkSmartPointer<vtkMatrix4x4>::New();
852 shape->GetPointData()->SetScalars(weights);
853 m_RobustSSM->GetSurfaceSimilarityParameters(shape, weights, matrix, b);
854 vtkSmartPointer<vtkPolyData> shape2 =
m_RobustSSM->GetSurface(matrix, b,
false);
855 double epsiSqr =
m_RobustSSM->PolyDataDistance(shape, shape2)/shape->GetNumberOfPoints();
857 table->SetValue(i, 0, i);
858 table->SetValue(i, 1, epsiSqr);
860 generalisability += epsiSqr;
863 qApp->processEvents();
865 printInfo(
"Generalisability Score: " + QString::number(generalisability));
871 plot->setPlotType2D(0, 1);
872 plot->setName(
"Generalisability of the Shape Model");
875 plot->SetSource(table);
876 plot->generatePlot();
887 vtkSmartPointer<vtkTable> table = vtkSmartPointer<vtkTable>::New();
888 vtkSmartPointer<vtkFloatArray> values =
m_RobustSSM->GetPCA()->GetEvals();
891 for(
int j = 0; j < 3; j ++)
893 vtkSmartPointer<vtkDoubleArray> column = vtkSmartPointer<vtkDoubleArray>::New();
894 for(
int k = 0; k < values->GetNumberOfTuples(); k ++)
895 column->InsertNextValue(0.0);
896 table->AddColumn(column);
898 printDebug(
"Compactness Table is " + QString::number(table->GetNumberOfRows()) +
"x" + QString::number(table->GetNumberOfColumns()));
901 table->GetColumn(0)->SetName(
"Mode");
902 table->GetColumn(1)->SetName(
"Value");
903 table->GetColumn(2)->SetName(
"Precision");
907 for (
int j = 0; j < values->GetNumberOfTuples(); j++)
908 total += values->GetValue(j);
909 printInfo(
"Total of eigenvalues is " + QString::number(total));
913 for (
int j = 0; j < values->GetNumberOfTuples(); j++)
915 compactness += values->GetValue(j)/total;
917 table->SetValue(j, 0, j+1);
918 table->SetValue(j, 1, values->GetValue(j));
919 table->SetValue(j, 2, compactness);
921 qApp->processEvents();
927 plot->setPlotType2D(0, 1);
928 plot->setName(
"Eigenvalues of the Shape Model");
931 plot->SetSource(table);
932 plot->generatePlot();
943 vtkSmartPointer<vtkTable> table = vtkSmartPointer<vtkTable>::New();
946 for(
int j = 0; j <
m_RobustSSM->GetNumberOfModes(); j ++)
948 vtkSmartPointer<vtkDoubleArray> column = vtkSmartPointer<vtkDoubleArray>::New();
949 for(
int k = 0; k <
m_RobustSSM->GetNumberOfShapes(); k ++)
950 column->InsertNextValue(0.0);
951 const QString nameOfColumn =
"Mode " + QString::number(j+1);
952 column->SetName(nameOfColumn.toStdString().c_str());
953 table->AddColumn(column);
955 printDebug(
"Modes Table is " + QString::number(table->GetNumberOfRows()) +
"x" + QString::number(table->GetNumberOfColumns()));
957 for(
int j = 0; j <
m_RobustSSM->GetNumberOfShapes(); j ++)
959 vtkSmartPointer<vtkFloatArray> b = vtkSmartPointer<vtkFloatArray>::New();
960 b->SetNumberOfComponents(1);
961 b->SetNumberOfTuples(
m_RobustSSM->GetNumberOfModes());
963 vtkSmartPointer<vtkMatrix4x4> matrix = vtkSmartPointer<vtkMatrix4x4>::New();
967 for(
int k = 0; k <
m_RobustSSM->GetNumberOfModes(); k ++)
968 table->SetValue(j, k, b->GetValue(k));
970 qApp->processEvents();
974 plot->setPlotType3D(0, 1, 2);
975 plot->setName(
"Specificity of the Shape Model");
978 plot->SetSource(table);
979 plot->generatePlot();
990 vtkSmartPointer<vtkTable> table = vtkSmartPointer<vtkTable>::New();
993 for(
int j = 0; j <
m_RobustSSM->GetNumberOfModes(); j ++)
995 vtkSmartPointer<vtkDoubleArray> column = vtkSmartPointer<vtkDoubleArray>::New();
996 for(
int k = 0; k <
m_RobustSSM->GetNumberOfShapes(); k ++)
997 column->InsertNextValue(0.0);
998 const QString nameOfColumn =
"Mode " + QString::number(j+1);
999 column->SetName(nameOfColumn.toStdString().c_str());
1000 table->AddColumn(column);
1002 printDebug(
"Parameters Table is " + QString::number(table->GetNumberOfRows()) +
"x" + QString::number(table->GetNumberOfColumns()));
1004 for(
int j = 0; j <
m_RobustSSM->GetNumberOfShapes(); j ++)
1006 vtkSmartPointer<vtkFloatArray> b = vtkSmartPointer<vtkFloatArray>::New();
1007 b->SetNumberOfComponents(1);
1008 b->SetNumberOfTuples(
m_RobustSSM->GetNumberOfModes());
1010 vtkSmartPointer<vtkMatrix4x4> matrix = vtkSmartPointer<vtkMatrix4x4>::New();
1014 for(
int k = 0; k <
m_RobustSSM->GetNumberOfModes(); k ++)
1015 table->SetValue(j, k, b->GetValue(k));
1017 qApp->processEvents();
1021 plot->setPlotTypeSurface();
1022 plot->setName(
"Training Shape Parameters of the Shape Model");
1024 plot->legend(
false);
1025 plot->SetSource(table);
1026 plot->generatePlot();
1032 void milxQtRobustShapeModel::reset()
1049 contextMenu->setTitle(QApplication::translate(
"MainWindow",
"Robust Shape Modelling", 0, QApplication::UnicodeUTF8));
1052 actionMean->setText(QApplication::translate(
"SSM",
"&Mean Model", 0, QApplication::UnicodeUTF8));
1057 actionAligned->setText(QApplication::translate(
"SSM",
"&Aligned Points", 0, QApplication::UnicodeUTF8));
1062 actionOriginal->setText(QApplication::translate(
"SSM",
"&Original Points", 0, QApplication::UnicodeUTF8));
1067 actionModesAsVectors->setText(QApplication::translate(
"SSM",
"Modes as &Vectors", 0, QApplication::UnicodeUTF8));
1072 actionModesAsTensors->setText(QApplication::translate(
"SSM",
"Modes as &Tensors", 0, QApplication::UnicodeUTF8));
1077 actionModesAsCollection->setText(QApplication::translate(
"SSM",
"Modes as Surface &Collection", 0, QApplication::UnicodeUTF8));
1080 actionCorrespond->setText(QApplication::translate(
"SSM",
"Correspondences as a &Hedgehog", 0, QApplication::UnicodeUTF8));
1087 actionCompact->setText(QApplication::translate(
"SSM",
"Compactness", 0, QApplication::UnicodeUTF8));
1090 actionSpecificity->setText(QApplication::translate(
"SSM",
"Specificity", 0, QApplication::UnicodeUTF8));
1093 actionGeneralise->setText(QApplication::translate(
"SSM",
"Generalisability", 0, QApplication::UnicodeUTF8));
1096 actionValues->setText(QApplication::translate(
"SSM",
"Eigenvalues", 0, QApplication::UnicodeUTF8));
1099 actionModes->setText(QApplication::translate(
"SSM",
"Primary Eigenmodes", 0, QApplication::UnicodeUTF8));
1102 actionParameters->setText(QApplication::translate(
"SSM",
"Training Shape Parameters", 0, QApplication::UnicodeUTF8));
1107 actionRigid->setText(QApplication::translate(
"SSM",
"Rigid", 0, QApplication::UnicodeUTF8));
1111 actionSimilarity->setText(QApplication::translate(
"SSM",
"Similarity", 0, QApplication::UnicodeUTF8));
1116 actionAffine->setText(QApplication::translate(
"SSM",
"Affine", 0, QApplication::UnicodeUTF8));
1125 actionAlignment->setText(QApplication::translate(
"SSM",
"Output &Alignment as Images", 0, QApplication::UnicodeUTF8));
1128 actionOriginalMeshes->setText(QApplication::translate(
"SSM",
"Output &Original Meshes", 0, QApplication::UnicodeUTF8));
1131 actionAlignedMeshes->setText(QApplication::translate(
"SSM",
"Output &Aligned Meshes", 0, QApplication::UnicodeUTF8));
1134 actionPointIDs->setText(QApplication::translate(
"SSM",
"Output &Point IDs as Images", 0, QApplication::UnicodeUTF8));
1137 actionCoordinates->setText(QApplication::translate(
"SSM",
"Output &Coordinates as Images", 0, QApplication::UnicodeUTF8));
1141 actionReplaceOriginal->setText(QApplication::translate(
"SSM",
"Replace Originals with Aligned", 0, QApplication::UnicodeUTF8));
void LoadModel(const QString filename)
Loads a robust model as an SSM (*.rssm) file. MILX-MSK like call.
virtual void generateMeanModel(vtkSmartPointer< vtkPolyData > shape=NULL)
void printWarning(QString msg)
Warning message wrapper for console.
QPointer< milxQtModel > m_modesVectorModel
Vector Model of the modes.
int defaultView
Default view for data (default is axial)
virtual void SetInputCollection(vtkPolyDataCollection *meshes)
Uses the collection of polydata to create shape model.
QAction * actionGeneralise
generalisibility error plot action
void printError(QString msg)
Error message wrapper for console.
QAction * actionAlignment
alignment check action
QAction * actionCoordinates
coordinates check action
QAction * actionModesAsCollection
modes collection action
QAction * saveViewFileAct
Save camera view to file.
QMenu * viewMenu
Context Menu.
int m_mode
Mode being viewed.
QAction * actionOriginal
original points action
bool m_tensor
Tensors generated?
void AddActor(vtkSmartPointer< vtkProp > actor)
Add a VTK actor to this window.
bool m_alignedShapesModelled
Shapes were generated?
void createActions()
Create the actions for context menu etc.
vtkSmartPointer< vtkLookupTable > lookupTable
Lookup table for the shapes/images, base class is used to allow references to different look up table...
QMenu * plotMenu
Plot menu for SSM analysis.
QAction * actionModesAsTensors
modes action
void eigenmodes()
Plot the primary eigenmodes of the model for each training shape.
QAction * viewZY
Change view to zy-plane (Coronal)
QList< int > m_caseIDs
A list of case IDs corresponding to the models in the SSM.
QAction * actionReplaceOriginal
correspondence check action
void eigenvalues()
Plot the eigenvalues of the model.
QMenu * contextMenu
Context Menu.
QAction * actionSimilarity
similarity Procrustes action
QAction * actionCompact
compactness plot action
QAction * actionAligned
aligned points action
QPointer< milxQtModel > m_modesTensorModel
Tensor Model of the modes.
QActionGroup * alignGroup
Procrustes align gp action.
virtual void generateCollectionBasedOnMode()
bool m_modes
Modes been generated?
void compactness()
Plot the compactness of the SSM.
virtual void generateModes()
QAction * actionOriginalMeshes
original meshes output action
QAction * actionModesAsVectors
modes action
QAction * actionCorrespond
correspondence check action
void createConnections()
Create the connections for context menu etc.
bool m_meaned
Mean generated?
bool m_modelled
SSM Modelled?
QString prefix
Prefix of the data.
void printDebug(QString msg)
Debug message wrapper for console.
QAction * actionAlignedMeshes
alignmed meshes output action
QAction * actionModes
primary modes plot action
void parameters()
Plot the training shape parameters of the model for each training shape (leave 1 out).
This class represents the MILX Qt Model/Mesh Display object using VTK.
QAction * actionRigid
rigid Procrustes action
QPointer< milxQtModel > m_correspondences
Hedgehog display of the correspondences.
The class provides 1D/2D and 3D plotting capability. This includes scatter and surface plots...
virtual void createMenu(QMenu *menu)
Create the menu for the data in this object. Used for context menu and file menus.
QAction * refreshAct
Action for refreshing the display.
void contextMenuEvent(QContextMenuEvent *event)
The context menu setup member.
virtual void generateCorrespondences()
bool m_correspond
Hedgehog generated?
void enableActionBasedOnView()
Enables the view actions corresponding to current view set.
QAction * actionSpecificity
specificity plot action
QAction * resetAct
Action for refreshing the display.
QMenu * colourMapMenu
Colour map menu.
void resultAvailable(milxQtRenderWindow *)
Send signal that Resultant render window is available for showing.
ShapeModelBaseType::Pointer m_SSM
The Statistical Shape Model Base Class.
QAction * saveViewAct
Save camera view.
QMenu * alignMenu
Plot menu for SSM alignment.
QAction * viewXY
Change view to xy-plane (Axial)
virtual ~milxQtRobustShapeModel()
QPointer< milxQtModel > m_meanModel
Model of the mean.
bool m_vector
Vectors generated?
QAction * actionPointIDs
point ids check action
RobustShapeModelType::Pointer m_RobustSSM
The Statistical Shape Model.
QAction * viewZX
Change view to zx-plane (Sagittal)
void done(int value)
Send signal that computation is done. Value carries the progress,.
void specificity()
Plot the specificity of the SSM.
void setupTooltips()
Assign tooltips to each action for users benefit. The tooltips explains the function of each action...
void setView(int viewMode)
Change view to view mode identified by number. 0-axial, 1-coronal, 2-sagittal.
QAction * actionValues
primary modes plot action
QAction * actionMean
mean action
bool m_loaded
Shapes loaded?
milxQtRobustShapeModel(QWidget *theParent=0, bool contextSystem=true)
milxQtConsole * console
Console for log outputs.
void printInfo(QString msg)
Info message wrapper for console.
QAction * actionAffine
affine Procrustes action
void generalisability()
Plot the generalisability of the SSM.
void working(int value)
Send signal that computation is in progress. Value carries the progress,.
virtual void generateSSM()
QMenu * windowPropertiesMenu
Context Menu.
QAction * actionParameters
training shape parameters plot action
QAction * loadViewAct
Load camera view.
bool m_shapesModelled
Shapes were generated?
QAction * loadViewFileAct
Load camera view to file.