PlusLib  2.9.0
Software library for tracked ultrasound image acquisition, calibration, and processing.
vtkRevopoint3DCameraTest.cxx
Go to the documentation of this file.
1 /*=Plus=header=begin======================================================
2  Program: Plus
3  Copyright (c) Laboratory for Percutaneous Surgery. All rights reserved.
4  See License.txt for details.
5 
6  Developed by MACBIOIDI & IACTEC group
7 =========================================================Plus=header=end*/
8 
9 #include "PlusConfigure.h"
10 #include "vtkCallbackCommand.h"
11 #include "vtkCommand.h"
12 #include "vtkPlusDataSource.h"
13 #include "vtkSmartPointer.h"
15 #include "vtksys/CommandLineArguments.hxx"
16 #include "vtksys/SystemTools.hxx"
17 #include "vtkImageData.h"
18 #include "vtkImageViewer.h"
19 #include "vtkInformation.h"
20 #include "vtkInformationVector.h"
21 #include "vtkRenderWindow.h"
22 #include "vtkRenderWindowInteractor.h"
23 #include "vtkRenderer.h"
24 #include "vtkRendererCollection.h"
25 #include "vtkPolyDataMapper.h"
26 #include "vtkPolyData.h"
27 #include "vtkPoints.h"
28 #include "vtkVertexGlyphFilter.h"
29 #include "vtkPointData.h"
30 #include "vtkActor.h"
31 #include "igtlOSUtil.h"
32 
33 void PrintLogsCallback(vtkObject* obj, unsigned long eid, void* clientdata, void* calldata);
34 
35 namespace
36 {
37  class vtkMyImageViewerCallback : public vtkCommand
38  {
39  public:
40  static vtkMyImageViewerCallback* New()
41  {
42  return new vtkMyImageViewerCallback;
43  }
44 
45  virtual void Execute(vtkObject* caller, unsigned long, void*)
46  {
47  if (m_Channel->GetVideoDataAvailable())
48  {
49  m_Viewer->SetInputData(m_Channel->GetBrightnessOutput());
50  }
51 
52  //update the timer so it will trigger again
53  m_Viewer->Render();
54  m_Interactor->CreateTimer(VTKI_TIMER_UPDATE);
55  }
56 
57  vtkRenderWindowInteractor* m_Interactor{nullptr};
58  vtkImageViewer* m_Viewer{nullptr};
59  vtkPlusChannel* m_Channel{nullptr};
60  };
61  class vtkMyMeshViewerCallback : public vtkCommand
62  {
63  public:
64  static vtkMyMeshViewerCallback* New()
65  {
66  return new vtkMyMeshViewerCallback;
67  }
68 
69  virtual void Execute(vtkObject* caller, unsigned long, void*)
70  {
71  static bool firstDisplay{true};
72 
73  if (m_Channel->GetVideoDataAvailable())
74  {
75  m_Mapper->SetInputData(ConvertToPCL(m_Channel->GetBrightnessOutput()));
76  m_Mapper->Modified();
77 
78  if (firstDisplay)
79  {
80  m_Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->ResetCamera();
81  firstDisplay = false;
82  }
83  }
84 
85  m_Interactor->Render();
86  }
87 
88  vtkRenderWindowInteractor* m_Interactor{nullptr};
89  vtkPlusChannel* m_Channel{nullptr};
90  vtkPolyDataMapper* m_Mapper{nullptr};
91 
92  private:
93  vtkSmartPointer<vtkPolyData> ConvertToPCL(vtkImageData* imageData)
94  {
95  if (imageData->GetNumberOfScalarComponents() != 3)
96  {
97  return nullptr;
98  }
99 
100  int* dims = imageData->GetDimensions();
101  vtkNew<vtkPoints> points;
102 
103  for (int x = 0; x < dims[0]; x++)
104  {
105  for (int y = 0; y < dims[1]; y++)
106  {
107  for (int z = 0; z < dims[2]; z++)
108  {
109  auto* coords =
110  static_cast<float*>(imageData->GetScalarPointer(x, y, z));
111 
112  if (coords[2] == 0)
113  {
114  continue;
115  }
116 
117  points->InsertNextPoint(coords[0], coords[1], coords[2]);
118  }
119  }
120  }
121 
122  vtkNew<vtkPolyData> poly;
123  poly->SetPoints(points);
124 
125  vtkNew<vtkVertexGlyphFilter> vertexGenerator;
126  vertexGenerator->SetInputData(poly);
127  vertexGenerator->Update();
128 
129  return vertexGenerator->GetOutput();
130  }
131  };
132 }
133 
134 int main(int argc, char** argv)
135 {
136 
137  bool printHelp(false);
138  std::string inputConfigFileName = "Testing/PlusDeviceSet_DataCollectionOnly_Revopoint3DCamera.xml";
139 
140  vtksys::CommandLineArguments args;
141  args.Initialize(argc, argv);
142 
143  int verboseLevel = vtkPlusLogger::LOG_LEVEL_UNDEFINED;
144  bool renderingOff(false);
145 
146  args.AddArgument("--help", vtksys::CommandLineArguments::NO_ARGUMENT, &printHelp, "Print this help.");
147  args.AddArgument("--verbose", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &verboseLevel, "Verbose level (1=error only, 2=warning, 3=info, 4=debug, 5=trace)");
148  args.AddArgument("--config-file", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &inputConfigFileName, "Config file containing the device configuration.");
149  args.AddArgument("--rendering-off", vtksys::CommandLineArguments::NO_ARGUMENT, &renderingOff, "Run test without rendering.");
150 
151  if (!args.Parse())
152  {
153  std::cerr << "Problem parsing arguments" << std::endl;
154  std::cout << "\n\nHelp:" << args.GetHelp() << std::endl;
155  exit(EXIT_FAILURE);
156  }
157 
158  vtkPlusLogger::Instance()->SetLogLevel(verboseLevel);
159 
160  if (printHelp)
161  {
162  std::cout << "\n\nHelp:" << args.GetHelp() << std::endl;
163  exit(EXIT_SUCCESS);
164  }
165 
166  vtkNew<vtkPlusRevopoint3DCamera> revopoint3DCameraDevice;
167  revopoint3DCameraDevice->SetDeviceId("VideoDevice");
168 
169  if (!vtksys::SystemTools::FileExists(inputConfigFileName))
170  {
171  LOG_ERROR("Bad configuration file: " << inputConfigFileName);
172  exit(EXIT_FAILURE);
173  }
174 
175  LOG_DEBUG("Reading config file: " << inputConfigFileName);
176  auto* configRead = vtkXMLUtilities::ReadElementFromFile(inputConfigFileName.c_str());
177 
178  if (!configRead)
179  {
180  LOG_ERROR("Failed to read configuration file");
181  exit(EXIT_FAILURE);
182  }
183 
184  LOG_TRACE("Config file: " << *configRead);
185  if (revopoint3DCameraDevice->ReadConfiguration(configRead) != PLUS_SUCCESS)
186  {
187  LOG_ERROR("Failed to read configuration");
188  exit(EXIT_FAILURE);
189  }
190 
191  if (revopoint3DCameraDevice->NotifyConfigured() != PLUS_SUCCESS)
192  {
193  LOG_ERROR("Invalid configuration");
194  exit(EXIT_FAILURE);
195  }
196 
197  vtkPlusChannel* depthChannel{nullptr};
198  revopoint3DCameraDevice->GetOutputChannelByName(depthChannel, "VideoStreamDEPTH");
199 
200 
201  vtkPlusChannel* pclChannel{nullptr};
202  revopoint3DCameraDevice->GetOutputChannelByName(pclChannel, "VideoStreamPCL");
203 
204  vtkIndent indent;
205  revopoint3DCameraDevice->PrintSelf(std::cout, indent);
206 
207  // Add an observer to warning and error events for redirecting it to the stdout
208  vtkNew<vtkCallbackCommand> callbackCommand;
209  callbackCommand->SetCallback(PrintLogsCallback);
210  revopoint3DCameraDevice->AddObserver("WarningEvent", callbackCommand);
211  revopoint3DCameraDevice->AddObserver("ErrorEvent", callbackCommand);
212 
213  if (revopoint3DCameraDevice->Connect() != PLUS_SUCCESS)
214  {
215  LOG_ERROR("Failed to connect");
216  exit(EXIT_FAILURE);
217  }
218 
219  if (revopoint3DCameraDevice->StartRecording() != PLUS_SUCCESS)
220  {
221  LOG_INFO("Failed to start recording");
222  exit(EXIT_FAILURE);
223  }
224 
225  if (!renderingOff)
226  {
227  vtkNew<vtkImageViewer> imageViewer;
228  imageViewer->SetColorWindow(255);
229  imageViewer->SetColorLevel(127.5);
230  imageViewer->SetZSlice(0);
231 
232  // Create the interactor that handles the event loop
233  vtkNew<vtkRenderWindowInteractor> imageInteractor;
234  imageInteractor->SetRenderWindow(imageViewer->GetRenderWindow());
235  imageViewer->SetupInteractor(imageInteractor);
236 
237  imageViewer->Render(); //must be called after iren and viewer are linked or there will be problems
238 
239  // Establish timer event and create timer to update the live image
240  vtkNew<vtkMyImageViewerCallback> call;
241  call->m_Interactor = imageInteractor;
242  call->m_Viewer = imageViewer;
243  imageInteractor->AddObserver(vtkCommand::TimerEvent, call);
244  imageInteractor->CreateTimer(VTKI_TIMER_FIRST);
245 
246  // Display depth image
247  if (depthChannel)
248  {
249  call->m_Channel = depthChannel;
250  imageInteractor->Initialize();
251  imageInteractor->Start();
252  }
253 
254  imageInteractor->GetRenderWindow()->Finalize();
255 
256  // Display points cloud
257  if (pclChannel)
258  {
259  vtkNew<vtkRenderer> pclRenderer;
260  vtkNew<vtkRenderWindow> pclRenderWindow;
261  pclRenderWindow->SetSize(640, 480);
262  pclRenderWindow->AddRenderer(pclRenderer);
263  vtkNew<vtkRenderWindowInteractor> pclInteractor;
264  pclInteractor->SetRenderWindow(pclRenderWindow);
265 
266  vtkNew<vtkPolyDataMapper> mapper;
267  mapper->SetInputData(vtkSmartPointer<vtkPolyData>::New());
268  vtkNew<vtkActor> actor;
269  actor->SetMapper(mapper);
270  pclRenderer->SetBackground(0., 0., 0.);
271  pclRenderer->AddActor(actor);
272 
273  pclRenderWindow->Render();
274  pclInteractor->Initialize();
275 
276  vtkNew<vtkMyMeshViewerCallback> call2;
277  call2->m_Interactor = pclInteractor;
278  call2->m_Mapper = mapper;
279  call2->m_Channel = pclChannel;
280 
281  pclInteractor->AddObserver(vtkCommand::TimerEvent, call2);
282  pclInteractor->CreateRepeatingTimer(100);
283 
284  pclInteractor->Start();
285  pclInteractor->GetRenderWindow()->Finalize();
286  }
287  }
288  else
289  {
290  igtl::Sleep(2000);
291  }
292 
293  if (revopoint3DCameraDevice->StopRecording() != PLUS_SUCCESS)
294  {
295  LOG_INFO("Failed to stop recording");
296  exit(EXIT_FAILURE);
297  }
298 
299  if (revopoint3DCameraDevice->Disconnect() != PLUS_SUCCESS)
300  {
301  LOG_ERROR("Failed to disconnect");
302  exit(EXIT_FAILURE);
303  }
304 
305  LOG_INFO("Exit successfully");
306  exit(EXIT_SUCCESS);
307 }
308 
309 
310 // Callback function for error and warning redirects
311 void PrintLogsCallback(vtkObject* obj, unsigned long eid, void* clientdata, void* calldata)
312 {
313  if (eid == vtkCommand::GetEventIdFromString("WarningEvent"))
314  {
315  LOG_WARNING((const char*)calldata);
316  }
317  else if (eid == vtkCommand::GetEventIdFromString("ErrorEvent"))
318  {
319  LOG_ERROR((const char*)calldata);
320  }
321 }
int main(int argc, char **argv)
void PrintLogsCallback(vtkObject *obj, unsigned long eid, void *clientdata, void *calldata)
#define PLUS_SUCCESS
Definition: PlusCommon.h:44
int x
Definition: phidget22.h:4265
static vtkIGSIOLogger * Instance()
Contains an optional timestamped circular buffer containing the video images and a number of timestam...
Direction vectors of rods y
Definition: algo3.m:15