Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
QmitkAffineTransformView.cpp
Go to the documentation of this file.
1 /*===================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center,
6 Division of Medical and Biological Informatics.
7 All rights reserved.
8 
9 This software is distributed WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE.
12 
13 See LICENSE.txt or http://www.mitk.org for details.
14 
15 ===================================================================*/
16 
18 #include "mitkImageAccessByItk.h"
19 #include <QValidator>
20 #include <itkAffineTransform.h>
21 #include <itkCenteredTransformInitializer.h>
22 #include <mitkImageCast.h>
23 
24 QmitkAffineTransformView::QmitkAffineTransformView(QWidget *parent, Qt::WindowFlags f)
25  : QmitkRigidRegistrationTransformsGUIBase(parent, f), m_CenterX(0), m_CenterY(0), m_CenterZ(0)
26 {
27 }
28 
30 {
31 }
32 
34 {
36 }
37 
39 {
40  if (m_FixedImage.IsNotNull())
41  {
43  return m_TransformObject;
44  }
45  return nullptr;
46 }
47 
48 template <class TPixelType, class MovingPixelType, unsigned int VImageDimension>
49 itk::Object::Pointer QmitkAffineTransformView::GetTransform2(itk::Image<TPixelType, VImageDimension> *itkImage1,
50  itk::Image<MovingPixelType, VImageDimension> *itkImage2)
51 {
52  typedef typename itk::Image<TPixelType, VImageDimension> FixedImageType;
53  typedef typename itk::Image<MovingPixelType, VImageDimension> MovingImageType;
54 
55  // the fixedImage is the input parameter (fix for Bug #14626)
56  typename FixedImageType::Pointer fixedImage = itkImage1;
57 
58  // // the movingImage type is known, use the ImageToItk filter (fix for Bug #14626)
59  // typename mitk::ImageToItk<MovingImageType>::Pointer movingImageToItk = mitk::ImageToItk<MovingImageType>::New();
60  // movingImageToItk->SetInput(m_MovingImage);
61  // movingImageToItk->Update();
62  typename MovingImageType::Pointer movingImage = itkImage2;
63 
66  transformPointer->SetIdentity();
67  if (m_Controls.m_CenterForInitializerAffine->isChecked())
68  {
69  typedef typename itk::AffineTransform<double, VImageDimension> AffineTransformType;
70  typedef typename itk::CenteredTransformInitializer<AffineTransformType, FixedImageType, MovingImageType>
71  TransformInitializerType;
72  typename TransformInitializerType::Pointer transformInitializer = TransformInitializerType::New();
73  transformInitializer->SetFixedImage(fixedImage);
74  transformInitializer->SetMovingImage(movingImage);
75  transformInitializer->SetTransform(transformPointer);
76  if (m_Controls.m_MomentsAffine->isChecked())
77  {
78  transformInitializer->MomentsOn();
79  }
80  else
81  {
82  transformInitializer->GeometryOn();
83  }
84  transformInitializer->InitializeTransform();
85  }
86  m_CenterX = transformPointer->GetCenter()[0];
87  m_CenterY = transformPointer->GetCenter()[1];
88  m_CenterZ = transformPointer->GetCenter()[2];
89  m_TransformObject = transformPointer.GetPointer();
90  return transformPointer.GetPointer();
91 }
92 
94 {
95  itk::Array<double> transformValues;
96  transformValues.SetSize(15);
97  transformValues.fill(0);
98  transformValues[0] = m_Controls.m_UseOptimizerScalesAffine->isChecked();
99  transformValues[1] = m_Controls.m_ScalesAffineTransformScale1->text().toDouble();
100  transformValues[2] = m_Controls.m_ScalesAffineTransformScale2->text().toDouble();
101  transformValues[3] = m_Controls.m_ScalesAffineTransformScale3->text().toDouble();
102  transformValues[4] = m_Controls.m_ScalesAffineTransformScale4->text().toDouble();
103  transformValues[5] = m_Controls.m_ScalesAffineTransformScale5->text().toDouble();
104  transformValues[6] = m_Controls.m_ScalesAffineTransformScale6->text().toDouble();
105  transformValues[7] = m_Controls.m_ScalesAffineTransformScale7->text().toDouble();
106  transformValues[8] = m_Controls.m_ScalesAffineTransformScale8->text().toDouble();
107  transformValues[9] = m_Controls.m_ScalesAffineTransformScale9->text().toDouble();
108  transformValues[10] = m_Controls.m_ScalesAffineTransformScaleTranslationX->text().toDouble();
109  transformValues[11] = m_Controls.m_ScalesAffineTransformScaleTranslationY->text().toDouble();
110  transformValues[12] = m_Controls.m_ScalesAffineTransformScaleTranslationZ->text().toDouble();
111  transformValues[13] = m_Controls.m_CenterForInitializerAffine->isChecked();
112  transformValues[14] = m_Controls.m_MomentsAffine->isChecked();
113  return transformValues;
114 }
115 
116 void QmitkAffineTransformView::SetTransformParameters(itk::Array<double> transformValues)
117 {
118  m_Controls.m_UseOptimizerScalesAffine->setChecked(transformValues[0]);
119  m_Controls.m_ScalesAffineTransformScale1->setText(QString::number(transformValues[1]));
120  m_Controls.m_ScalesAffineTransformScale2->setText(QString::number(transformValues[2]));
121  m_Controls.m_ScalesAffineTransformScale3->setText(QString::number(transformValues[3]));
122  m_Controls.m_ScalesAffineTransformScale4->setText(QString::number(transformValues[4]));
123  m_Controls.m_ScalesAffineTransformScale5->setText(QString::number(transformValues[5]));
124  m_Controls.m_ScalesAffineTransformScale6->setText(QString::number(transformValues[6]));
125  m_Controls.m_ScalesAffineTransformScale7->setText(QString::number(transformValues[7]));
126  m_Controls.m_ScalesAffineTransformScale8->setText(QString::number(transformValues[8]));
127  m_Controls.m_ScalesAffineTransformScale9->setText(QString::number(transformValues[9]));
128  m_Controls.m_ScalesAffineTransformScaleTranslationX->setText(QString::number(transformValues[10]));
129  m_Controls.m_ScalesAffineTransformScaleTranslationY->setText(QString::number(transformValues[11]));
130  m_Controls.m_ScalesAffineTransformScaleTranslationZ->setText(QString::number(transformValues[12]));
131  m_Controls.m_CenterForInitializerAffine->setChecked(transformValues[13]);
132  m_Controls.m_MomentsAffine->setChecked(transformValues[14]);
133  m_Controls.m_GeometryAffine->setChecked(!transformValues[14]);
134 }
135 
137 {
138  return "Affine";
139 }
140 
142 {
143  m_Controls.setupUi(parent);
144  QValidator *validatorLineEditInputFloat = new QDoubleValidator(0, 20000000, 8, this);
145  m_Controls.m_ScalesAffineTransformScale1->setValidator(validatorLineEditInputFloat);
146  m_Controls.m_ScalesAffineTransformScale2->setValidator(validatorLineEditInputFloat);
147  m_Controls.m_ScalesAffineTransformScale3->setValidator(validatorLineEditInputFloat);
148  m_Controls.m_ScalesAffineTransformScale4->setValidator(validatorLineEditInputFloat);
149  m_Controls.m_ScalesAffineTransformScale5->setValidator(validatorLineEditInputFloat);
150  m_Controls.m_ScalesAffineTransformScale6->setValidator(validatorLineEditInputFloat);
151  m_Controls.m_ScalesAffineTransformScale7->setValidator(validatorLineEditInputFloat);
152  m_Controls.m_ScalesAffineTransformScale8->setValidator(validatorLineEditInputFloat);
153  m_Controls.m_ScalesAffineTransformScale9->setValidator(validatorLineEditInputFloat);
154  m_Controls.m_ScalesAffineTransformScaleTranslationX->setValidator(validatorLineEditInputFloat);
155  m_Controls.m_ScalesAffineTransformScaleTranslationY->setValidator(validatorLineEditInputFloat);
156  m_Controls.m_ScalesAffineTransformScaleTranslationZ->setValidator(validatorLineEditInputFloat);
157 }
158 
160 {
161  itk::Array<double> scales;
162  scales.SetSize(12);
163  scales.Fill(1.0);
164  scales[0] = m_Controls.m_ScalesAffineTransformScale1->text().toDouble();
165  scales[1] = m_Controls.m_ScalesAffineTransformScale2->text().toDouble();
166  scales[2] = m_Controls.m_ScalesAffineTransformScale3->text().toDouble();
167  scales[3] = m_Controls.m_ScalesAffineTransformScale4->text().toDouble();
168  scales[4] = m_Controls.m_ScalesAffineTransformScale5->text().toDouble();
169  scales[5] = m_Controls.m_ScalesAffineTransformScale6->text().toDouble();
170  scales[6] = m_Controls.m_ScalesAffineTransformScale7->text().toDouble();
171  scales[7] = m_Controls.m_ScalesAffineTransformScale8->text().toDouble();
172  scales[8] = m_Controls.m_ScalesAffineTransformScale9->text().toDouble();
173  scales[9] = m_Controls.m_ScalesAffineTransformScaleTranslationX->text().toDouble();
174  scales[10] = m_Controls.m_ScalesAffineTransformScaleTranslationY->text().toDouble();
175  scales[11] = m_Controls.m_ScalesAffineTransformScaleTranslationZ->text().toDouble();
176  return scales;
177 }
178 
179 vtkTransform *QmitkAffineTransformView::Transform(vtkMatrix4x4 *vtkmatrix,
180  vtkTransform *vtktransform,
181  itk::Array<double> transformParams)
182 {
183  if (m_MovingImage.IsNotNull())
184  {
185  // - the 9 rotation-coefficients are copied
186  // directly to the top left part of the matrix
187  int m = 0;
188  for (unsigned int i = 0; i < m_FixedImage->GetDimension(); i++)
189  {
190  for (unsigned int j = 0; j < m_FixedImage->GetDimension(); j++)
191  {
192  vtkmatrix->SetElement(i, j, transformParams[m]);
193  m++;
194  }
195  }
196 
197  // - the 3 translation-coefficients are corrected to take
198  // into account the center of the transformation
199  float center[4];
200  center[0] = m_CenterX;
201  center[1] = m_CenterY;
202  center[2] = m_CenterZ;
203  center[3] = 1;
204  std::cout << "rotation center: " << center[0] << " " << center[1] << " " << center[2] << std::endl;
205 
206  float translation[4];
207  vtkmatrix->MultiplyPoint(center, translation);
208  if (m_FixedImage->GetDimension() == 2)
209  {
210  vtkmatrix->SetElement(0, 3, -translation[0] + center[0] + transformParams[4]);
211  vtkmatrix->SetElement(1, 3, -translation[1] + center[1] + transformParams[5]);
212  }
213  else if (m_FixedImage->GetDimension() == 3)
214  {
215  vtkmatrix->SetElement(0, 3, -translation[0] + center[0] + transformParams[9]);
216  vtkmatrix->SetElement(1, 3, -translation[1] + center[1] + transformParams[10]);
217  vtkmatrix->SetElement(2, 3, -translation[2] + center[2] + transformParams[11]);
218  }
219 
220  // set the transform matrix to init the transform
221  vtktransform->SetMatrix(vtkmatrix);
222  }
223  return vtktransform;
224 }
225 
227 {
228  if (m_FixedImage.IsNotNull())
229  {
230  if (m_FixedImage->GetDimension() == 2)
231  {
232  m_Controls.m_ScalesAffineTransformScale7->hide();
233  m_Controls.m_ScalesAffineTransformScale8->hide();
234  m_Controls.m_ScalesAffineTransformScale9->hide();
235  m_Controls.m_ScalesAffineTransformScaleTranslationX->hide();
236  m_Controls.m_ScalesAffineTransformScaleTranslationY->hide();
237  m_Controls.m_ScalesAffineTransformScaleTranslationZ->hide();
238  m_Controls.textLabel2_7->setText("Translation Scale X:");
239  m_Controls.textLabel3_6->setText("Translation Scale Y:");
240  m_Controls.textLabel4_4->hide();
241  m_Controls.textLabel5_4->hide();
242  m_Controls.textLabel6_4->hide();
243  m_Controls.textLabel11_3->hide();
244  m_Controls.textLabel12_3->hide();
245  m_Controls.textLabel13_2->hide();
246  return 6;
247  }
248  else
249  {
250  m_Controls.m_ScalesAffineTransformScale7->show();
251  m_Controls.m_ScalesAffineTransformScale8->show();
252  m_Controls.m_ScalesAffineTransformScale9->show();
253  m_Controls.m_ScalesAffineTransformScaleTranslationX->show();
254  m_Controls.m_ScalesAffineTransformScaleTranslationY->show();
255  m_Controls.m_ScalesAffineTransformScaleTranslationZ->show();
256  m_Controls.textLabel2_7->setText("Scale 5:");
257  m_Controls.textLabel3_6->setText("Scale 6:");
258  m_Controls.textLabel4_4->show();
259  m_Controls.textLabel5_4->show();
260  m_Controls.textLabel6_4->show();
261  m_Controls.textLabel11_3->show();
262  m_Controls.textLabel12_3->show();
263  m_Controls.textLabel13_2->show();
264  return 12;
265  }
266  }
267  else
268  return 0;
269 }
itk::SmartPointer< Self > Pointer
QmitkAffineTransformView(QWidget *parent=nullptr, Qt::WindowFlags f=nullptr)
virtual itk::Array< double > GetScales() override
virtual itk::Array< double > GetTransformParameters() override
TransformType
Unique integer value for every transform.
Ui::QmitkAffineTransformControls m_Controls
virtual void SetupUI(QWidget *parent) override
virtual int GetNumberOfTransformParameters() override
virtual mitk::TransformParameters::TransformType GetTransformType() override
virtual void SetTransformParameters(itk::Array< double > transformValues) override
virtual vtkTransform * Transform(vtkMatrix4x4 *vtkmatrix, vtkTransform *vtktransform, itk::Array< double > transformParams) override
#define AccessTwoImagesFixedDimensionByItk(mitkImage1, mitkImage2, itkImageTypeFunction, dimension)
Access two mitk-images with known dimension by itk-images.
virtual itk::Object::Pointer GetTransform() override
itk::Object::Pointer m_TransformObject
virtual QString GetName() override
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.