Fraxinus  2023.01.05-dev+develop.0da12
An IGT application
cxBronchoscopyRegistrationWidget.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) SINTEF Department of Medical Technology.
5 All rights reserved.
6 
7 CustusX is released under a BSD 3-Clause license.
8 
9 See Lisence.txt (https://github.com/SINTEFMedtek/CustusX/blob/master/License.txt) for details.
10 =========================================================================*/
11 
13 #include <vtkPolyData.h>
14 #include "cxTransform3D.h"
15 #include "cxDataSelectWidget.h"
16 #include "cxTrackingService.h"
17 #include "cxMesh.h"
19 #include "cxRecordSessionWidget.h"
20 #include "cxRecordSession.h"
21 #include "cxView.h"
22 #include "cxToolRep3D.h"
23 #include "cxToolTracer.h"
25 #include "cxLogger.h"
26 #include "cxTypeConversions.h"
27 #include "cxPatientModelService.h"
28 #include "cxRegistrationService.h"
29 #include "cxViewService.h"
30 #include "cxStringProperty.h"
32 #include "cxTrackingService.h"
33 #include "cxDoubleProperty.h"
34 #include "cxProfile.h"
35 #include "cxHelperWidgets.h"
36 #include "cxBoolProperty.h"
37 #include "cxCheckBoxWidget.h"
38 #include "cxRepContainer.h"
40 #include "cxViewGroupData.h"
42 #include "cxHelperWidgets.h"
43 #include "cxAcquisitionService.h"
44 #include "cxRegServices.h"
45 #include "cxRecordTrackingWidget.h"
46 
47 
48 namespace cx
49 {
51  RegistrationBaseWidget(services, parent, "org_custusx_registration_method_bronchoscopy_widget",
52  "Bronchoscopy Registration"),
53  mBronchoscopyRegistration(new BronchoscopyRegistration()),
54  mServices(services),
55  mRecordTrackingWidget(NULL)
56 {
57  mVerticalLayout = new QVBoxLayout(this);
58 }
59 
61 {
62  if (!mRecordTrackingWidget)
63  {
64  this->setup();
65  }
66 }
67 
68 void BronchoscopyRegistrationWidget::setup()
69 {
70  mOptions = profile()->getXmlSettings().descend("bronchoscopyregistrationwidget");
71 
72  mSelectMeshWidget = StringPropertySelectMesh::New(mServices->patient());
73  mSelectMeshWidget->setValueName("Centerline: ");
74 
75  //this->initializeTrackingService();
76 
77  connect(mServices->patient().get(),&PatientModelService::patientChanged,this,&BronchoscopyRegistrationWidget::clearDataOnNewPatient);
78 
79  mProcessCenterlineButton = new QPushButton("Process centerline");
80  connect(mProcessCenterlineButton, SIGNAL(clicked()), this, SLOT(processCenterlineSlot()));
81  mProcessCenterlineButton->setToolTip(this->defaultWhatsThis());
82 
83  // mBronchoscopeRegistrationPtr = BronchoscopeRegistrationPtr(new BronchoscopePositionProjection());
84  // mProjectionCenterlinePtr->createMaxDistanceToCenterlineOption(mOptions.getElement());
85 
86  mRegisterButton = new QPushButton("Register");
87  connect(mRegisterButton, SIGNAL(clicked()), this, SLOT(registerSlot()));
88  mRegisterButton->setToolTip(this->defaultWhatsThis());
89 
90  mRecordTrackingWidget = new RecordTrackingWidget(mOptions.descend("recordTracker"),
91  mServices->acquisition(), mServices,
92  "bronc_path",
93  this);
94  mRecordTrackingWidget->getSessionSelector()->setHelp("Select bronchoscope path for registration");
95  mRecordTrackingWidget->getSessionSelector()->setDisplayName("Bronchoscope path");
96 
97  mVerticalLayout->setMargin(0);
98  mVerticalLayout->addWidget(new DataSelectWidget(mServices->view(), mServices->patient(), this, mSelectMeshWidget));
99 
100  this->selectSubsetOfBranches(mOptions.getElement());
101  this->createMaxNumberOfGenerations(mOptions.getElement());
102  this->useEBUSprobe(mOptions.getElement());
103  this->useLocalRegistration(mOptions.getElement());
104  this->createMaxLocalRegistrationDistance(mOptions.getElement());
105 
106  // PropertyPtr maxLocalRegistrationDistance = mProjectionCenterlinePtr->getMaxLocalRegistrationDistanceOption();
107 
108  mVerticalLayout->addWidget(new CheckBoxWidget(this, mUseSubsetOfGenerations));
109  mVerticalLayout->addWidget(createDataWidget(mServices->view(), mServices->patient(), this, mMaxNumberOfGenerations));
110  mVerticalLayout->addWidget(mProcessCenterlineButton);
111  mVerticalLayout->addWidget(new CheckBoxWidget(this, mUseEBUSProbe));
112  mVerticalLayout->addWidget(mRecordTrackingWidget);
113  mVerticalLayout->addWidget(new CheckBoxWidget(this, mUseLocalRegistration));
114  mVerticalLayout->addWidget(createDataWidget(mServices->view(), mServices->patient(), this, mMaxLocalRegistrationDistance));
115  mVerticalLayout->addWidget(mRegisterButton);
116 
117  mVerticalLayout->addStretch();
118 }
119 
121 {
122  return QString();
123 }
124 
125 void BronchoscopyRegistrationWidget::initializeTrackingService()
126 {
127  if(mServices->tracking()->getState() < Tool::tsCONFIGURED)
128  mServices->tracking()->setState(Tool::tsCONFIGURED);
129 }
130 
131 void BronchoscopyRegistrationWidget::processCenterlineSlot()
132 {
133  this->initializeTrackingService();
134 
135  if(!mSelectMeshWidget->getMesh())
136  {
137  reportError("No centerline");
138  return;
139  }
140  vtkPolyDataPtr centerline = mSelectMeshWidget->getMesh()->getVtkPolyData();//input
141  Transform3D rMd = mSelectMeshWidget->getMesh()->get_rMd();
142  vtkPolyDataPtr processedCenterline;
143  if (mUseSubsetOfGenerations->getValue())
144  processedCenterline = mBronchoscopyRegistration->processCenterline(centerline, rMd, mMaxNumberOfGenerations->getValue());
145  else
146  processedCenterline = mBronchoscopyRegistration->processCenterline(centerline, rMd);
147 
148  if (!mMesh)
149  {
150  QString uid = mSelectMeshWidget->getMesh()->getUid() + "_cl%1";
151  QString name = mSelectMeshWidget->getMesh()->getName()+" cl_processed%1";
152  std::cout << "name: " << name << std::endl;
153  std::cout << "uid: " << uid << std::endl;
154  mMesh = mServices->patient()->createSpecificData<Mesh>(uid, name);
155  }
156  mMesh->setVtkPolyData(processedCenterline);
157  mMesh->setColor(QColor(0, 0, 255, 255));
158  mServices->patient()->insertData(mMesh);
159  mServices->view()->autoShowData(mMesh);
160 }
161 
162 void BronchoscopyRegistrationWidget::registerSlot()
163 {
164  if(!mBronchoscopyRegistration->isCenterlineProcessed())
165  {
166  reportError("Centerline not processed");
167  return;
168  }
169 
170  Transform3D old_rMpr = mServices->patient()->get_rMpr();//input to registrationAlgorithm
171  //std::cout << "rMpr: " << std::endl;
172  //std::cout << old_rMpr << std::endl;
173 
174  TimedTransformMap trackerRecordedData;
175  if(mUseEBUSProbe->getValue())
176  trackerRecordedData = mRecordTrackingWidget->getRecordedTrackerData_prMs();
177  else
178  trackerRecordedData = mRecordTrackingWidget->getRecordedTrackerData_prMt();
179 
180  if(trackerRecordedData.empty())
181  {
182  reportError("No positions");
183  return;
184  }
185 
186  Transform3D new_rMpr;
187 
188  if(mUseLocalRegistration->getValue()){
189  std::cout << "Running local registration with max distance " << mMaxLocalRegistrationDistance->getValue() << " mm." << std::endl;
190  new_rMpr = Transform3D(mBronchoscopyRegistration->runBronchoscopyRegistration(trackerRecordedData,old_rMpr,mMaxLocalRegistrationDistance->getValue()));
191  }
192  else{
193  std::cout << "Running global registration." << std::endl;
194  new_rMpr = Transform3D(mBronchoscopyRegistration->runBronchoscopyRegistration(trackerRecordedData,old_rMpr,0));
195  }
196 
197  new_rMpr = new_rMpr*old_rMpr;//output
198  mServices->registration()->addPatientRegistration(new_rMpr, "Bronchoscopy centerline to tracking data");
199 
200  Eigen::Matrix4d display_rMpr = Eigen::Matrix4d::Identity();
201  display_rMpr = new_rMpr*display_rMpr;
202  std::cout << "New prMt: " << std::endl;
203  for (int i = 0; i < 4; i++)
204  std::cout << display_rMpr.row(i) << std::endl;
205 
206  // mRecordTrackingWidget->showSelectedRecordingInView();
207 
208 }
209 
210 void BronchoscopyRegistrationWidget::createMaxNumberOfGenerations(QDomElement root)
211 {
212  mMaxNumberOfGenerations = DoubleProperty::initialize("Max number of generations in centerline", "",
213  "Set max number of generations centerline", 4, DoubleRange(0, 10, 1), 0,
214  root);
215  mMaxNumberOfGenerations->setGuiRepresentation(DoublePropertyBase::grSLIDER);
216 }
217 
218 void BronchoscopyRegistrationWidget::selectSubsetOfBranches(QDomElement root)
219 {
220  mUseSubsetOfGenerations = BoolProperty::initialize("Select branch generations to be used in registration", "",
221  "Select branch generations to be used in registration", false,
222  root);
223 }
224 
225 void BronchoscopyRegistrationWidget::useEBUSprobe(QDomElement root)
226 {
227  mUseEBUSProbe = BoolProperty::initialize("EBUS probe", "",
228  "Select if EBUS probe is used registration (using prMs to exclude probe calibration)", false,
229  root);
230 }
231 
232 void BronchoscopyRegistrationWidget::useLocalRegistration(QDomElement root)
233 {
234  mUseLocalRegistration = BoolProperty::initialize("Use local registration", "",
235  "Use local registration", false,
236  root);
237 }
238 
239 void BronchoscopyRegistrationWidget::createMaxLocalRegistrationDistance(QDomElement root)
240 {
241  mMaxLocalRegistrationDistance = DoubleProperty::initialize("Max local registration distance (mm)", "",
242  "Set max distance for local registration in mm", 30, DoubleRange(1, 200, 1), 0,
243  root);
244  mMaxLocalRegistrationDistance->setGuiRepresentation(DoubleProperty::grSLIDER);
245 }
246 
247 void BronchoscopyRegistrationWidget::clearDataOnNewPatient()
248 {
249  mMesh.reset();
250 }
251 } //namespace cx
cxResource_EXPORT ProfilePtr profile()
Definition: cxProfile.cpp:160
static BoolPropertyPtr initialize(const QString &uid, QString name, QString help, bool value, QDomNode root=QDomNode())
void reportError(QString msg)
Definition: cxLogger.cpp:71
A mesh data set.
Definition: cxMesh.h:45
Transform3D Transform3D
Transform3D is a representation of an affine 3D transform.
Widget for the BoolPropertyBase.
Utility class for describing a bounded numeric range.
Definition: cxDoubleRange.h:32
TimedTransformMap getRecordedTrackerData_prMt()
StringPropertyPtr getSessionSelector()
QDomElement getElement()
return the current element
configured with basic info
Definition: cxTool.h:75
QWidget * createDataWidget(ViewServicePtr viewService, PatientModelServicePtr patientModelService, QWidget *parent, PropertyPtr data, QGridLayout *gridLayout, int row)
Create a widget capable of displaying the input data.
BronchoscopyRegistrationWidget(RegServicesPtr services, QWidget *parent)
boost::shared_ptr< class RegServices > RegServicesPtr
Definition: cxRegServices.h:20
vtkSmartPointer< vtkPolyData > vtkPolyDataPtr
TimedTransformMap getRecordedTrackerData_prMs()
static DoublePropertyPtr initialize(const QString &uid, QString name, QString help, double value, DoubleRange range, int decimals, QDomNode root=QDomNode())
static StringPropertySelectMeshPtr New(PatientModelServicePtr patientModelService)
std::map< double, Transform3D > TimedTransformMap
XmlOptionFile descend(QString element) const
step one level down in the xml tree
Namespace for all CustusX production code.