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"
31 #include "clitkAffineRegistrationGenericFilter.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);
58 // Set how many inputs are needed for this tool
59 mFilter = new clitk::AffineRegistrationGenericFilter<args_info_clitkAffineRegistration>;
61 // Set how many inputs are needed for this tool
62 AddInputSelector("Select moving image",mFilter);
63 AddInputSelector("Select fixed image",mFilter);
65 //------------------------------------------------------------------------------
67 //------------------------------------------------------------------------------
68 vvToolRigidReg::~vvToolRigidReg()
71 //------------------------------------------------------------------------------
73 //------------------------------------------------------------------------------
74 bool vvToolRigidReg::close()
78 return vvToolWidgetBase::close();
80 //------------------------------------------------------------------------------
82 //------------------------------------------------------------------------------
83 void vvToolRigidReg::reject()
86 return vvToolWidgetBase::reject();
88 //------------------------------------------------------------------------------
90 //------------------------------------------------------------------------------
91 void vvToolRigidReg::GetArgsInfoFromGUI()
93 QFont font=QFont("Times New Roman",10);
94 tab2textedit->setTextColor(QColor(255,0,0));
95 tab2textedit->setCurrentFont(font);
96 tab2textedit->update();
98 QString file = QFileDialog::getOpenFileName(
100 "Choose the Transformation Parameters file",
101 mMainWindow->GetInputPathName(),
102 "Text (*.conf *.txt *.rtf *.doc)");
106 // ifstream readfile;
107 std::string configfile= file.toStdString();
108 cmdline_parser_clitkAffineRegistration_configfile(const_cast<char*>(configfile.c_str()),&mArgsInfo,1,1,1);
109 mArgsInfo.gradient_flag=1;
111 //Read from File and display it on the TextBox 2
113 std::vector<QString> Qstr;
114 readfile.open(configfile.c_str());
115 if (readfile.is_open())
117 while (!readfile.eof())
119 readfile >> configfile;
120 Qstr.push_back(QString(configfile.c_str()));
125 cout << "Unable to open file";
127 for(unsigned int i=0;i<Qstr.size();i++)
129 str=tab2textedit->toPlainText();
130 str.append(Qstr.at(i));
131 tab2textedit->setText(str);
133 tab2textedit->setText(str);
136 //------------------------------------------------------------------------------
138 //------------------------------------------------------------------------------
139 void vvToolRigidReg::InputIsSelected(std::vector<vvSlicerManager *> & l)
145 UpdateTextEditor(mCurrentSlicerManager->GetImage()->GetTransform()->GetMatrix(),textEdit_2);
147 for(int i =0;i<4;i++)
149 mInitialMatrix[i*4+j]=mCurrentSlicerManager->GetImage()->GetTransform()->GetMatrix()->GetElement(i,j);
151 if(mInput1->GetFileName()==mInput2->GetFileName())
153 QMessageBox::information(this, "Warning","Your Reference and Target Images are the same");
156 SetOverlay(mInput2->GetImage());
157 mImageSize=mInput1->GetImage()->GetSize();
161 //connect all sigs to slots
162 connect(resetbutton, SIGNAL(pressed()), this, SLOT(ResetTransform()));
163 connect(tab2loadbutton, SIGNAL(pressed()), this, SLOT(GetArgsInfoFromGUI()));
164 connect(tab2applybutton, SIGNAL(pressed()), this, SLOT(AutoRegister()));
167 connect(Xval, SIGNAL(editingFinished()), this, SLOT(SetXvalue()));
168 connect(Yval, SIGNAL(editingFinished()), this, SLOT(SetYvalue()));
169 connect(Zval, SIGNAL(editingFinished()), this, SLOT(SetZvalue()));
171 connect(xtrans_slider, SIGNAL(valueChanged(int)), this, SLOT(UpdateTransform_sliders()));
172 connect(ytrans_slider, SIGNAL(valueChanged(int)), this, SLOT(UpdateTransform_sliders()));
173 connect(ztrans_slider, SIGNAL(valueChanged(int)), this, SLOT(UpdateTransform_sliders()));
176 connect(xrot_slider, SIGNAL(valueChanged(int)), this, SLOT(UpdateTransform_sliders()));
177 connect(yrot_slider, SIGNAL(valueChanged(int)), this, SLOT(UpdateTransform_sliders()));
178 connect(zrot_slider, SIGNAL(valueChanged(int)), this, SLOT(UpdateTransform_sliders()));
180 connect(xtrans_sb, SIGNAL(valueChanged(double)), this, SLOT(UpdateTransform_sb()));
181 connect(ytrans_sb, SIGNAL(valueChanged(double)), this, SLOT(UpdateTransform_sb()));
182 connect(ztrans_sb, SIGNAL(valueChanged(double)), this, SLOT(UpdateTransform_sb()));
183 connect(xrot_sb, SIGNAL(valueChanged(double)), this, SLOT(UpdateTransform_sb()));
184 connect(yrot_sb, SIGNAL(valueChanged(double)), this, SLOT(UpdateTransform_sb()));
185 connect(zrot_sb, SIGNAL(valueChanged(double)), this, SLOT(UpdateTransform_sb()));
187 connect(loadbutton, SIGNAL(pressed()), this, SLOT(ReadFile()));
188 connect(savebutton, SIGNAL(pressed()), this, SLOT(SaveFile()));
191 //------------------------------------------------------------------------------
193 //------------------------------------------------------------------------------
194 void vvToolRigidReg::apply()
198 //------------------------------------------------------------------------------
200 //------------------------------------------------------------------------------
201 void vvToolRigidReg::SetOverlay(vvImage::Pointer Image)
203 for (int i =0; i<mCurrentSlicerManager->NumberOfSlicers(); i++) {
204 mCurrentSlicerManager->GetSlicer(i)->SetOverlay(Image);
205 mCurrentSlicerManager->GetSlicer(i)->SetActorVisibility("overlay",0,true);
206 mCurrentSlicerManager->SetColorMap();
207 mCurrentSlicerManager->Render();
210 //------------------------------------------------------------------------------
212 //------------------------------------------------------------------------------
213 void vvToolRigidReg::RemoveOverlay()
215 for(int i=0;i<mCurrentSlicerManager->NumberOfSlicers();i++)
217 mInput1->RemoveActor("overlay",0);
218 mInput1->SetColorMap(0);
223 //------------------------------------------------------------------------------
225 //------------------------------------------------------------------------------
226 void vvToolRigidReg::SetXvalue()
228 QString xstr = Xval->text();
230 //------------------------------------------------------------------------------
232 //------------------------------------------------------------------------------
233 void vvToolRigidReg::SetYvalue()
235 QString ystr = Yval->text();
237 //------------------------------------------------------------------------------
239 //------------------------------------------------------------------------------
240 void vvToolRigidReg::SetZvalue()
242 QString zstr = Zval->text();
244 //------------------------------------------------------------------------------
246 //------------------------------------------------------------------------------
247 void vvToolRigidReg::SetTransform(double tX, double tY, double tZ, double aX, double aY, double aZ,bool update)
249 vtkSmartPointer<vtkTransform> transform = mInput1->GetImage()->GetTransform();
250 transform->PostMultiply();
252 if (aX!=0 || aY!=0 || aZ!=0) {
254 x= Xval->text().toDouble();
255 y= Yval->text().toDouble();
256 z= Zval->text().toDouble();
257 transform->Translate(-x,-y,-z);
258 if (aX!=0) transform->RotateX(aX);
259 if (aY!=0) transform->RotateY(aY);
260 if (aZ!=0) transform->RotateZ(aZ);
261 transform->Translate(x,y,z);
264 if (tX!=0||tY!=0||tZ!=0)
265 transform->Translate(tX*mInput1->GetImage()->GetSpacing()[0],tY*mInput1->GetImage()->GetSpacing()[1],tZ*mInput1->GetImage()->GetSpacing()[2]);
267 //------------------------------------------------------------------------------
269 //------------------------------------------------------------------------------
270 void vvToolRigidReg::SetTransform(vtkMatrix4x4 *matrix)
272 vtkSmartPointer<vtkTransform> transform=vtkSmartPointer<vtkTransform>::New();
273 for(int i=0; i<4;i++)
275 mCurrentSlicerManager->GetImage()->GetTransform()->GetMatrix()->SetElement(i,j,matrix->GetElement(i,j));
279 //------------------------------------------------------------------------------
281 //------------------------------------------------------------------------------
282 void vvToolRigidReg::Render()
284 for (int i=0; i<mCurrentSlicerManager->NumberOfSlicers(); i++) {
285 mCurrentSlicerManager->GetSlicer(i)->ForceUpdateDisplayExtent();
286 mCurrentSlicerManager->GetSlicer(i)->Render();
289 //------------------------------------------------------------------------------
291 //------------------------------------------------------------------------------
292 void vvToolRigidReg::UpdateTextEditor(vtkMatrix4x4 *matrix,QTextEdit* textEdit)
294 QFont font=QFont("Times New Roman",11);
295 textEdit->setCurrentFont(font);
298 QString str1,str2,str3;
301 textEdit->setAcceptRichText(true);
302 str2=textEdit->toPlainText();
303 str2.append("#Rotation Center(mm): \n#");
304 textEdit->setText(str2);
306 str2=textEdit->toPlainText();
307 textEdit->setTextColor(QColor(255,0,0));
308 str2.append(str3.append(Xval->text()));
309 textEdit->setText(str2);
312 str2=textEdit->toPlainText();
314 textEdit->setText(str2);
316 str2=textEdit->toPlainText();
317 str2.append(str3.append(Yval->text()));
318 textEdit->setText(str2);
321 str2=textEdit->toPlainText();
323 textEdit->setText(str2);
326 str2=textEdit->toPlainText();
327 str2.append(str3.append(Zval->text()));
328 textEdit->setText(str2);
331 str2=textEdit->toPlainText();
333 textEdit->setText(str2);
336 str2=textEdit->toPlainText();
337 str2.append("#Transformation Matrix(mm):\n");
338 textEdit->setText(str2);
343 str2=textEdit->toPlainText();
344 // str2.append("\t"+str1.setNum(matrix->Element[i][j]));
345 str2.append(QString("%1\t").arg(str1.setNum(matrix->Element[i][j]),2));
346 textEdit->setText(str2);
348 str2=textEdit->toPlainText();
350 textEdit->setText(str2);
352 //QString str = QFileDialog::getOpenFileName();
353 textEdit->setTextColor(QColor(255,0,0));
354 textEdit->setFont(QFont("courrier new",12,4,true));
355 textEdit->toPlainText().toAscii();
357 str2=textEdit->toPlainText();
358 textEdit->setText(str2);
360 //------------------------------------------------------------------------------
362 //------------------------------------------------------------------------------
363 void vvToolRigidReg::UpdateTransform_sliders()
365 InitializeSliders(xtrans_slider->value()*mInput1->GetImage()->GetSpacing()[0],
366 ytrans_slider->value()*mInput1->GetImage()->GetSpacing()[1],
367 ztrans_slider->value()*mInput1->GetImage()->GetSpacing()[2],
368 xrot_slider->value(),yrot_slider->value(),zrot_slider->value(),false);
369 UpdateTransform(true);
372 //------------------------------------------------------------------------------
374 //------------------------------------------------------------------------------
375 void vvToolRigidReg::UpdateTransform_sb()
377 InitializeSliders(xtrans_sb->value(),
380 xrot_sb->value(),yrot_sb->value(),zrot_sb->value(),false);
381 DD(xtrans_sb->value());
382 UpdateTransform(false);
385 //------------------------------------------------------------------------------
387 //------------------------------------------------------------------------------
388 void vvToolRigidReg::AutoRegister()
390 if (!mCurrentSlicerManager) close();
391 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
393 std::vector<vvImage::Pointer> inputs;
395 inputs.push_back(mInput1->GetImage());
396 inputs.push_back(mInput2->GetImage());
399 clitk::AffineRegistrationGenericFilter<args_info_clitkAffineRegistration>::Pointer filter =
400 clitk::AffineRegistrationGenericFilter<args_info_clitkAffineRegistration>::New();
401 filter->SetInputVVImages(inputs);
402 filter->SetArgsInfo(mArgsInfo);
403 DD("ArgsInfo given in");
404 filter->EnableReadOnDisk(false);
406 DD("I am done...! Updated");
407 vvImage::Pointer output = filter->GetOutputVVImage();
408 DD("filter getoutput done...");
409 std::ostringstream osstream;
410 //osstream << "Registered" << "_ "
411 // << mCurrentSlicerManager->GetSlicer(0)->GetFileName() << ".mhd";
412 //AddImage(output,osstream.str());
415 QApplication::restoreOverrideCursor();
418 //------------------------------------------------------------------------------
420 //------------------------------------------------------------------------------
421 void vvToolRigidReg::UpdateTransform(bool slider_enabled)
423 vtkSmartPointer<vtkTransform> transform_final=vtkSmartPointer<vtkTransform>::New();
424 transform_final->SetMatrix(mInitialMatrix);
425 transform_final->PostMultiply();
427 double x=0, y=0 ,z=0;
428 x= Xval->text().toDouble();
429 y= Yval->text().toDouble();
430 z= Zval->text().toDouble();
431 transform_final->Translate(-x,-y,-z);
433 transform_final->RotateY(yrot_slider->value());
434 transform_final->RotateX(xrot_slider->value());
435 transform_final->RotateZ(zrot_slider->value());
438 transform_final->RotateY(yrot_sb->value());
439 transform_final->RotateX(xrot_sb->value());
440 transform_final->RotateZ(zrot_sb->value());
442 transform_final->Translate(x,y,z);
443 transform_final->PreMultiply();
445 transform_final->Translate(xtrans_slider->value()*mInput1->GetImage()->GetSpacing()[0],0,0);
446 transform_final->Translate(0,ytrans_slider->value()*mInput1->GetImage()->GetSpacing()[1],0);
447 transform_final->Translate(0,0,ztrans_slider->value()*mInput1->GetImage()->GetSpacing()[2]);
450 transform_final->Translate(xtrans_sb->value(),0,0);
451 transform_final->Translate(0,ytrans_sb->value(),0);
452 transform_final->Translate(0,0,ztrans_sb->value());
454 SetTransform(transform_final->GetMatrix());
455 UpdateTextEditor(transform_final->GetMatrix(),textEdit);
457 //------------------------------------------------------------------------------
460 //------------------------------------------------------------------------------
461 void vvToolRigidReg::SaveFile()
463 //Write the Transformation Matrix
464 QString f1 = QFileDialog::getSaveFileName(this, tr("Save Transformation Matrix File"),
465 mMainWindow->GetInputPathName(),
466 tr("Text (*.mat *.txt *.doc *.rtf)"));
468 std::vector<QString> transparameters;
471 for(int i =0;i<4;i++)
473 transparameters.push_back(line1.setNum(mCurrentSlicerManager->GetImage()->GetTransform()->GetMatrix()->Element[i][j]));
475 if (file1.open(QFile::WriteOnly | QFile::Truncate)) {
476 QTextStream out1(&file1);
477 for(int i =0;i<4;i++){
478 for(int j=0;j<4;j++) {
479 out1<<transparameters[i*4+j]+"\t";
486 QMessageBox::information(this,"Warning","Error Reading Parameters");
489 //------------------------------------------------------------------------------
491 //------------------------------------------------------------------------------
492 void vvToolRigidReg::ReadFile()
496 double * orientations=new double[3];
497 double * translations=new double[3];
498 vtkMatrix4x4 *matrix=vtkMatrix4x4::New();
499 vtkSmartPointer<vtkTransform> transform = mCurrentSlicerManager->GetImage()->GetTransform();
501 //Open File to read the transformation parameters
502 QString file1 = QFileDialog::getOpenFileName(
504 "Choose the Transformation Parameters file",
505 mMainWindow->GetInputPathName(),
506 "Text (*.mat *.txt *.rtf *.doc)");
510 // ifstream readfile;
511 std::string transfile= file1.toStdString();
512 std::string filename1(transfile);
513 std::ifstream f1(filename1.c_str());
517 itk::Matrix<double, 4, 4> itkMat = clitk::ReadMatrix3D(transfile);
518 for(int j=0; j<4; j++)
519 for(int i=0; i<4; i++)
520 matrix->SetElement(i,j,itkMat[i][j]);
522 UpdateTextEditor(matrix,textEdit);
523 transform->SetMatrix(matrix);
524 transform->GetOrientation(orientations);
525 transform->PostMultiply();
527 //Obtain the Rotation Center , set it to origin
528 Xval->setText(center.setNum(0));
529 Yval->setText(center.setNum(0));
530 Zval->setText(center.setNum(0));
532 //In the Order or Y X Z //
533 //now postmultiply for the rotations
534 SetTransform(0,0,0,0,0,-rint(orientations[2]),false);
535 SetTransform(0,0,0,-rint(orientations[0]),0,0,false);
536 SetTransform(0,0,0,0,-rint(orientations[1]),0,false);
538 transform->GetPosition(translations);
539 transform->Identity();
541 DD(translations[0]/mInput1->GetImage()->GetSpacing()[0]);
542 DD(translations[1]/mInput1->GetImage()->GetSpacing()[1]);
543 DD(translations[2]/mInput1->GetImage()->GetSpacing()[2]);
547 //set the sliders and spin box values
548 InitializeSliders(rint(translations[0]),rint(translations[1])
549 ,rint(translations[2]),rint(orientations[0]),rint(orientations[1]),rint(orientations[2]),true);
550 SetTransform(matrix);
552 //------------------------------------------------------------------------------
554 //------------------------------------------------------------------------------
555 void vvToolRigidReg::ResetTransform()
557 vtkMatrix4x4 *matrix = vtkMatrix4x4::New();
560 matrix->SetElement(i,j,mInitialMatrix[i*4+j]);
561 SetTransform(matrix);
564 UpdateTextEditor(matrix,textEdit);
566 //------------------------------------------------------------------------------
568 //------------------------------------------------------------------------------
569 void vvToolRigidReg::SetRotationCenter()
571 //default image rotation center is the center of the image
572 QString xcord,ycord,zcord;
573 std::vector<double> imageorigin;
574 imageorigin=mInput1->GetImage()->GetOrigin();
576 xcord=xcord.setNum(imageorigin[0]+mImageSize[0]*mInput1->GetImage()->GetSpacing()[0]/2, 'g', 3);
577 ycord=ycord.setNum(imageorigin[1]+mImageSize[1]*mInput1->GetImage()->GetSpacing()[1]/2, 'g', 3);
578 zcord=zcord.setNum(imageorigin[2]+mImageSize[2]*mInput1->GetImage()->GetSpacing()[2]/2, 'g', 3);
580 Xval->setText(xcord);
581 Yval->setText(ycord);
582 Zval->setText(zcord);
583 InitializeSliders(0,0,0,0,0,0,true);
585 //------------------------------------------------------------------------------
587 //------------------------------------------------------------------------------
588 void vvToolRigidReg::InitializeSliders(double xtrans,double ytrans, double ztrans, double xrot, double yrot, double zrot,bool sliders)
591 xtrans_sb->blockSignals(true);
592 xtrans_sb->setSingleStep(mInput1->GetImage()->GetSpacing()[0]);
593 xtrans_sb->setValue(xtrans);
594 xtrans_sb->blockSignals(false);
595 ytrans_sb->blockSignals(true);
596 ytrans_sb->setSingleStep(mInput1->GetImage()->GetSpacing()[1]);
597 ytrans_sb->setValue(ytrans);
598 ytrans_sb->blockSignals(false);
599 ztrans_sb->blockSignals(true);
600 ztrans_sb->setSingleStep(mInput1->GetImage()->GetSpacing()[2]);
601 ztrans_sb->setValue(ztrans);
602 ztrans_sb->blockSignals(false);
605 xtrans_slider->blockSignals(true);
606 xtrans_slider->setValue(rint(xtrans));
607 xtrans_slider->blockSignals(false);
608 ytrans_slider->blockSignals(true);
609 ytrans_slider->setValue(rint(ytrans));
610 ytrans_slider->blockSignals(false);
611 ztrans_slider->blockSignals(true);
612 ztrans_slider->setValue(rint(ztrans));
613 ztrans_slider->blockSignals(false);
615 xrot_sb->blockSignals(true);
616 xrot_sb->setValue(xrot);
617 xrot_sb->blockSignals(false);
618 yrot_sb->blockSignals(true);
619 yrot_sb->setValue(yrot);
620 yrot_sb->blockSignals(false);
621 zrot_sb->blockSignals(true);
622 zrot_sb->setValue(zrot);
623 zrot_sb->blockSignals(false);
624 xrot_slider->blockSignals(true);
625 xrot_slider->setValue(xrot);
626 xrot_slider->blockSignals(false);
627 yrot_slider->blockSignals(true);
628 yrot_slider->setValue(yrot);
629 yrot_slider->blockSignals(false);
630 zrot_slider->blockSignals(true);
631 zrot_slider->setValue(zrot);
632 zrot_slider->blockSignals(false);
634 //------------------------------------------------------------------------------
636 //------------------------------------------------------------------------------
637 void vvToolRigidReg::SetSliderRanges()
639 xtrans_slider->blockSignals(true);
640 xtrans_slider->setRange(-2000,2000);
641 xtrans_slider->blockSignals(false);
643 ytrans_slider->blockSignals(true);
644 ytrans_slider->setRange(-2000,2000);
645 ytrans_slider->blockSignals(false);
647 ztrans_slider->blockSignals(true);
648 ztrans_slider->setRange(-2000,2000);
649 ztrans_slider->blockSignals(false);
651 xtrans_sb->blockSignals(true);
652 xtrans_sb->setRange(-2000,2000);
653 xtrans_sb->setDecimals(3);
654 xtrans_sb->blockSignals(false);
656 ytrans_sb->blockSignals(true);
657 ytrans_sb->setRange(-2000,2000);
658 ytrans_sb->setDecimals(3);
659 ytrans_sb->blockSignals(false);
661 ztrans_sb->blockSignals(true);
662 ztrans_sb->setRange(-2000,2000);
663 ztrans_sb->setDecimals(3);
664 ztrans_sb->blockSignals(false);
666 xrot_slider->blockSignals(true);
667 xrot_slider->setRange(-360,360);
668 xrot_slider->blockSignals(false);
670 yrot_slider->blockSignals(true);
671 yrot_slider->setRange(-360,360);
672 yrot_slider->blockSignals(false);
674 zrot_slider->blockSignals(true);
675 zrot_slider->setRange(-360,360);
676 zrot_slider->blockSignals(false);
678 xrot_sb->blockSignals(true);
679 xrot_sb->setRange(-360,360);
680 xrot_sb->blockSignals(false);
682 yrot_sb->blockSignals(true);
683 yrot_sb->setRange(-360,360);
684 yrot_sb->blockSignals(false);
686 zrot_sb->blockSignals(true);
687 zrot_sb->setRange(-360,360);
688 zrot_sb->blockSignals(false);