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 transform->SetMatrix(matrix);
233 //------------------------------------------------------------------------------
235 //------------------------------------------------------------------------------
236 void vvToolRigidReg::Render()
238 for (int i=0; i<mCurrentSlicerManager->NumberOfSlicers(); i++) {
239 mCurrentSlicerManager->GetSlicer(i)->ForceUpdateDisplayExtent();
240 mCurrentSlicerManager->GetSlicer(i)->Render();
243 //------------------------------------------------------------------------------
245 //------------------------------------------------------------------------------
246 void vvToolRigidReg::UpdateTextEditor(vtkMatrix4x4 *matrix,QTextEdit* textEdit)
248 QFont font=QFont("Times New Roman",11);
249 textEdit->setCurrentFont(font);
252 QString str1,str2,str3;
255 textEdit->setAcceptRichText(true);
256 str2=textEdit->toPlainText();
257 str2.append("#Rotation Center(mm): \n#");
258 textEdit->setText(str2);
260 str2=textEdit->toPlainText();
261 textEdit->setTextColor(QColor(255,0,0));
262 str2.append(str3.append(Xval->text()));
263 textEdit->setText(str2);
266 str2=textEdit->toPlainText();
268 textEdit->setText(str2);
270 str2=textEdit->toPlainText();
271 str2.append(str3.append(Yval->text()));
272 textEdit->setText(str2);
275 str2=textEdit->toPlainText();
277 textEdit->setText(str2);
280 str2=textEdit->toPlainText();
281 str2.append(str3.append(Zval->text()));
282 textEdit->setText(str2);
285 str2=textEdit->toPlainText();
287 textEdit->setText(str2);
290 str2=textEdit->toPlainText();
291 str2.append("#Transformation Matrix(mm):\n");
292 textEdit->setText(str2);
297 str2=textEdit->toPlainText();
298 // str2.append("\t"+str1.setNum(matrix->Element[i][j]));
299 str2.append(QString("%1\t").arg(str1.setNum(matrix->Element[i][j]),2));
300 textEdit->setText(str2);
302 str2=textEdit->toPlainText();
304 textEdit->setText(str2);
306 //QString str = QFileDialog::getOpenFileName();
307 textEdit->setTextColor(QColor(255,0,0));
308 textEdit->setFont(QFont("courrier new",12,4,true));
309 textEdit->toPlainText().toAscii();
311 str2=textEdit->toPlainText();
312 textEdit->setText(str2);
314 //------------------------------------------------------------------------------
316 //------------------------------------------------------------------------------
317 void vvToolRigidReg::UpdateTransform_sliders()
319 InitializeSliders(xtrans_slider->value()*mInput1->GetImage()->GetSpacing()[0],
320 ytrans_slider->value()*mInput1->GetImage()->GetSpacing()[1],
321 ztrans_slider->value()*mInput1->GetImage()->GetSpacing()[2],
322 xrot_slider->value(),yrot_slider->value(),zrot_slider->value(),false);
323 UpdateTransform(true);
326 //------------------------------------------------------------------------------
328 //------------------------------------------------------------------------------
329 void vvToolRigidReg::UpdateTransform_sb()
331 InitializeSliders(xtrans_sb->value(),
334 xrot_sb->value(),yrot_sb->value(),zrot_sb->value(),false);
335 UpdateTransform(false);
338 //------------------------------------------------------------------------------
340 //------------------------------------------------------------------------------
341 void vvToolRigidReg::AutoRegister()
343 GetArgsInfoFromGUI();
344 //clitk::AffineRegistrationGenericFilter::Pointer filter =
345 // clitk::AffineRegistrationGenericFilter::New();
346 //filter->SetArgsInfo(mArgsInfo);
350 //------------------------------------------------------------------------------
352 //------------------------------------------------------------------------------
353 void vvToolRigidReg::UpdateTransform(bool slider_enabled)
355 vtkSmartPointer<vtkTransform> transform_final=vtkSmartPointer<vtkTransform>::New();
356 transform_final->SetMatrix(mInitialMatrix);
357 transform_final->PostMultiply();
359 double x=0, y=0 ,z=0;
360 x= Xval->text().toDouble();
361 y= Yval->text().toDouble();
362 z= Zval->text().toDouble();
363 transform_final->Translate(-x,-y,-z);
365 transform_final->RotateY(yrot_slider->value());
366 transform_final->RotateX(xrot_slider->value());
367 transform_final->RotateZ(zrot_slider->value());
370 transform_final->RotateY(yrot_sb->value());
371 transform_final->RotateX(xrot_sb->value());
372 transform_final->RotateZ(zrot_sb->value());
374 transform_final->Translate(x,y,z);
375 transform_final->PreMultiply();
377 transform_final->Translate(xtrans_slider->value()*mInput1->GetImage()->GetSpacing()[0],0,0);
378 transform_final->Translate(0,ytrans_slider->value()*mInput1->GetImage()->GetSpacing()[1],0);
379 transform_final->Translate(0,0,ztrans_slider->value()*mInput1->GetImage()->GetSpacing()[2]);
382 transform_final->Translate(xtrans_sb->value(),0,0);
383 transform_final->Translate(0,ytrans_sb->value(),0);
384 transform_final->Translate(0,0,ztrans_sb->value());
386 SetTransform(transform_final->GetMatrix());
387 UpdateTextEditor(transform_final->GetMatrix(),textEdit);
389 //------------------------------------------------------------------------------
392 //------------------------------------------------------------------------------
393 void vvToolRigidReg::SaveFile()
395 //Write the Transformation Matrix
396 QString f1 = QFileDialog::getSaveFileName(this, tr("Save Transformation Matrix File"),
397 mMainWindow->GetInputPathName(),
398 tr("Text (*.mat *.txt *.doc *.rtf)"));
400 std::vector<QString> transparameters;
403 for(int i =0;i<4;i++)
405 transparameters.push_back(line1.setNum(mCurrentSlicerManager->GetImage()->GetTransform()->GetMatrix()->Element[i][j]));
407 if (file1.open(QFile::WriteOnly | QFile::Truncate)) {
408 QTextStream out1(&file1);
409 for(int i =0;i<4;i++){
410 for(int j=0;j<4;j++) {
411 out1<<transparameters[i*4+j]+"\t";
418 QMessageBox::information(this,"Warning","Error Reading Parameters");
421 //------------------------------------------------------------------------------
423 //------------------------------------------------------------------------------
424 void vvToolRigidReg::ReadFile()
428 double * orientations=new double[3];
429 double * translations=new double[3];
430 vtkMatrix4x4 *matrix=vtkMatrix4x4::New();
431 vtkSmartPointer<vtkTransform> transform = mCurrentSlicerManager->GetImage()->GetTransform();
433 //Open File to read the transformation parameters
434 QString file1 = QFileDialog::getOpenFileName(
436 "Choose the Transformation Parameters file",
437 mMainWindow->GetInputPathName(),
438 "Text (*.mat *.txt *.rtf *.doc)");
442 // ifstream readfile;
443 std::string transfile= file1.toStdString();
444 std::string filename1(transfile);
445 std::ifstream f1(filename1.c_str());
449 itk::Matrix<double, 4, 4> itkMat = clitk::ReadMatrix3D(transfile);
450 for(int j=0; j<4; j++)
451 for(int i=0; i<4; i++)
452 matrix->SetElement(i,j,itkMat[i][j]);
454 UpdateTextEditor(matrix,textEdit);
455 transform->SetMatrix(matrix);
456 transform->GetOrientation(orientations);
457 transform->PostMultiply();
459 //Obtain the Rotation Center , set it to origin
460 Xval->setText(center.setNum(0));
461 Yval->setText(center.setNum(0));
462 Zval->setText(center.setNum(0));
464 //In the Order or Y X Z //
465 //now postmultiply for the rotations
466 SetTransform(0,0,0,0,0,-rint(orientations[2]),false);
467 SetTransform(0,0,0,-rint(orientations[0]),0,0,false);
468 SetTransform(0,0,0,0,-rint(orientations[1]),0,false);
470 transform->GetPosition(translations);
471 transform->Identity();
473 DD(translations[0]/mInput1->GetImage()->GetSpacing()[0]);
474 DD(translations[1]/mInput1->GetImage()->GetSpacing()[1]);
475 DD(translations[2]/mInput1->GetImage()->GetSpacing()[2]);
479 //set the sliders and spin box values
480 InitializeSliders(rint(translations[0]),rint(translations[1])
481 ,rint(translations[2]),rint(orientations[0]),rint(orientations[1]),rint(orientations[2]),true);
482 SetTransform(matrix);
484 //------------------------------------------------------------------------------
486 //------------------------------------------------------------------------------
487 void vvToolRigidReg::ResetTransform()
489 vtkMatrix4x4 *matrix = vtkMatrix4x4::New();
492 matrix->SetElement(i,j,mInitialMatrix[i*4+j]);
493 SetTransform(matrix);
496 UpdateTextEditor(matrix,textEdit);
498 //------------------------------------------------------------------------------
500 //------------------------------------------------------------------------------
501 void vvToolRigidReg::SetRotationCenter()
503 //default image rotation center is the center of the image
504 QString xcord,ycord,zcord;
505 std::vector<double> imageorigin;
506 imageorigin=mInput1->GetImage()->GetOrigin();
508 xcord=xcord.setNum(imageorigin[0]+mImageSize[0]*mInput1->GetImage()->GetSpacing()[0]/2, 'g', 3);
509 ycord=ycord.setNum(imageorigin[1]+mImageSize[1]*mInput1->GetImage()->GetSpacing()[1]/2, 'g', 3);
510 zcord=zcord.setNum(imageorigin[2]+mImageSize[2]*mInput1->GetImage()->GetSpacing()[2]/2, 'g', 3);
512 Xval->setText(xcord);
513 Yval->setText(ycord);
514 Zval->setText(zcord);
515 InitializeSliders(0,0,0,0,0,0,true);
517 //------------------------------------------------------------------------------
519 //------------------------------------------------------------------------------
520 void vvToolRigidReg::InitializeSliders(double xtrans,double ytrans, double ztrans, double xrot, double yrot, double zrot,bool sliders)
523 xtrans_sb->blockSignals(true);
524 xtrans_sb->setSingleStep(mInput1->GetImage()->GetSpacing()[0]);
525 xtrans_sb->setValue(xtrans);
526 xtrans_sb->blockSignals(false);
527 ytrans_sb->blockSignals(true);
528 ytrans_sb->setSingleStep(mInput1->GetImage()->GetSpacing()[1]);
529 ytrans_sb->setValue(ytrans);
530 ytrans_sb->blockSignals(false);
531 ztrans_sb->blockSignals(true);
532 ztrans_sb->setSingleStep(mInput1->GetImage()->GetSpacing()[2]);
533 ztrans_sb->setValue(ztrans);
534 ztrans_sb->blockSignals(false);
537 xtrans_slider->blockSignals(true);
538 DD(xtrans_slider->value());
539 xtrans_slider->setValue(rint(xtrans));
540 xtrans_slider->blockSignals(false);
541 ytrans_slider->blockSignals(true);
542 ytrans_slider->setValue(rint(ytrans));
543 ytrans_slider->blockSignals(false);
544 ztrans_slider->blockSignals(true);
545 ztrans_slider->setValue(rint(ztrans));
546 ztrans_slider->blockSignals(false);
548 xrot_sb->blockSignals(true);
549 xrot_sb->setValue(xrot);
550 xrot_sb->blockSignals(false);
551 yrot_sb->blockSignals(true);
552 yrot_sb->setValue(yrot);
553 yrot_sb->blockSignals(false);
554 zrot_sb->blockSignals(true);
555 zrot_sb->setValue(zrot);
556 zrot_sb->blockSignals(false);
557 xrot_slider->blockSignals(true);
558 xrot_slider->setValue(xrot);
559 xrot_slider->blockSignals(false);
560 yrot_slider->blockSignals(true);
561 yrot_slider->setValue(yrot);
562 yrot_slider->blockSignals(false);
563 zrot_slider->blockSignals(true);
564 zrot_slider->setValue(zrot);
565 zrot_slider->blockSignals(false);
567 //------------------------------------------------------------------------------
569 //------------------------------------------------------------------------------
570 void vvToolRigidReg::SetSliderRanges()
572 xtrans_slider->blockSignals(true);
573 xtrans_slider->setRange(-2000,2000);
574 xtrans_slider->blockSignals(false);
576 ytrans_slider->blockSignals(true);
577 ytrans_slider->setRange(-2000,2000);
578 ytrans_slider->blockSignals(false);
580 ztrans_slider->blockSignals(true);
581 ztrans_slider->setRange(-2000,2000);
582 ztrans_slider->blockSignals(false);
584 xtrans_sb->blockSignals(true);
585 xtrans_sb->setRange(-2000,2000);
586 xtrans_sb->setDecimals(3);
587 xtrans_sb->blockSignals(false);
589 ytrans_sb->blockSignals(true);
590 ytrans_sb->setRange(-2000,2000);
591 ytrans_sb->setDecimals(3);
592 ytrans_sb->blockSignals(false);
594 ztrans_sb->blockSignals(true);
595 ztrans_sb->setRange(-2000,2000);
596 ztrans_sb->setDecimals(3);
597 ztrans_sb->blockSignals(false);
599 xrot_slider->blockSignals(true);
600 xrot_slider->setRange(-360,360);
601 xrot_slider->blockSignals(false);
603 yrot_slider->blockSignals(true);
604 yrot_slider->setRange(-360,360);
605 yrot_slider->blockSignals(false);
607 zrot_slider->blockSignals(true);
608 zrot_slider->setRange(-360,360);
609 zrot_slider->blockSignals(false);
612 xrot_sb->blockSignals(true);
613 xrot_sb->setRange(-360,360);
614 xrot_sb->blockSignals(false);
616 yrot_sb->blockSignals(true);
617 yrot_sb->setRange(-360,360);
618 yrot_sb->blockSignals(false);
620 zrot_sb->blockSignals(true);
621 zrot_sb->setRange(-360,360);
622 zrot_sb->blockSignals(false);