Fraxinus  16.5.0-fx-rc1
An IGT application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
cxLapFrameToolCalibrationWidget.cpp
Go to the documentation of this file.
1 /*=========================================================================
2 This file is part of CustusX, an Image Guided Therapy Application.
3 
4 Copyright (c) 2008-2014, SINTEF Department of Medical Technology
5 All rights reserved.
6 
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are met:
9 
10 1. Redistributions of source code must retain the above copyright notice,
11  this list of conditions and the following disclaimer.
12 
13 2. Redistributions in binary form must reproduce the above copyright notice,
14  this list of conditions and the following disclaimer in the documentation
15  and/or other materials provided with the distribution.
16 
17 3. Neither the name of the copyright holder nor the names of its contributors
18  may be used to endorse or promote products derived from this software
19  without specific prior written permission.
20 
21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
25 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 =========================================================================*/
32 
33 
35 
36 #include <QPushButton>
37 #include <QTextStream>
38 #include <QFileDialog>
39 #include <QMessageBox>
40 #include "cxTypeConversions.h"
41 #include "cxLogger.h"
42 #include "cxTrackingService.h"
43 #include "cxVector3D.h"
44 #include "cxDefinitionStrings.h"
46 #include "cxTool.h"
47 #include "cxTrackingService.h"
48 #include <cxActiveToolWidget.h>
49 #include "cxDoubleWidgets.h"
50 #include "cxVisServices.h"
52 
53 namespace cx
54 {
55 
56 //------------------------------------------------------------------------------
58  BaseWidget(parent, "LapFrameToolCalibrationWidget", "LapFrame Calibrate"),
59  mServices(services),
60  mCalibrateButton(new QPushButton("Calibrate")),
61  mReferencePointLabel(new QLabel("Ref. point:")),
62  mTestButton(new QPushButton("Test calibration")),
63  mCalibrationLabel(new QLabel("Calibration: \n")),
64  mDeltaLabel(new QLabel("Delta:"))
65 {
66  QVBoxLayout* toplayout = new QVBoxLayout(this);
67 
68  mCameraAngleAdapter = DoubleProperty::initialize("Camera Angle", "",
69  "Additional tilt of calibration around tool y-axis,\nfor use with cameras tilted relative to tool direction",
70  0.0, DoubleRange(-M_PI/2, M_PI/2, M_PI/180), 0);
71  mCameraAngleAdapter->setInternal2Display(180.0/M_PI);
72 
73  mCalibRefTool = StringPropertySelectTool::New(mServices->tracking());
74  mCalibRefTool->setValueName("Calibration Frame");
75  mCalibRefTool->setHelp("Select Calibration Reference Frame");
76 
77  mCalibratingTool = StringPropertySelectTool::New(mServices->tracking());
78  mCalibratingTool->setValueName("Tool");
79  mCalibratingTool->setHelp("Select which Tool to calibrate");
80 
81  this->setToolTip("Calibrate tool matrix using a custom frame");
82 
83 // toplayout->addWidget(new QLabel("<b>Select a tool with a known reference point:</b>"));
84  toplayout->addWidget(new LabeledComboBoxWidget(this, mCalibRefTool));
85  toplayout->addWidget(mReferencePointLabel);
86  toplayout->addWidget(new LabeledComboBoxWidget(this, mCalibratingTool));
87 // toplayout->addWidget(new ActiveToolWidget(this));
88  toplayout->addWidget(new SpinBoxAndSliderGroupWidget(this, mCameraAngleAdapter));
89  toplayout->addWidget(mCalibrateButton);
90  toplayout->addWidget(mCalibrationLabel);
91  toplayout->addWidget(this->createHorizontalLine());
92  toplayout->addWidget(mTestButton);
93  toplayout->addWidget(mDeltaLabel);
94  toplayout->addStretch();
95 
96  mReferencePointLabel->setText("<i> Use only with the special Laparascopic <br>"
97  "calibration frame as reference. </i>");
98 
99  connect(mCalibrateButton, SIGNAL(clicked()), this, SLOT(calibrateSlot()));
100  connect(mTestButton, SIGNAL(clicked()), this, SLOT(testCalibrationSlot()));
101 
102  connect(mCalibRefTool.get(), SIGNAL(changed()), this, SLOT(toolSelectedSlot()));
103 
104  //setting default state
105  this->toolSelectedSlot();
106 
107  connect(mServices->tracking().get(), &cx::TrackingService::stateChanged, this, &LapFrameToolCalibrationWidget::trackingStartedSlot);
108 }
109 
111 {}
112 
113 void LapFrameToolCalibrationWidget::calibrateSlot()
114 {
115  ToolPtr refTool = mCalibRefTool->getTool();
116  ToolPtr tool = mCalibratingTool->getTool();
117  double cameraAngle = mCameraAngleAdapter->getValue();
118  if(!refTool || !tool)
119  {
120  reportError(QString("Calibration prerequisited not met: calref:%1, tool:%2").arg(refTool!=0).arg(tool!=0) );
121  return;
122  }
123  if(!refTool->getVisible() || !tool->getVisible() || !refTool->hasReferencePointWithId(1))
124  {
125  reportError(QString("Calibration prerequisited not met: calref vis:%1, tool vis :%2, refpoint:%3").arg(refTool->getVisible()).arg(tool->getVisible()).arg(refTool->hasReferencePointWithId(1)) );
126  return;
127  }
128 
129  LapFrameToolCalibrationCalculator calc(tool, refTool, cameraAngle);
130  Transform3D calibration = calc.get_calibration_sMt();
131 
132  QMessageBox msgBox;
133  msgBox.setText("Do you want to overwrite "+tool->getName()+"'s calibration file?");
134  msgBox.setInformativeText("This cannot be undone.");
135  msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
136  msgBox.setDefaultButton(QMessageBox::Ok);
137  int ret = msgBox.exec();
138 
139  if(ret == QMessageBox::Ok)
140  {
141  tool->setCalibration_sMt(calibration);
142 // std::stringstream ss;
143 // ss << calibration.matrix().format(Eigen::IOFormat()) << std::endl;
144  mCalibrationLabel->setText(QString("Calibration matrix for %1:\n%2").arg(tool->getName(), qstring_cast(calibration)));
145  }
146 }
147 
148 void LapFrameToolCalibrationWidget::testCalibrationSlot()
149 {
150  ToolPtr refTool = mCalibRefTool->getTool();
151  ToolPtr tool = mCalibratingTool->getTool();
152  double cameraAngle = mCameraAngleAdapter->getValue();
153 
154  if(!refTool || !tool || !refTool->hasReferencePointWithId(1))
155  return;
156 
157  LapFrameToolCalibrationCalculator calc(tool, refTool, cameraAngle);
158  Vector3D delta_selectedTool = calc.get_delta_ref();
159 
160  QString delta = QString("%1 mm").arg(delta_selectedTool.length(), 6, 'g', 1);
161  mDeltaLabel->setText("<b>Delta "+tool->getName()+":</b> "+qstring_cast(delta_selectedTool)+" <br> <b>Accuracy:</b> " + delta);
162 
163  report("Delta "+tool->getName()+": "+qstring_cast(delta_selectedTool)+" Length: "+ delta);
164 
165 
166 }
167 
168 void LapFrameToolCalibrationWidget::toolSelectedSlot()
169 {
170  // QString text("Ref. point: <UNDEFINED POINT>");
171  mCalibrateButton->setEnabled(false);
172  mTestButton->setEnabled(false);
173 
174  if (mCalibRefTool->getTool())
175  {
176 // mCalibrationLabel->setText("Calibration:\n" + qstring_cast(mCalibratingTool->getTool()->getCalibration_sMt()));
177 // Transform3D calibration = mCalibratingTool->getTool()->getCalibration_sMt();
178 // mCalibrationLabel->setText(QString("Calibration matrix for %1:\n%2").arg(tool->getName(), qstring_cast(calibration)));
179  mCalibrateButton->setEnabled(true);
180  mTestButton->setEnabled(true);
181  }
182 
183  // mReferencePointLabel->setText(text);
184 }
185 //------------------------------------------------------------------------------
186 
187 void LapFrameToolCalibrationWidget::trackingStartedSlot()
188 {
189  ToolPtr ref = mServices->tracking()->getTool("calibration_tool");
190  if (ref)
191  mCalibRefTool->setValue(ref->getUid());
192 }
193 
194 //------------------------------------------------------------------------------
195 //------------------------------------------------------------------------------
196 //------------------------------------------------------------------------------
197 
198 
199 
200 
202  mTool(tool), mCalibrationRef(calRef), mCameraAngle(cameraAngle)
203 {
204  m_sMpr = mTool->getCalibration_sMt() * mTool->get_prMt().inv();
205 
206 // m_qMcr = Transform3D::fromString(" 0.0, 0.0, -1.0, -71.5,"
207 // " 0.0, -1.0, 0.0, -8.0,"
208 // "-1.0, 0.0, 0.0, -8.8,"
209 // " 0.0, 0.0, 0.0, 1.0");
210 
211  m_qMcr = Transform3D::Identity();
212  m_qMpr = m_qMcr * mCalibrationRef->get_prMt().inv();
213 }
214 
216 {
217  Vector3D p(0,0,0);
218  Transform3D qMpr = m_qMcr * mCalibrationRef->get_prMt().inv();
219 
220  Vector3D calibPoint_pr = qMpr.inv().coord(p);
221  Vector3D toolPoint_pr = mTool->get_prMt().coord(p);
222  return calibPoint_pr - toolPoint_pr;
223 }
224 
226 {
227  return m_sMpr * m_qMpr.inv() * createTransformRotateY(mCameraAngle);
228 }
229 
230 
231 }
QString qstring_cast(const T &val)
Transform3D createTransformRotateY(const double angle)
void reportError(QString msg)
Definition: cxLogger.cpp:92
boost::shared_ptr< class VisServices > VisServicesPtr
Definition: cxMainWindow.h:62
Transform3D Transform3D
Transform3D is a representation of an affine 3D transform.
Utility class for describing a bounded numeric range.
Definition: cxDoubleRange.h:53
Transform3D get_calibration_sMt()
new calibration matrix for the input tool.
Vector3D get_delta_ref()
how far from the reference point the sampled point is, in pr's coord
Composite widget for string selection.
Composite widget for scalar data manipulation.
static QFrame * createHorizontalLine()
Creates a horizontal line which can be inserted into widgets.
Eigen::Vector3d Vector3D
Vector3D is a representation of a point or vector in 3D.
Definition: cxVector3D.h:63
Interface for QWidget which handles widgets uniformly for the system.
Definition: cxBaseWidget.h:108
static StringPropertySelectToolPtr New(TrackingServicePtr trackingService)
void report(QString msg)
Definition: cxLogger.cpp:90
static DoublePropertyPtr initialize(const QString &uid, QString name, QString help, double value, DoubleRange range, int decimals, QDomNode root=QDomNode())
LapFrameToolCalibrationWidget(VisServicesPtr services, QWidget *parent)
LapFrameToolCalibrationCalculator(ToolPtr tool, ToolPtr calRef, double cameraAngle)
#define M_PI
boost::shared_ptr< class Tool > ToolPtr