1 /*=========================================================================
2 Program: vv http://www.creatis.insa-lyon.fr/rio/vv
5 - University of LYON http://www.universite-lyon.fr/
6 - Léon Bérard cancer center http://oncora1.lyon.fnclcc.fr
7 - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
9 This software is distributed WITHOUT ANY WARRANTY; without even
10 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11 PURPOSE. See the copyright notices for more information.
13 It is distributed under dual licence
15 - BSD See included LICENSE.txt file
16 - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
17 ======================================================================-====*/
20 #include "vvToolRigidReg.h"
21 #include "vvImageReader.h"
25 #include <vtkImageData.h>
26 #include <vtkSmartPointer.h>
27 #include <vtkTransform.h>
30 #include "clitkTransformUtilities.h"
33 #include <QMessageBox>
34 #include <QFileDialog>
35 #include <QTextStream>
39 //------------------------------------------------------------------------------
40 // Create the tool and automagically (I like this word) insert it in
41 // the main window menu.
42 ADD_TOOL(vvToolRigidReg);
43 //------------------------------------------------------------------------------
45 //------------------------------------------------------------------------------
46 vvToolRigidReg::vvToolRigidReg(vvMainWindowBase * parent, Qt::WindowFlags f):
47 vvToolWidgetBase(parent, f),
48 vvToolBase<vvToolRigidReg>(parent),
52 Ui_vvToolRigidReg::setupUi(mToolWidget);
54 // qsize.setHeight(470);
55 // qsize.setWidth(850);
56 // mToolWidget->setFixedSize(qsize);
59 // Set how many inputs are needed for this tool
60 // mFilter = new clitk::AffineTransformGenericFilter<args_info_clitkAffineTransform>;
62 // Set how many inputs are needed for this tool
63 AddInputSelector("Select moving image");
64 AddInputSelector("Select fixed image");
66 //------------------------------------------------------------------------------
68 //------------------------------------------------------------------------------
69 vvToolRigidReg::~vvToolRigidReg()
72 //------------------------------------------------------------------------------
74 //------------------------------------------------------------------------------
75 bool vvToolRigidReg::close()
79 return vvToolWidgetBase::close();
81 //------------------------------------------------------------------------------
83 //------------------------------------------------------------------------------
84 void vvToolRigidReg::reject()
86 return vvToolWidgetBase::reject();
88 //------------------------------------------------------------------------------
90 //------------------------------------------------------------------------------
91 void vvToolRigidReg::GetArgsInfoFromGUI()
95 //------------------------------------------------------------------------------
97 //------------------------------------------------------------------------------
98 void vvToolRigidReg::InputIsSelected(std::vector<vvSlicerManager *> & l)
104 UpdateTextEditor(mCurrentSlicerManager->GetImage()->GetTransform()->GetMatrix(),textEdit_2);
106 for(int i =0;i<4;i++)
108 mInitialMatrix[i*4+j]=mCurrentSlicerManager->GetImage()->GetTransform()->GetMatrix()->GetElement(i,j);
110 if(mInput1->GetFileName()==mInput2->GetFileName())
112 QMessageBox::information(this, "Warning","Your Reference and Target Images are the same");
116 mImageSize=mInput1->GetImage()->GetSize();
120 //connect all sigs to slots
121 connect(resetbutton, SIGNAL(pressed()), this, SLOT(ResetTransform()));
122 connect(tab2loadbutton, SIGNAL(pressed()), this, SLOT(AutoRegister()));
124 connect(Xval, SIGNAL(editingFinished()), this, SLOT(SetXvalue()));
125 connect(Yval, SIGNAL(editingFinished()), this, SLOT(SetYvalue()));
126 connect(Zval, SIGNAL(editingFinished()), this, SLOT(SetZvalue()));
128 connect(xtrans_slider, SIGNAL(valueChanged(int)), this, SLOT(UpdateTransform_sliders()));
129 connect(ytrans_slider, SIGNAL(valueChanged(int)), this, SLOT(UpdateTransform_sliders()));
130 connect(ztrans_slider, SIGNAL(valueChanged(int)), this, SLOT(UpdateTransform_sliders()));
133 connect(xrot_slider, SIGNAL(valueChanged(int)), this, SLOT(UpdateTransform_sliders()));
134 connect(yrot_slider, SIGNAL(valueChanged(int)), this, SLOT(UpdateTransform_sliders()));
135 connect(zrot_slider, SIGNAL(valueChanged(int)), this, SLOT(UpdateTransform_sliders()));
137 connect(xtrans_sb, SIGNAL(valueChanged(double)), this, SLOT(UpdateTransform_sb()));
138 connect(ytrans_sb, SIGNAL(valueChanged(double)), this, SLOT(UpdateTransform_sb()));
139 connect(ztrans_sb, SIGNAL(valueChanged(double)), this, SLOT(UpdateTransform_sb()));
140 connect(xrot_sb, SIGNAL(valueChanged(double)), this, SLOT(UpdateTransform_sb()));
141 connect(yrot_sb, SIGNAL(valueChanged(double)), this, SLOT(UpdateTransform_sb()));
142 connect(zrot_sb, SIGNAL(valueChanged(double)), this, SLOT(UpdateTransform_sb()));
144 connect(loadbutton, SIGNAL(pressed()), this, SLOT(ReadFile()));
145 connect(savebutton, SIGNAL(pressed()), this, SLOT(SaveFile()));
148 //------------------------------------------------------------------------------
150 //------------------------------------------------------------------------------
151 void vvToolRigidReg::apply()
155 //------------------------------------------------------------------------------
157 //------------------------------------------------------------------------------
158 void vvToolRigidReg::SetOverlay()
160 for (int i =0; i<mCurrentSlicerManager->NumberOfSlicers(); i++) {
161 mCurrentSlicerManager->GetSlicer(i)->SetOverlay(mInput2->GetImage());
162 mCurrentSlicerManager->GetSlicer(i)->SetActorVisibility("overlay",0,true);
163 mCurrentSlicerManager->SetColorMap();
164 mCurrentSlicerManager->Render();
167 //------------------------------------------------------------------------------
169 //------------------------------------------------------------------------------
170 void vvToolRigidReg::RemoveOverlay()
172 for(int i=0;i<mCurrentSlicerManager->NumberOfSlicers();i++)
174 mInput1->RemoveActor("overlay",0);
175 mInput1->SetColorMap(0);
180 //------------------------------------------------------------------------------
182 //------------------------------------------------------------------------------
183 void vvToolRigidReg::SetXvalue()
185 QString xstr = Xval->text();
187 //------------------------------------------------------------------------------
189 //------------------------------------------------------------------------------
190 void vvToolRigidReg::SetYvalue()
192 QString ystr = Yval->text();
194 //------------------------------------------------------------------------------
196 //------------------------------------------------------------------------------
197 void vvToolRigidReg::SetZvalue()
199 QString zstr = Zval->text();
201 //------------------------------------------------------------------------------
203 //------------------------------------------------------------------------------
204 void vvToolRigidReg::SetTransform(double tX, double tY, double tZ, double aX, double aY, double aZ,bool update)
206 vtkSmartPointer<vtkTransform> transform = mInput1->GetImage()->GetTransform();
207 transform->PostMultiply();
209 if (aX!=0 || aY!=0 || aZ!=0) {
211 x= Xval->text().toDouble();
212 y= Yval->text().toDouble();
213 z= Zval->text().toDouble();
214 transform->Translate(-x,-y,-z);
215 if (aX!=0) transform->RotateX(aX);
216 if (aY!=0) transform->RotateY(aY);
217 if (aZ!=0) transform->RotateZ(aZ);
218 transform->Translate(x,y,z);
221 if (tX!=0||tY!=0||tZ!=0)
222 transform->Translate(tX*mInput1->GetImage()->GetSpacing()[0],tY*mInput1->GetImage()->GetSpacing()[1],tZ*mInput1->GetImage()->GetSpacing()[2]);
224 //------------------------------------------------------------------------------
226 //------------------------------------------------------------------------------
227 void vvToolRigidReg::SetTransform(vtkMatrix4x4 *matrix)
229 vtkSmartPointer<vtkTransform> transform =mCurrentSlicerManager->GetImage()->GetTransform();
230 for(int i=0; i<4;i++)
232 mCurrentSlicerManager->GetImage()->GetTransform()->GetMatrix()->SetElement(i,j,matrix->GetElement(i,j));
237 //------------------------------------------------------------------------------
239 //------------------------------------------------------------------------------
240 void vvToolRigidReg::Render()
242 for (int i=0; i<mCurrentSlicerManager->NumberOfSlicers(); i++) {
243 mCurrentSlicerManager->GetSlicer(i)->ForceUpdateDisplayExtent();
244 mCurrentSlicerManager->GetSlicer(i)->Render();
247 //------------------------------------------------------------------------------
249 //------------------------------------------------------------------------------
250 void vvToolRigidReg::UpdateTextEditor(vtkMatrix4x4 *matrix,QTextEdit* textEdit)
252 QFont font=QFont("Times New Roman",11);
253 textEdit->setCurrentFont(font);
256 QString str1,str2,str3;
259 textEdit->setAcceptRichText(true);
260 str2=textEdit->toPlainText();
261 str2.append("#Rotation Center(mm): \n#");
262 textEdit->setText(str2);
264 str2=textEdit->toPlainText();
265 textEdit->setTextColor(QColor(255,0,0));
266 str2.append(str3.append(Xval->text()));
267 textEdit->setText(str2);
270 str2=textEdit->toPlainText();
272 textEdit->setText(str2);
274 str2=textEdit->toPlainText();
275 str2.append(str3.append(Yval->text()));
276 textEdit->setText(str2);
279 str2=textEdit->toPlainText();
281 textEdit->setText(str2);
284 str2=textEdit->toPlainText();
285 str2.append(str3.append(Zval->text()));
286 textEdit->setText(str2);
289 str2=textEdit->toPlainText();
291 textEdit->setText(str2);
294 str2=textEdit->toPlainText();
295 str2.append("#Transformation Matrix(mm):\n");
296 textEdit->setText(str2);
301 str2=textEdit->toPlainText();
302 // str2.append("\t"+str1.setNum(matrix->Element[i][j]));
303 str2.append(QString("%1\t").arg(str1.setNum(matrix->Element[i][j]),2));
304 textEdit->setText(str2);
306 str2=textEdit->toPlainText();
308 textEdit->setText(str2);
310 //QString str = QFileDialog::getOpenFileName();
311 textEdit->setTextColor(QColor(255,0,0));
312 textEdit->setFont(QFont("courrier new",12,4,true));
313 textEdit->toPlainText().toAscii();
315 str2=textEdit->toPlainText();
316 textEdit->setText(str2);
318 //------------------------------------------------------------------------------
320 //------------------------------------------------------------------------------
321 void vvToolRigidReg::UpdateTransform_sliders()
323 InitializeSliders(xtrans_slider->value()*mInput1->GetImage()->GetSpacing()[0],
324 ytrans_slider->value()*mInput1->GetImage()->GetSpacing()[1],
325 ztrans_slider->value()*mInput1->GetImage()->GetSpacing()[2],
326 xrot_slider->value(),yrot_slider->value(),zrot_slider->value(),false);
327 UpdateTransform(true);
330 //------------------------------------------------------------------------------
332 //------------------------------------------------------------------------------
333 void vvToolRigidReg::UpdateTransform_sb()
335 InitializeSliders(xtrans_sb->value(),
338 xrot_sb->value(),yrot_sb->value(),zrot_sb->value(),false);
339 UpdateTransform(false);
342 //------------------------------------------------------------------------------
344 //------------------------------------------------------------------------------
345 void vvToolRigidReg::AutoRegister()
347 GetArgsInfoFromGUI();
348 //clitk::AffineRegistrationGenericFilter::Pointer filter =
349 // clitk::AffineRegistrationGenericFilter::New();
350 //filter->SetArgsInfo(mArgsInfo);
354 //------------------------------------------------------------------------------
356 //------------------------------------------------------------------------------
357 void vvToolRigidReg::UpdateTransform(bool slider_enabled)
359 vtkSmartPointer<vtkTransform> transform_final=vtkSmartPointer<vtkTransform>::New();
360 transform_final->SetMatrix(mInitialMatrix);
361 transform_final->PostMultiply();
363 double x=0, y=0 ,z=0;
364 x= Xval->text().toDouble();
365 y= Yval->text().toDouble();
366 z= Zval->text().toDouble();
367 transform_final->Translate(-x,-y,-z);
369 transform_final->RotateY(yrot_slider->value());
370 transform_final->RotateX(xrot_slider->value());
371 transform_final->RotateZ(zrot_slider->value());
374 transform_final->RotateY(yrot_sb->value());
375 transform_final->RotateX(xrot_sb->value());
376 transform_final->RotateZ(zrot_sb->value());
378 transform_final->Translate(x,y,z);
379 transform_final->PreMultiply();
381 transform_final->Translate(xtrans_slider->value()*mInput1->GetImage()->GetSpacing()[0],0,0);
382 transform_final->Translate(0,ytrans_slider->value()*mInput1->GetImage()->GetSpacing()[1],0);
383 transform_final->Translate(0,0,ztrans_slider->value()*mInput1->GetImage()->GetSpacing()[2]);
386 transform_final->Translate(xtrans_sb->value(),0,0);
387 transform_final->Translate(0,ytrans_sb->value(),0);
388 transform_final->Translate(0,0,ztrans_sb->value());
390 SetTransform(transform_final->GetMatrix());
391 UpdateTextEditor(transform_final->GetMatrix(),textEdit);
393 //------------------------------------------------------------------------------
396 //------------------------------------------------------------------------------
397 void vvToolRigidReg::SaveFile()
399 //Write the Transformation Matrix
400 QString f1 = QFileDialog::getSaveFileName(this, tr("Save Transformation Matrix File"),
401 mMainWindow->GetInputPathName(),
402 tr("Text (*.mat *.txt *.doc *.rtf)"));
404 std::vector<QString> transparameters;
407 for(int i =0;i<4;i++)
409 transparameters.push_back(line1.setNum(mCurrentSlicerManager->GetImage()->GetTransform()->GetMatrix()->Element[i][j]));
411 if (file1.open(QFile::WriteOnly | QFile::Truncate)) {
412 QTextStream out1(&file1);
413 for(int i =0;i<4;i++){
414 for(int j=0;j<4;j++) {
415 out1<<transparameters[i*4+j]+"\t";
422 QMessageBox::information(this,"Warning","Error Reading Parameters");
425 //------------------------------------------------------------------------------
427 //------------------------------------------------------------------------------
428 void vvToolRigidReg::ReadFile()
432 double * orientations=new double[3];
433 double * translations=new double[3];
434 vtkMatrix4x4 *matrix=vtkMatrix4x4::New();
435 vtkSmartPointer<vtkTransform> transform = mCurrentSlicerManager->GetImage()->GetTransform();
437 //Open File to read the transformation parameters
438 QString file1 = QFileDialog::getOpenFileName(
440 "Choose the Transformation Parameters file",
441 mMainWindow->GetInputPathName(),
442 "Text (*.mat *.txt *.rtf *.doc)");
446 // ifstream readfile;
447 std::string transfile= file1.toStdString();
448 std::string filename1(transfile);
449 std::ifstream f1(filename1.c_str());
453 itk::Matrix<double, 4, 4> itkMat = clitk::ReadMatrix3D(transfile);
454 for(int j=0; j<4; j++)
455 for(int i=0; i<4; i++)
456 matrix->SetElement(i,j,itkMat[i][j]);
458 UpdateTextEditor(matrix,textEdit);
459 transform->SetMatrix(matrix);
460 transform->GetOrientation(orientations);
461 transform->PostMultiply();
463 //Obtain the Rotation Center , set it to origin
464 Xval->setText(center.setNum(0));
465 Yval->setText(center.setNum(0));
466 Zval->setText(center.setNum(0));
468 //In the Order or Y X Z //
469 //now postmultiply for the rotations
470 SetTransform(0,0,0,0,0,-rint(orientations[2]),false);
471 SetTransform(0,0,0,-rint(orientations[0]),0,0,false);
472 SetTransform(0,0,0,0,-rint(orientations[1]),0,false);
474 transform->GetPosition(translations);
475 transform->Identity();
477 DD(translations[0]/mInput1->GetImage()->GetSpacing()[0]);
478 DD(translations[1]/mInput1->GetImage()->GetSpacing()[1]);
479 DD(translations[2]/mInput1->GetImage()->GetSpacing()[2]);
483 //set the sliders and spin box values
484 InitializeSliders(rint(translations[0]),rint(translations[1])
485 ,rint(translations[2]),rint(orientations[0]),rint(orientations[1]),rint(orientations[2]),true);
486 SetTransform(matrix);
488 //------------------------------------------------------------------------------
490 //------------------------------------------------------------------------------
491 void vvToolRigidReg::ResetTransform()
493 vtkMatrix4x4 *matrix = vtkMatrix4x4::New();
496 matrix->SetElement(i,j,mInitialMatrix[i*4+j]);
497 SetTransform(matrix);
500 UpdateTextEditor(matrix,textEdit);
502 //------------------------------------------------------------------------------
504 //------------------------------------------------------------------------------
505 void vvToolRigidReg::SetRotationCenter()
507 //default image rotation center is the center of the image
508 QString xcord,ycord,zcord;
509 std::vector<double> imageorigin;
510 imageorigin=mInput1->GetImage()->GetOrigin();
512 xcord=xcord.setNum(imageorigin[0]+mImageSize[0]*mInput1->GetImage()->GetSpacing()[0]/2, 'g', 3);
513 ycord=ycord.setNum(imageorigin[1]+mImageSize[1]*mInput1->GetImage()->GetSpacing()[1]/2, 'g', 3);
514 zcord=zcord.setNum(imageorigin[2]+mImageSize[2]*mInput1->GetImage()->GetSpacing()[2]/2, 'g', 3);
516 Xval->setText(xcord);
517 Yval->setText(ycord);
518 Zval->setText(zcord);
519 InitializeSliders(0,0,0,0,0,0,true);
521 //------------------------------------------------------------------------------
523 //------------------------------------------------------------------------------
524 void vvToolRigidReg::InitializeSliders(double xtrans,double ytrans, double ztrans, double xrot, double yrot, double zrot,bool sliders)
527 xtrans_sb->blockSignals(true);
528 xtrans_sb->setSingleStep(mInput1->GetImage()->GetSpacing()[0]);
529 xtrans_sb->setValue(xtrans);
530 xtrans_sb->blockSignals(false);
531 ytrans_sb->blockSignals(true);
532 ytrans_sb->setSingleStep(mInput1->GetImage()->GetSpacing()[1]);
533 ytrans_sb->setValue(ytrans);
534 ytrans_sb->blockSignals(false);
535 ztrans_sb->blockSignals(true);
536 ztrans_sb->setSingleStep(mInput1->GetImage()->GetSpacing()[2]);
537 ztrans_sb->setValue(ztrans);
538 ztrans_sb->blockSignals(false);
541 xtrans_slider->blockSignals(true);
542 DD(xtrans_slider->value());
543 xtrans_slider->setValue(rint(xtrans));
544 xtrans_slider->blockSignals(false);
545 ytrans_slider->blockSignals(true);
546 ytrans_slider->setValue(rint(ytrans));
547 ytrans_slider->blockSignals(false);
548 ztrans_slider->blockSignals(true);
549 ztrans_slider->setValue(rint(ztrans));
550 ztrans_slider->blockSignals(false);
552 xrot_sb->blockSignals(true);
553 xrot_sb->setValue(xrot);
554 xrot_sb->blockSignals(false);
555 yrot_sb->blockSignals(true);
556 yrot_sb->setValue(yrot);
557 yrot_sb->blockSignals(false);
558 zrot_sb->blockSignals(true);
559 zrot_sb->setValue(zrot);
560 zrot_sb->blockSignals(false);
561 xrot_slider->blockSignals(true);
562 xrot_slider->setValue(xrot);
563 xrot_slider->blockSignals(false);
564 yrot_slider->blockSignals(true);
565 yrot_slider->setValue(yrot);
566 yrot_slider->blockSignals(false);
567 zrot_slider->blockSignals(true);
568 zrot_slider->setValue(zrot);
569 zrot_slider->blockSignals(false);
571 //------------------------------------------------------------------------------
573 //------------------------------------------------------------------------------
574 void vvToolRigidReg::SetSliderRanges()
576 xtrans_slider->blockSignals(true);
577 xtrans_slider->setRange(-2000,2000);
578 xtrans_slider->blockSignals(false);
580 ytrans_slider->blockSignals(true);
581 ytrans_slider->setRange(-2000,2000);
582 ytrans_slider->blockSignals(false);
584 ztrans_slider->blockSignals(true);
585 ztrans_slider->setRange(-2000,2000);
586 ztrans_slider->blockSignals(false);
588 xtrans_sb->blockSignals(true);
589 xtrans_sb->setRange(-2000,2000);
590 xtrans_sb->setDecimals(3);
591 xtrans_sb->blockSignals(false);
593 ytrans_sb->blockSignals(true);
594 ytrans_sb->setRange(-2000,2000);
595 ytrans_sb->setDecimals(3);
596 ytrans_sb->blockSignals(false);
598 ztrans_sb->blockSignals(true);
599 ztrans_sb->setRange(-2000,2000);
600 ztrans_sb->setDecimals(3);
601 ztrans_sb->blockSignals(false);
603 xrot_slider->blockSignals(true);
604 xrot_slider->setRange(-360,360);
605 xrot_slider->blockSignals(false);
607 yrot_slider->blockSignals(true);
608 yrot_slider->setRange(-360,360);
609 yrot_slider->blockSignals(false);
611 zrot_slider->blockSignals(true);
612 zrot_slider->setRange(-360,360);
613 zrot_slider->blockSignals(false);
616 xrot_sb->blockSignals(true);
617 xrot_sb->setRange(-360,360);
618 xrot_sb->blockSignals(false);
620 yrot_sb->blockSignals(true);
621 yrot_sb->setRange(-360,360);
622 yrot_sb->blockSignals(false);
624 zrot_sb->blockSignals(true);
625 zrot_sb->setRange(-360,360);
626 zrot_sb->blockSignals(false);