CustusX  15.3.4-beta
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->getToolManager());
74  mCalibRefTool->setValueName("Calibration Frame");
75  mCalibRefTool->setHelp("Select Calibration Reference Frame");
76 
77  mCalibratingTool = StringPropertySelectTool::New(mServices->getToolManager());
78  mCalibratingTool->setValueName("Tool");
79  mCalibratingTool->setHelp("Select which Tool to calibrate");
80 
81  this->setToolTip(this->defaultWhatsThis());
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->getToolManager().get(), &cx::TrackingService::stateChanged, this, &LapFrameToolCalibrationWidget::trackingStartedSlot);
108 }
109 
111 {}
112 
114 {
115  return "<html>"
116  "<h3>Laparascopic tool calibration</h3>"
117  "<p><i>Calibrates a tool by sampling it when it is inserted into the slot of the custom-made calibration frame.</i></br>"
118  "<p><i>The tool to be calibrated will have its calibration set in such a way that the calibrating and calibrated tools"
119  "are in the same position.</i></br>"
120  "<p>By using the test button you can test your calibration by pointing at a known reference point.</br></p>"
121  "</html>";
122 }
123 
124 void LapFrameToolCalibrationWidget::calibrateSlot()
125 {
126  ToolPtr refTool = mCalibRefTool->getTool();
127  ToolPtr tool = mCalibratingTool->getTool();
128  double cameraAngle = mCameraAngleAdapter->getValue();
129  if(!refTool || !tool)
130  {
131  reportError(QString("Calibration prerequisited not met: calref:%1, tool:%2").arg(refTool!=0).arg(tool!=0) );
132  return;
133  }
134  if(!refTool->getVisible() || !tool->getVisible() || !refTool->hasReferencePointWithId(1))
135  {
136  reportError(QString("Calibration prerequisited not met: calref vis:%1, tool vis :%2, refpoint:%3").arg(refTool->getVisible()).arg(tool->getVisible()).arg(refTool->hasReferencePointWithId(1)) );
137  return;
138  }
139 
140  LapFrameToolCalibrationCalculator calc(tool, refTool, cameraAngle);
141  Transform3D calibration = calc.get_calibration_sMt();
142 
143  QMessageBox msgBox;
144  msgBox.setText("Do you want to overwrite "+tool->getName()+"'s calibration file?");
145  msgBox.setInformativeText("This cannot be undone.");
146  msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
147  msgBox.setDefaultButton(QMessageBox::Ok);
148  int ret = msgBox.exec();
149 
150  if(ret == QMessageBox::Ok)
151  {
152  tool->setCalibration_sMt(calibration);
153 // std::stringstream ss;
154 // ss << calibration.matrix().format(Eigen::IOFormat()) << std::endl;
155  mCalibrationLabel->setText(QString("Calibration matrix for %1:\n%2").arg(tool->getName(), qstring_cast(calibration)));
156  }
157 }
158 
159 void LapFrameToolCalibrationWidget::testCalibrationSlot()
160 {
161  ToolPtr refTool = mCalibRefTool->getTool();
162  ToolPtr tool = mCalibratingTool->getTool();
163  double cameraAngle = mCameraAngleAdapter->getValue();
164 
165  if(!refTool || !tool || !refTool->hasReferencePointWithId(1))
166  return;
167 
168  LapFrameToolCalibrationCalculator calc(tool, refTool, cameraAngle);
169  Vector3D delta_selectedTool = calc.get_delta_ref();
170 
171  QString delta = QString("%1 mm").arg(delta_selectedTool.length(), 6, 'g', 1);
172  mDeltaLabel->setText("<b>Delta "+tool->getName()+":</b> "+qstring_cast(delta_selectedTool)+" <br> <b>Accuracy:</b> " + delta);
173 
174  report("Delta "+tool->getName()+": "+qstring_cast(delta_selectedTool)+" Length: "+ delta);
175 
176 
177 }
178 
179 void LapFrameToolCalibrationWidget::toolSelectedSlot()
180 {
181  // QString text("Ref. point: <UNDEFINED POINT>");
182  mCalibrateButton->setEnabled(false);
183  mTestButton->setEnabled(false);
184 
185  if (mCalibRefTool->getTool())
186  {
187 // mCalibrationLabel->setText("Calibration:\n" + qstring_cast(mCalibratingTool->getTool()->getCalibration_sMt()));
188 // Transform3D calibration = mCalibratingTool->getTool()->getCalibration_sMt();
189 // mCalibrationLabel->setText(QString("Calibration matrix for %1:\n%2").arg(tool->getName(), qstring_cast(calibration)));
190  mCalibrateButton->setEnabled(true);
191  mTestButton->setEnabled(true);
192  }
193 
194  // mReferencePointLabel->setText(text);
195 }
196 //------------------------------------------------------------------------------
197 
198 void LapFrameToolCalibrationWidget::trackingStartedSlot()
199 {
200  ToolPtr ref = mServices->getToolManager()->getTool("calibration_tool");
201  if (ref)
202  mCalibRefTool->setValue(ref->getUid());
203 }
204 
205 //------------------------------------------------------------------------------
206 //------------------------------------------------------------------------------
207 //------------------------------------------------------------------------------
208 
209 
210 
211 
213  mTool(tool), mCalibrationRef(calRef), mCameraAngle(cameraAngle)
214 {
215  m_sMpr = mTool->getCalibration_sMt() * mTool->get_prMt().inv();
216 
217 // m_qMcr = Transform3D::fromString(" 0.0, 0.0, -1.0, -71.5,"
218 // " 0.0, -1.0, 0.0, -8.0,"
219 // "-1.0, 0.0, 0.0, -8.8,"
220 // " 0.0, 0.0, 0.0, 1.0");
221 
222  m_qMcr = Transform3D::Identity();
223  m_qMpr = m_qMcr * mCalibrationRef->get_prMt().inv();
224 }
225 
227 {
228  Vector3D p(0,0,0);
229  Transform3D qMpr = m_qMcr * mCalibrationRef->get_prMt().inv();
230 
231  Vector3D calibPoint_pr = qMpr.inv().coord(p);
232  Vector3D toolPoint_pr = mTool->get_prMt().coord(p);
233  return calibPoint_pr - toolPoint_pr;
234 }
235 
237 {
238  return m_sMpr * m_qMpr.inv() * createTransformRotateY(mCameraAngle);
239 }
240 
241 
242 }
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:61
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
virtual QString defaultWhatsThis() const
Returns a short description of what this widget will do for you.
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