7 #include "PlusConfigure.h" 9 #include "igsioTrackedFrame.h" 10 #include "vtkAppendPolyData.h" 11 #include "vtkCubeSource.h" 12 #include "vtkImageData.h" 13 #include "vtkMatrix4x4.h" 14 #include "vtkPointData.h" 15 #include "vtkSTLWriter.h" 17 #include "vtkSmartPointer.h" 18 #include "vtkTimerLog.h" 19 #include "vtkIGSIOTrackedFrameList.h" 20 #include "vtkTransform.h" 21 #include "vtkTransformPolyDataFilter.h" 22 #include "vtkIGSIOTransformRepository.h" 24 #include "vtkXMLImageDataWriter.h" 25 #include "vtkXMLUtilities.h" 26 #include "vtksys/CommandLineArguments.hxx" 31 #include "vtkImageActor.h" 33 #include "vtkRenderWindow.h" 34 #include "vtkRenderer.h" 35 #include "vtkRenderWindowInteractor.h" 36 #include "vtkPolyDataMapper.h" 37 #include "vtkProperty.h" 38 #include "vtkInteractorStyleImage.h" 41 void CreateSliceModels(vtkIGSIOTrackedFrameList* trackedFrameList, vtkIGSIOTransformRepository* transformRepository, igsioTransformName& imageToReferenceTransformName, vtkPolyData* outputPolyData)
44 vtkSmartPointer< vtkAppendPolyData > appender = vtkSmartPointer<vtkAppendPolyData>::New();
47 for (
unsigned int frameIndex = 0; frameIndex < trackedFrameList->GetNumberOfTrackedFrames(); ++ frameIndex)
49 igsioTrackedFrame* frame = trackedFrameList->GetTrackedFrame(frameIndex);
52 if (transformRepository->SetTransforms(*frame) !=
PLUS_SUCCESS)
54 LOG_ERROR(
"Failed to set repository transforms from tracked frame!");
58 vtkSmartPointer<vtkMatrix4x4> tUserDefinedMatrix = vtkSmartPointer<vtkMatrix4x4>::New();
59 if (transformRepository->GetTransform(imageToReferenceTransformName, tUserDefinedMatrix) !=
PLUS_SUCCESS)
61 std::string strTransformName;
62 imageToReferenceTransformName.GetTransformName(strTransformName);
63 LOG_ERROR(
"Failed to get transform from repository: " << strTransformName);
67 vtkSmartPointer< vtkTransform> tUserDefinedTransform = vtkSmartPointer< vtkTransform >::New();
68 tUserDefinedTransform->SetMatrix(tUserDefinedMatrix);
70 FrameSizeType frameSize = frame->GetFrameSize();
72 vtkSmartPointer<vtkTransform> tCubeToImage = vtkSmartPointer<vtkTransform>::New();
73 tCubeToImage->Scale(frameSize[ 0 ], frameSize[ 1 ], 1);
74 tCubeToImage->Translate(0.5, 0.5, 0.5);
76 vtkSmartPointer<vtkTransform> tCubeToTracker = vtkSmartPointer< vtkTransform >::New();
77 tCubeToTracker->Identity();
78 tCubeToTracker->Concatenate(tUserDefinedTransform);
79 tCubeToTracker->Concatenate(tCubeToImage);
81 vtkSmartPointer<vtkTransformPolyDataFilter > cubeToTracker = vtkSmartPointer<vtkTransformPolyDataFilter>::New();
82 cubeToTracker->SetTransform(tCubeToTracker);
83 vtkSmartPointer<vtkCubeSource>
source = vtkSmartPointer<vtkCubeSource>::New();
84 cubeToTracker->SetInputConnection(
source->GetOutputPort());
85 cubeToTracker->Update();
87 appender->AddInputConnection(cubeToTracker->GetOutputPort());
91 outputPolyData->DeepCopy(appender->GetOutput());
95 void ShowResults(vtkIGSIOTrackedFrameList* trackedFrameList, vtkIGSIOTransformRepository* transformRepository, igsioTransformName imageToReferenceTransformName, std::string intersectionFile)
98 vtkSmartPointer<vtkRenderer> rendererPoly = vtkSmartPointer<vtkRenderer>::New();
99 vtkSmartPointer<vtkRenderWindow> renderWindowPoly = vtkSmartPointer<vtkRenderWindow>::New();
100 renderWindowPoly->AddRenderer(rendererPoly);
101 vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractorPoly = vtkSmartPointer<vtkRenderWindowInteractor>::New();
102 renderWindowInteractorPoly->SetRenderWindow(renderWindowPoly);
103 vtkSmartPointer<vtkInteractorStyleTrackballCamera> style = vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();
104 renderWindowInteractorPoly->SetInteractorStyle(style);
118 vtkSmartPointer< vtkPolyData > slicesPolyData = vtkSmartPointer< vtkPolyData >::New();
119 CreateSliceModels(trackedFrameList, transformRepository, imageToReferenceTransformName, slicesPolyData);
121 if (!intersectionFile.empty())
123 vtkSmartPointer<vtkSTLWriter> surfaceModelWriter = vtkSmartPointer<vtkSTLWriter>::New();
124 surfaceModelWriter->SetFileName(intersectionFile.c_str());
125 surfaceModelWriter->SetInputData(slicesPolyData);
126 surfaceModelWriter->Write();
129 vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
130 mapper->SetInputData(slicesPolyData);
131 vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
132 actor->SetMapper(mapper);
133 rendererPoly->AddActor(actor);
135 renderWindowPoly->Render();
136 renderWindowInteractorPoly->Start();
142 vtkSmartPointer<vtkImageData> usImage = vtkSmartPointer<vtkImageData>::New();
143 usImage->DeepCopy(simOutput);
146 vtkSmartPointer<vtkImageActor> redImageActor = vtkSmartPointer<vtkImageActor>::New();
147 redImageActor->SetInputData(simOutput);
150 vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
153 renderer->AddActor(redImageActor);
154 renderer->ResetCamera();
156 vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
157 renderWindow->AddRenderer(renderer);
158 renderer->SetBackground(0, 72, 0);
160 vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
161 vtkSmartPointer<vtkInteractorStyleImage> style = vtkSmartPointer<vtkInteractorStyleImage>::New();
163 renderWindowInteractor->SetInteractorStyle(style);
164 renderWindowInteractor->SetRenderWindow(renderWindow);
168 int main(
int argc,
char** argv)
170 bool printHelp =
false;
171 std::string inputTransformsFile;
172 std::string inputConfigFileName;
173 std::string outputUsImageFile;
174 std::string intersectionFile;
175 bool showResults =
false;
176 bool useCompression(
true);
178 int verboseLevel = vtkPlusLogger::LOG_LEVEL_UNDEFINED;
180 vtksys::CommandLineArguments args;
181 args.Initialize(argc, argv);
183 args.AddArgument(
"--help", vtksys::CommandLineArguments::NO_ARGUMENT, &printHelp,
"Print this help.");
184 args.AddArgument(
"--verbose", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &verboseLevel,
"Verbose level (1=error only, 2=warning, 3=info, 4=debug, 5=trace)");
185 args.AddArgument(
"--config-file", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &inputConfigFileName,
"Config file containing the image to probe and phantom to reference transformations");
186 args.AddArgument(
"--transforms-seq-file", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &inputTransformsFile,
"Input file containing coordinate frames and the associated model to image transformations");
187 args.AddArgument(
"--use-compression", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &useCompression,
"Use compression when outputting data");
188 args.AddArgument(
"--output-us-img-file", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &outputUsImageFile,
"File name of the generated output ultrasound image");
189 args.AddArgument(
"--output-slice-model-file", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &intersectionFile,
"Name of STL output file containing the model of all the frames (optional)");
190 args.AddArgument(
"--show-results", vtksys::CommandLineArguments::NO_ARGUMENT, &showResults,
"Show the simulated image on the screen");
195 std::cerr <<
"Problem parsing arguments" << std::endl;
196 std::cout <<
"Help: " << args.GetHelp() << std::endl;
202 std::cout << args.GetHelp() << std::endl;
208 if (inputConfigFileName.empty())
210 std::cerr <<
"--config-file required " << std::endl;
213 if (inputTransformsFile.empty())
215 std::cerr <<
"--transforms-seq-file required" << std::endl;
218 if (outputUsImageFile.empty())
220 std::cerr <<
"--output-us-img-file required" << std::endl;
225 LOG_DEBUG(
"Reading input meta file...");
226 vtkSmartPointer< vtkIGSIOTrackedFrameList > trackedFrameList = vtkSmartPointer< vtkIGSIOTrackedFrameList >::New();
229 LOG_ERROR(
"Unable to load input sequences file.");
232 LOG_DEBUG(
"Reading input meta file completed");
235 vtkSmartPointer<vtkIGSIOTrackedFrameList> simulatedUltrasoundFrameList = vtkSmartPointer<vtkIGSIOTrackedFrameList>::New();
238 LOG_DEBUG(
"Reading config file...")
239 vtkSmartPointer<vtkXMLDataElement> configRootElement = vtkSmartPointer<vtkXMLDataElement>::New();
242 LOG_ERROR(
"Unable to read configuration from file " << inputConfigFileName.c_str());
245 LOG_DEBUG(
"Reading config file finished.");
248 vtkSmartPointer<vtkIGSIOTransformRepository> transformRepository = vtkSmartPointer<vtkIGSIOTransformRepository>::New();
249 if (transformRepository->ReadConfiguration(configRootElement) !=
PLUS_SUCCESS)
251 LOG_ERROR(
"Failed to read transforms for transform repository!");
256 vtkSmartPointer<vtkPlusUsSimulatorAlgo> usSimulator = vtkSmartPointer<vtkPlusUsSimulatorAlgo>::New();
257 if (usSimulator->ReadConfiguration(configRootElement) !=
PLUS_SUCCESS)
259 LOG_ERROR(
"Failed to read US simulator configuration!");
262 usSimulator->SetTransformRepository(transformRepository);
263 igsioTransformName imageToReferenceTransformName(usSimulator->GetImageCoordinateFrame(), usSimulator->GetReferenceCoordinateFrame());
266 if (!intersectionFile.empty())
268 vtkSmartPointer< vtkPolyData > slicesPolyData = vtkSmartPointer< vtkPolyData >::New();
269 CreateSliceModels(trackedFrameList, transformRepository, imageToReferenceTransformName, slicesPolyData);
270 vtkSmartPointer<vtkSTLWriter> surfaceModelWriter = vtkSmartPointer<vtkSTLWriter>::New();
271 surfaceModelWriter->SetFileName(intersectionFile.c_str());
272 surfaceModelWriter->SetInputData(slicesPolyData);
273 surfaceModelWriter->Write();
278 ShowResults(trackedFrameList, transformRepository, imageToReferenceTransformName, intersectionFile);
281 std::vector<double> timeElapsedPerFrameSec;
282 double startTimeSec = 0;
283 double endTimeSec = 0;
286 trackedFrameList->RemoveTrackedFrameRange(15, trackedFrameList->GetNumberOfTrackedFrames() - 1);
288 for (
unsigned int i = 0;
i < trackedFrameList->GetNumberOfTrackedFrames();
i++)
290 startTimeSec = vtkTimerLog::GetUniversalTime();
292 LOG_DEBUG(
"Processing frame " <<
i);
293 igsioTrackedFrame* frame = trackedFrameList->GetTrackedFrame(
i);
296 if (transformRepository->SetTransforms(*frame) !=
PLUS_SUCCESS)
298 LOG_ERROR(
"Failed to set repository transforms from tracked frame!");
303 usSimulator->Modified();
304 usSimulator->Update();
305 vtkImageData* simOutput = usSimulator->GetOutput();
307 igsioVideoFrame* simulatorOutputigsioVideoFrame =
new igsioVideoFrame();
308 simulatorOutputigsioVideoFrame->DeepCopyFrom(simOutput);
310 frame->SetImageData(*simulatorOutputigsioVideoFrame);
339 endTimeSec = vtkTimerLog::GetUniversalTime();
340 timeElapsedPerFrameSec.push_back(endTimeSec - startTimeSec);
349 LOG_INFO(
"Computation time for the fits frame (not included in the statistics because of BSP Tree Building, in sec): " << timeElapsedPerFrameSec.at(0));
352 timeElapsedPerFrameSec.erase(timeElapsedPerFrameSec.begin());
354 double meanTimeElapsedPerFrameSec = 0;
355 double stdevTimeElapsedPerFrameSec = 0;
356 igsioMath::ComputeMeanAndStdev(timeElapsedPerFrameSec, meanTimeElapsedPerFrameSec, stdevTimeElapsedPerFrameSec);
357 LOG_INFO(
" Average computation time per frame (sec): " << meanTimeElapsedPerFrameSec) ;
358 LOG_INFO(
" Standard dev computation time per frame (sec): " << stdevTimeElapsedPerFrameSec) ;
359 LOG_INFO(
" Average fps: " << 1 / meanTimeElapsedPerFrameSec) ;
void ShowImage(vtkImageData *simOutput)
void CreateSliceModels(vtkIGSIOTrackedFrameList *trackedFrameList, vtkIGSIOTransformRepository *transformRepository, igsioTransformName &imageToReferenceTransformName, vtkPolyData *outputPolyData)
static igsioStatus Write(const std::string &filename, igsioTrackedFrame *frame, US_IMAGE_ORIENTATION orientationInFile=US_IMG_ORIENT_MF, bool useCompression=true, bool EnableImageDataWrite=true)
static igsioStatus Read(const std::string &filename, vtkIGSIOTrackedFrameList *frameList)
int main(int argc, char **argv)
void ShowResults(vtkIGSIOTrackedFrameList *trackedFrameList, vtkIGSIOTransformRepository *transformRepository, igsioTransformName imageToReferenceTransformName, std::string intersectionFile)
static vtkIGSIOLogger * Instance()
static PlusStatus ReadDeviceSetConfigurationFromFile(vtkXMLDataElement *config, const char *filename)