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 ======================================================================-====*/
18 #include "vvToolRigidReg.h"
21 #include <QApplication>
22 #include <vtkImageData.h>
23 #include <vtkSmartPointer.h>
24 #include <vtkTransform.h>
25 #include <vvImageReader.h>
29 #include "clitkTransformUtilities.h"
31 #include <QMessageBox>
32 #include <vvMainWindow.h>
33 #include <QFileDialog>
34 #include <QTextStream>
35 //------------------------------------------------------------------------------
36 // Create the tool and automagically (I like this word) insert it in
37 // the main window menu.
38 ADD_TOOL(vvToolRigidReg);
39 //------------------------------------------------------------------------------
41 //------------------------------------------------------------------------------
42 vvToolRigidReg::vvToolRigidReg(vvMainWindowBase * parent, Qt::WindowFlags f):
43 vvToolWidgetBase(parent, f),
44 vvToolBase<vvToolRigidReg>(parent),
48 Ui_vvToolRigidReg::setupUi(mToolWidget);
52 mToolWidget->setFixedSize(qsize);
55 // Set how many inputs are needed for this tool
56 // mFilter = new clitk::AffineTransformGenericFilter<args_info_clitkAffineTransform>;
58 // Set how many inputs are needed for this tool
59 AddInputSelector("Select moving image");
60 AddInputSelector("Select fixed image");
62 //------------------------------------------------------------------------------
64 //------------------------------------------------------------------------------
65 vvToolRigidReg::~vvToolRigidReg()
68 //------------------------------------------------------------------------------
70 //------------------------------------------------------------------------------
71 bool vvToolRigidReg::close()
75 return vvToolWidgetBase::close();
77 //------------------------------------------------------------------------------
79 //------------------------------------------------------------------------------
80 void vvToolRigidReg::reject()
82 return vvToolWidgetBase::reject();
84 //------------------------------------------------------------------------------
86 //------------------------------------------------------------------------------
87 void vvToolRigidReg::GetArgsInfoFromGUI()
91 //------------------------------------------------------------------------------
93 //------------------------------------------------------------------------------
94 void vvToolRigidReg::InputIsSelected(std::vector<vvSlicerManager *> & l)
100 UpdateTextEditor(mCurrentSlicerManager->GetImage()->GetTransform()->GetMatrix(),textEdit_2);
102 for(int i =0;i<4;i++)
104 mInitialMatrix[i*4+j]=mCurrentSlicerManager->GetImage()->GetTransform()->GetMatrix()->GetElement(i,j);
106 if(mInput1->GetFileName()==mInput2->GetFileName())
108 QMessageBox::information(this, "Warning","Your Reference and Target Images are the same");
112 mImageSize=mInput1->GetImage()->GetSize();
116 //connect all sigs to slots
117 connect(resetbutton, SIGNAL(pressed()), this, SLOT(ResetTransform()));
118 connect(tab2loadbutton, SIGNAL(pressed()), this, SLOT(AutoRegister()));
120 connect(Xval, SIGNAL(editingFinished()), this, SLOT(SetXvalue()));
121 connect(Yval, SIGNAL(editingFinished()), this, SLOT(SetYvalue()));
122 connect(Zval, SIGNAL(editingFinished()), this, SLOT(SetZvalue()));
124 connect(xtrans_slider, SIGNAL(valueChanged(int)), this, SLOT(UpdateTransform_sliders()));
125 connect(ytrans_slider, SIGNAL(valueChanged(int)), this, SLOT(UpdateTransform_sliders()));
126 connect(ztrans_slider, SIGNAL(valueChanged(int)), this, SLOT(UpdateTransform_sliders()));
129 connect(xrot_slider, SIGNAL(valueChanged(int)), this, SLOT(UpdateTransform_sliders()));
130 connect(yrot_slider, SIGNAL(valueChanged(int)), this, SLOT(UpdateTransform_sliders()));
131 connect(zrot_slider, SIGNAL(valueChanged(int)), this, SLOT(UpdateTransform_sliders()));
133 connect(xtrans_sb, SIGNAL(valueChanged(double)), this, SLOT(UpdateTransform_sb()));
134 connect(ytrans_sb, SIGNAL(valueChanged(double)), this, SLOT(UpdateTransform_sb()));
135 connect(ztrans_sb, SIGNAL(valueChanged(double)), this, SLOT(UpdateTransform_sb()));
136 connect(xrot_sb, SIGNAL(valueChanged(double)), this, SLOT(UpdateTransform_sb()));
137 connect(yrot_sb, SIGNAL(valueChanged(double)), this, SLOT(UpdateTransform_sb()));
138 connect(zrot_sb, SIGNAL(valueChanged(double)), this, SLOT(UpdateTransform_sb()));
140 connect(loadbutton, SIGNAL(pressed()), this, SLOT(ReadFile()));
141 connect(savebutton, SIGNAL(pressed()), this, SLOT(SaveFile()));
144 //------------------------------------------------------------------------------
146 //------------------------------------------------------------------------------
147 void vvToolRigidReg::apply()
151 //------------------------------------------------------------------------------
153 //------------------------------------------------------------------------------
154 void vvToolRigidReg::SetOverlay()
156 for (int i =0; i<mCurrentSlicerManager->NumberOfSlicers(); i++) {
157 mCurrentSlicerManager->GetSlicer(i)->SetOverlay(mInput2->GetImage());
158 mCurrentSlicerManager->GetSlicer(i)->SetActorVisibility("overlay",0,true);
159 mCurrentSlicerManager->SetColorMap();
160 mCurrentSlicerManager->Render();
163 //------------------------------------------------------------------------------
165 //------------------------------------------------------------------------------
166 void vvToolRigidReg::RemoveOverlay()
168 for(int i=0;i<mCurrentSlicerManager->NumberOfSlicers();i++)
170 mInput1->RemoveActor("overlay",0);
171 mInput1->SetColorMap(0);
176 //------------------------------------------------------------------------------
178 //------------------------------------------------------------------------------
179 void vvToolRigidReg::SetXvalue()
181 QString xstr = Xval->text();
183 //------------------------------------------------------------------------------
185 //------------------------------------------------------------------------------
186 void vvToolRigidReg::SetYvalue()
188 QString ystr = Yval->text();
190 //------------------------------------------------------------------------------
192 //------------------------------------------------------------------------------
193 void vvToolRigidReg::SetZvalue()
195 QString zstr = Zval->text();
197 //------------------------------------------------------------------------------
199 //------------------------------------------------------------------------------
200 void vvToolRigidReg::SetTransform(double tX, double tY, double tZ, double aX, double aY, double aZ,bool update)
202 vtkSmartPointer<vtkTransform> transform = mInput1->GetImage()->GetTransform();
203 transform->PostMultiply();
205 if (aX!=0 || aY!=0 || aZ!=0) {
207 x= Xval->text().toDouble();
208 y= Yval->text().toDouble();
209 z= Zval->text().toDouble();
210 transform->Translate(-x,-y,-z);
211 if (aX!=0) transform->RotateX(aX);
212 if (aY!=0) transform->RotateY(aY);
213 if (aZ!=0) transform->RotateZ(aZ);
214 transform->Translate(x,y,z);
217 if (tX!=0||tY!=0||tZ!=0)
218 transform->Translate(tX*mInput1->GetImage()->GetSpacing()[0],tY*mInput1->GetImage()->GetSpacing()[1],tZ*mInput1->GetImage()->GetSpacing()[2]);
220 //------------------------------------------------------------------------------
222 //------------------------------------------------------------------------------
223 void vvToolRigidReg::SetTransform(vtkMatrix4x4 *matrix)
225 vtkSmartPointer<vtkTransform> transform =mCurrentSlicerManager->GetImage()->GetTransform();
226 transform->SetMatrix(matrix);
229 //------------------------------------------------------------------------------
231 //------------------------------------------------------------------------------
232 void vvToolRigidReg::Render()
234 for (int i=0; i<mCurrentSlicerManager->NumberOfSlicers(); i++) {
235 mCurrentSlicerManager->GetSlicer(i)->ForceUpdateDisplayExtent();
236 mCurrentSlicerManager->GetSlicer(i)->Render();
239 //------------------------------------------------------------------------------
241 //------------------------------------------------------------------------------
242 void vvToolRigidReg::UpdateTextEditor(vtkMatrix4x4 *matrix,QTextEdit* textEdit)
244 QFont font=QFont("Times New Roman",11);
245 textEdit->setCurrentFont(font);
248 QString str1,str2,str3;
251 textEdit->setAcceptRichText(true);
252 str2=textEdit->toPlainText();
253 str2.append("#Rotation Center(mm): \n#");
254 textEdit->setText(str2);
256 str2=textEdit->toPlainText();
257 textEdit->setTextColor(QColor(255,0,0));
258 str2.append(str3.append(Xval->text()));
259 textEdit->setText(str2);
262 str2=textEdit->toPlainText();
264 textEdit->setText(str2);
266 str2=textEdit->toPlainText();
267 str2.append(str3.append(Yval->text()));
268 textEdit->setText(str2);
271 str2=textEdit->toPlainText();
273 textEdit->setText(str2);
276 str2=textEdit->toPlainText();
277 str2.append(str3.append(Zval->text()));
278 textEdit->setText(str2);
281 str2=textEdit->toPlainText();
283 textEdit->setText(str2);
286 str2=textEdit->toPlainText();
287 str2.append("#Transformation Matrix(mm):\n");
288 textEdit->setText(str2);
293 str2=textEdit->toPlainText();
294 // str2.append("\t"+str1.setNum(matrix->Element[i][j]));
295 str2.append(QString("%1\t").arg(str1.setNum(matrix->Element[i][j]),2));
296 textEdit->setText(str2);
298 str2=textEdit->toPlainText();
300 textEdit->setText(str2);
302 //QString str = QFileDialog::getOpenFileName();
303 textEdit->setTextColor(QColor(255,0,0));
304 textEdit->setFont(QFont("courrier new",12,4,true));
305 textEdit->toPlainText().toAscii();
307 str2=textEdit->toPlainText();
308 textEdit->setText(str2);
310 //------------------------------------------------------------------------------
312 //------------------------------------------------------------------------------
313 void vvToolRigidReg::UpdateTransform_sliders()
315 InitializeSliders(xtrans_slider->value()*mInput1->GetImage()->GetSpacing()[0],
316 ytrans_slider->value()*mInput1->GetImage()->GetSpacing()[1],
317 ztrans_slider->value()*mInput1->GetImage()->GetSpacing()[2],
318 xrot_slider->value(),yrot_slider->value(),zrot_slider->value(),false);
319 UpdateTransform(true);
322 //------------------------------------------------------------------------------
324 //------------------------------------------------------------------------------
325 void vvToolRigidReg::UpdateTransform_sb()
327 InitializeSliders(xtrans_sb->value(),
330 xrot_sb->value(),yrot_sb->value(),zrot_sb->value(),false);
331 UpdateTransform(false);
334 //------------------------------------------------------------------------------
336 //------------------------------------------------------------------------------
337 void vvToolRigidReg::AutoRegister()
339 GetArgsInfoFromGUI();
340 //clitk::AffineRegistrationGenericFilter::Pointer filter =
341 // clitk::AffineRegistrationGenericFilter::New();
342 //filter->SetArgsInfo(mArgsInfo);
346 //------------------------------------------------------------------------------
348 //------------------------------------------------------------------------------
349 void vvToolRigidReg::UpdateTransform(bool slider_enabled)
351 vtkSmartPointer<vtkTransform> transform_final=vtkSmartPointer<vtkTransform>::New();
352 transform_final->SetMatrix(mInitialMatrix);
353 transform_final->PostMultiply();
355 double x=0, y=0 ,z=0;
356 x= Xval->text().toDouble();
357 y= Yval->text().toDouble();
358 z= Zval->text().toDouble();
359 transform_final->Translate(-x,-y,-z);
361 transform_final->RotateY(yrot_slider->value());
362 transform_final->RotateX(xrot_slider->value());
363 transform_final->RotateZ(zrot_slider->value());
366 transform_final->RotateY(yrot_sb->value());
367 transform_final->RotateX(xrot_sb->value());
368 transform_final->RotateZ(zrot_sb->value());
370 transform_final->Translate(x,y,z);
371 transform_final->PreMultiply();
373 transform_final->Translate(xtrans_slider->value()*mInput1->GetImage()->GetSpacing()[0],0,0);
374 transform_final->Translate(0,ytrans_slider->value()*mInput1->GetImage()->GetSpacing()[1],0);
375 transform_final->Translate(0,0,ztrans_slider->value()*mInput1->GetImage()->GetSpacing()[2]);
378 transform_final->Translate(xtrans_sb->value(),0,0);
379 transform_final->Translate(0,ytrans_sb->value(),0);
380 transform_final->Translate(0,0,ztrans_sb->value());
382 SetTransform(transform_final->GetMatrix());
383 UpdateTextEditor(transform_final->GetMatrix(),textEdit);
385 //------------------------------------------------------------------------------
387 //------------------------------------------------------------------------------
388 void vvToolRigidReg::SaveFile()
390 //Write the Transformation Matrix
391 QString f1 = QFileDialog::getSaveFileName(this, tr("Save Transformation Matrix File"),
393 tr("Text (*.mat *.txt *.doc *.rtf)"));
395 std::vector<QString> transparameters;
398 for(int i =0;i<4;i++)
400 transparameters.push_back(line1.setNum(mCurrentSlicerManager->GetImage()->GetTransform()->GetMatrix()->Element[i][j]));
402 if (file1.open(QFile::WriteOnly | QFile::Truncate)) {
403 QTextStream out1(&file1);
404 for(int i =0;i<4;i++){
405 for(int j=0;j<4;j++) {
406 out1<<transparameters[i*4+j]+"\t";
413 QMessageBox::information(this,"Warning","Error Reading Parameters");
416 //------------------------------------------------------------------------------
418 //------------------------------------------------------------------------------
419 void vvToolRigidReg::ReadFile()
423 double * orientations=new double[3];
424 double * translations=new double[3];
425 vtkMatrix4x4 *matrix=vtkMatrix4x4::New();
426 vtkSmartPointer<vtkTransform> transform = mCurrentSlicerManager->GetImage()->GetTransform();
428 //Open File to read the transformation parameters
429 QString file1 = QFileDialog::getOpenFileName(
431 "Choose the Transformation Parameters file",
433 "Text (*.mat *.txt *.rtf *.doc)");
437 // ifstream readfile;
438 std::string transfile= file1.toStdString();
439 std::string filename1(transfile);
440 std::ifstream f1(filename1.c_str());
444 itk::Matrix<double, 4, 4> itkMat = clitk::ReadMatrix3D(transfile);
445 for(int j=0; j<4; j++)
446 for(int i=0; i<4; i++)
447 matrix->SetElement(i,j,itkMat[i][j]);
449 UpdateTextEditor(matrix,textEdit);
450 transform->SetMatrix(matrix);
451 transform->GetOrientation(orientations);
452 transform->PostMultiply();
454 //Obtain the Rotation Center , set it to origin
455 Xval->setText(center.setNum(0));
456 Yval->setText(center.setNum(0));
457 Zval->setText(center.setNum(0));
459 //In the Order or Y X Z //
460 //now postmultiply for the rotations
461 SetTransform(0,0,0,0,0,-round(orientations[2]),false);
462 SetTransform(0,0,0,-round(orientations[0]),0,0,false);
463 SetTransform(0,0,0,0,-round(orientations[1]),0,false);
465 transform->GetPosition(translations);
466 transform->Identity();
468 DD(translations[0]/mInput1->GetImage()->GetSpacing()[0]);
469 DD(translations[1]/mInput1->GetImage()->GetSpacing()[1]);
470 DD(translations[2]/mInput1->GetImage()->GetSpacing()[2]);
474 //set the sliders and spin box values
475 InitializeSliders(rint(translations[0]),rint(translations[1])
476 ,rint(translations[2]),rint(orientations[0]),rint(orientations[1]),rint(orientations[2]),true);
477 SetTransform(matrix);
479 //------------------------------------------------------------------------------
481 //------------------------------------------------------------------------------
482 void vvToolRigidReg::ResetTransform()
484 vtkMatrix4x4 *matrix = vtkMatrix4x4::New();
487 matrix->SetElement(i,j,mInitialMatrix[i*4+j]);
488 SetTransform(matrix);
491 UpdateTextEditor(matrix,textEdit);
493 //------------------------------------------------------------------------------
495 //------------------------------------------------------------------------------
496 void vvToolRigidReg::SetRotationCenter()
498 //default image rotation center is the center of the image
499 QString xcord,ycord,zcord;
500 std::vector<double> imageorigin;
501 imageorigin=mInput1->GetImage()->GetOrigin();
503 xcord=xcord.setNum(imageorigin[0]+mImageSize[0]*mInput1->GetImage()->GetSpacing()[0]/2, 'g', 3);
504 ycord=ycord.setNum(imageorigin[1]+mImageSize[1]*mInput1->GetImage()->GetSpacing()[1]/2, 'g', 3);
505 zcord=zcord.setNum(imageorigin[2]+mImageSize[2]*mInput1->GetImage()->GetSpacing()[2]/2, 'g', 3);
507 Xval->setText(xcord);
508 Yval->setText(ycord);
509 Zval->setText(zcord);
510 InitializeSliders(0,0,0,0,0,0,true);
512 //------------------------------------------------------------------------------
514 //------------------------------------------------------------------------------
515 void vvToolRigidReg::InitializeSliders(double xtrans,double ytrans, double ztrans, double xrot, double yrot, double zrot,bool sliders)
518 xtrans_sb->blockSignals(true);
519 xtrans_sb->setSingleStep(mInput1->GetImage()->GetSpacing()[0]);
520 xtrans_sb->setValue(xtrans);
521 xtrans_sb->blockSignals(false);
522 ytrans_sb->blockSignals(true);
523 ytrans_sb->setSingleStep(mInput1->GetImage()->GetSpacing()[1]);
524 ytrans_sb->setValue(ytrans);
525 ytrans_sb->blockSignals(false);
526 ztrans_sb->blockSignals(true);
527 ztrans_sb->setSingleStep(mInput1->GetImage()->GetSpacing()[2]);
528 ztrans_sb->setValue(ztrans);
529 ztrans_sb->blockSignals(false);
532 xtrans_slider->blockSignals(true);
533 DD(xtrans_slider->value());
534 xtrans_slider->setValue(rint(xtrans));
535 xtrans_slider->blockSignals(false);
536 ytrans_slider->blockSignals(true);
537 ytrans_slider->setValue(rint(ytrans));
538 ytrans_slider->blockSignals(false);
539 ztrans_slider->blockSignals(true);
540 ztrans_slider->setValue(rint(ztrans));
541 ztrans_slider->blockSignals(false);
543 xrot_sb->blockSignals(true);
544 xrot_sb->setValue(xrot);
545 xrot_sb->blockSignals(false);
546 yrot_sb->blockSignals(true);
547 yrot_sb->setValue(yrot);
548 yrot_sb->blockSignals(false);
549 zrot_sb->blockSignals(true);
550 zrot_sb->setValue(zrot);
551 zrot_sb->blockSignals(false);
552 xrot_slider->blockSignals(true);
553 xrot_slider->setValue(xrot);
554 xrot_slider->blockSignals(false);
555 yrot_slider->blockSignals(true);
556 yrot_slider->setValue(yrot);
557 yrot_slider->blockSignals(false);
558 zrot_slider->blockSignals(true);
559 zrot_slider->setValue(zrot);
560 zrot_slider->blockSignals(false);
562 //------------------------------------------------------------------------------
564 //------------------------------------------------------------------------------
565 void vvToolRigidReg::SetSliderRanges()
567 xtrans_slider->blockSignals(true);
568 xtrans_slider->setRange(-2000,2000);
569 xtrans_slider->blockSignals(false);
571 ytrans_slider->blockSignals(true);
572 ytrans_slider->setRange(-2000,2000);
573 ytrans_slider->blockSignals(false);
575 ztrans_slider->blockSignals(true);
576 ztrans_slider->setRange(-2000,2000);
577 ztrans_slider->blockSignals(false);
579 xtrans_sb->blockSignals(true);
580 xtrans_sb->setRange(-2000,2000);
581 xtrans_sb->setDecimals(3);
582 xtrans_sb->blockSignals(false);
584 ytrans_sb->blockSignals(true);
585 ytrans_sb->setRange(-2000,2000);
586 ytrans_sb->setDecimals(3);
587 ytrans_sb->blockSignals(false);
589 ztrans_sb->blockSignals(true);
590 ztrans_sb->setRange(-2000,2000);
591 ztrans_sb->setDecimals(3);
592 ztrans_sb->blockSignals(false);
594 xrot_slider->blockSignals(true);
595 xrot_slider->setRange(-360,360);
596 xrot_slider->blockSignals(false);
598 yrot_slider->blockSignals(true);
599 yrot_slider->setRange(-360,360);
600 yrot_slider->blockSignals(false);
602 zrot_slider->blockSignals(true);
603 zrot_slider->setRange(-360,360);
604 zrot_slider->blockSignals(false);
607 xrot_sb->blockSignals(true);
608 xrot_sb->setRange(-360,360);
609 xrot_sb->blockSignals(false);
611 yrot_sb->blockSignals(true);
612 yrot_sb->setRange(-360,360);
613 yrot_sb->blockSignals(false);
615 zrot_sb->blockSignals(true);
616 zrot_sb->setRange(-360,360);
617 zrot_sb->blockSignals(false);