7 #include "PlusConfigure.h" 8 #include "igsioTrackedFrame.h" 9 #include "vtkImageData.h" 10 #include "vtkMatrix4x4.h" 11 #include "vtkIGSIOSequenceIO.h" 12 #include "vtkIGSIOTrackedFrameList.h" 13 #include "vtkIGSIOTransformRepository.h" 15 #include "vtkXMLUtilities.h" 16 #include "vtksys/CommandLineArguments.hxx" 18 int main(
int argc,
char* argv[])
20 bool printHelp(
false);
23 std::string inputImgSeqFileName;
24 std::string inputConfigFileName;
25 std::string outputVolumeFileName;
26 std::string outputVolumeAlphaFileNameDeprecated;
27 std::string outputVolumeAccumulationFileName;
28 std::string outputFrameFileName;
29 std::string importanceMaskFileName;
30 std::string inputImageToReferenceTransformName;
33 std::string inputImageToReferenceTransformNameDeprecated;
34 std::string inputImgSeqFileNameDeprecated;
36 int verboseLevel = vtkPlusLogger::LOG_LEVEL_UNDEFINED;
38 bool disableCompression =
false;
40 std::vector<std::string> customHeaderFieldsToSave;
41 std::vector<std::string> customHeaderValuesToSave;
43 vtksys::CommandLineArguments cmdargs;
44 cmdargs.Initialize(argc, argv);
46 cmdargs.AddArgument(
"--image-to-reference-transform", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &inputImageToReferenceTransformName,
"Name of the transform to define the image slice pose relative to the reference coordinate system (e.g., ImageToReference). Note that this parameter is optional, if it is defined then it overrides the ImageCoordinateFrame and ReferenceCoordinateFrame attribute values in the configuration file.");
47 cmdargs.AddArgument(
"--source-seq-file", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &inputImgSeqFileName,
"Input sequence file filename (.mha/.nrrd)");
48 cmdargs.AddArgument(
"--config-file", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &inputConfigFileName,
"Input configuration file name (.xml)");
49 cmdargs.AddArgument(
"--output-volume-file", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &outputVolumeFileName,
"Output file name of the reconstructed volume (must have .mha, .mhd, .nrrd or .nhdr extension)");
50 cmdargs.AddArgument(
"--output-volume-accumulation-file", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &outputVolumeAccumulationFileName,
"Output file name of the accumulation of the reconstructed volume (.mha/.nrrd)");
51 cmdargs.AddArgument(
"--output-frame-file", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &outputFrameFileName,
"A filename that will be used for storing the tracked image frames. Each frame will be exported individually, with the proper position and orientation in the reference coordinate system");
52 cmdargs.AddArgument(
"--help", vtksys::CommandLineArguments::NO_ARGUMENT, &printHelp,
"Print this help.");
53 cmdargs.AddArgument(
"--disable-compression", vtksys::CommandLineArguments::NO_ARGUMENT, &disableCompression,
"Do not compress output image files.");
54 cmdargs.AddArgument(
"--save-custom-headers", vtksys::CommandLineArguments::MULTI_ARGUMENT, &customHeaderFieldsToSave,
"List of custom header fields to pass into the output file.");
55 cmdargs.AddArgument(
"--verbose", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &verboseLevel,
"Verbose level (1=error only, 2=warning, 3=info, 4=debug, 5=trace)");
56 cmdargs.AddArgument(
"--importance-mask-file", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &importanceMaskFileName,
"The file to use as the importance mask.");
59 cmdargs.AddArgument(
"--transform", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &inputImageToReferenceTransformNameDeprecated,
"Image to reference transform name used for the reconstruction. DEPRECATED, use --image-to-reference-transform argument instead");
60 cmdargs.AddArgument(
"--img-seq-file", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &inputImgSeqFileNameDeprecated,
"Input sequence file filename (.mha/.nrrd). DEPRECATED: use --source-seq-file argument instead");
62 cmdargs.AddArgument(
"--output-volume-alpha-file", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &outputVolumeAlphaFileNameDeprecated,
"Output file name of the alpha channel of the reconstructed volume (.mha/.nrrd). DEPRECATED: use --output-volume-accumulation-file argument instead");
66 std::cerr <<
"Problem parsing arguments" << std::endl;
67 std::cout <<
"Help: " << cmdargs.GetHelp() << std::endl;
73 std::cout << cmdargs.GetHelp() << std::endl;
81 if (!inputImageToReferenceTransformNameDeprecated.empty())
83 LOG_WARNING(
"The --transform argument is deprecated. Use --image-to-reference-transform instead.");
84 if (inputImageToReferenceTransformName.empty())
86 inputImageToReferenceTransformName = inputImageToReferenceTransformNameDeprecated;
89 if (!inputImgSeqFileNameDeprecated.empty())
91 LOG_WARNING(
"The --img-seq-file argument is deprecated. Use --source-seq-file instead.");
92 if (inputImgSeqFileName.empty())
94 inputImgSeqFileName = inputImgSeqFileNameDeprecated;
98 if (!outputVolumeAlphaFileNameDeprecated.empty())
100 LOG_WARNING(
"The --output-volume-alpha-file argument is deprecated. Use --output-volume-accumulation-file instead.");
101 if (outputVolumeAccumulationFileName.empty())
103 outputVolumeAccumulationFileName = outputVolumeAlphaFileNameDeprecated;
107 if (inputConfigFileName.empty())
109 std::cout <<
"ERROR: Input config file name is missing!" << std::endl;
110 std::cout <<
"Help: " << cmdargs.GetHelp() << std::endl;
114 vtkSmartPointer<vtkPlusVolumeReconstructor> reconstructor = vtkSmartPointer<vtkPlusVolumeReconstructor>::New();
116 LOG_INFO(
"Reading configuration file:" << inputConfigFileName);
117 vtkSmartPointer<vtkXMLDataElement> configRootElement = vtkSmartPointer<vtkXMLDataElement>::New();
120 LOG_ERROR(
"Unable to read configuration from file " << inputConfigFileName.c_str());
124 if (reconstructor->ReadConfiguration(configRootElement) !=
PLUS_SUCCESS)
126 LOG_ERROR(
"Failed to read configuration from " << inputConfigFileName.c_str());
130 if (!importanceMaskFileName.empty())
132 reconstructor->SetImportanceMaskFilename(importanceMaskFileName);
135 vtkSmartPointer<vtkIGSIOTransformRepository> transformRepository = vtkSmartPointer<vtkIGSIOTransformRepository>::New();
136 if (configRootElement->FindNestedElementWithName(
"CoordinateDefinitions") != NULL)
138 if (transformRepository->ReadConfiguration(configRootElement) !=
PLUS_SUCCESS)
140 LOG_ERROR(
"Failed to read transforms from CoordinateDefinitions");
146 LOG_DEBUG(
"No transforms were found in CoordinateDefinitions. Only the transforms defined in the input image will be available.");
150 std::ostringstream osTransformRepo;
151 transformRepository->Print(osTransformRepo);
152 LOG_DEBUG(
"Transform repository: \n" << osTransformRepo.str());
155 LOG_INFO(
"Reading image sequence " << inputImgSeqFileName);
156 vtkSmartPointer<vtkIGSIOTrackedFrameList> trackedFrameList = vtkSmartPointer<vtkIGSIOTrackedFrameList>::New();
157 if (vtkIGSIOSequenceIO::Read(inputImgSeqFileName, trackedFrameList) !=
PLUS_SUCCESS)
159 LOG_ERROR(
"Unable to load input sequences file.");
164 igsioTransformName imageToReferenceTransformName;
165 if (!inputImageToReferenceTransformName.empty())
168 if (imageToReferenceTransformName.SetTransformName(inputImageToReferenceTransformName.c_str()) !=
PLUS_SUCCESS)
170 LOG_ERROR(
"Invalid image to reference transform name: " << inputImageToReferenceTransformName);
173 reconstructor->SetImageCoordinateFrame(imageToReferenceTransformName.From());
174 reconstructor->SetReferenceCoordinateFrame(imageToReferenceTransformName.To());
177 LOG_INFO(
"Set volume output extent...");
179 if (reconstructor->SetOutputExtentFromFrameList(trackedFrameList, transformRepository,
errorDetail) !=
PLUS_SUCCESS)
181 LOG_ERROR(
"Failed to set output extent of volume!");
185 LOG_INFO(
"Reconstruct volume...");
186 const int numberOfFrames = trackedFrameList->GetNumberOfTrackedFrames();
187 int numberOfFramesAddedToVolume = 0;
189 for (
int frameIndex = 0; frameIndex < numberOfFrames; frameIndex += reconstructor->GetSkipInterval())
191 LOG_DEBUG(
"Frame: " << frameIndex);
192 vtkPlusLogger::PrintProgressbar((100.0 * frameIndex) / numberOfFrames);
194 igsioTrackedFrame* frame = trackedFrameList->GetTrackedFrame(frameIndex);
196 if (transformRepository->SetTransforms(*frame) !=
PLUS_SUCCESS)
198 LOG_ERROR(
"Failed to update transform repository with frame #" << frameIndex);
203 bool insertedIntoVolume =
false;
204 bool isFirst = frameIndex == 0;
205 bool isLast = frameIndex + reconstructor->GetSkipInterval() >= numberOfFrames;
206 if (reconstructor->AddTrackedFrame(frame, transformRepository, isFirst, isLast, &insertedIntoVolume) !=
PLUS_SUCCESS)
208 LOG_ERROR(
"Failed to add tracked frame to volume with frame #" << frameIndex);
212 if (insertedIntoVolume)
214 numberOfFramesAddedToVolume++;
218 if (!outputFrameFileName.empty())
220 vtkSmartPointer<vtkMatrix4x4> imageToReferenceTransformMatrix = vtkSmartPointer<vtkMatrix4x4>::New();
221 if (transformRepository->GetTransform(imageToReferenceTransformName, imageToReferenceTransformMatrix) !=
PLUS_SUCCESS)
223 std::string strImageToReferenceTransformName;
224 imageToReferenceTransformName.GetTransformName(strImageToReferenceTransformName);
225 LOG_ERROR(
"Failed to get transform '" << strImageToReferenceTransformName <<
"' from transform repository!");
230 std::ostringstream os;
231 imageToReferenceTransformMatrix->Print(os);
232 LOG_TRACE(
"Image to reference transform: \n" << os.str());
235 std::ostringstream ss;
237 found = outputFrameFileName.find_last_of(
".");
238 ss << outputFrameFileName.substr(0, found);
242 ss << outputFrameFileName.substr(found);
248 vtkPlusLogger::PrintProgressbar(100);
250 if (!customHeaderFieldsToSave.empty())
252 std::string fieldValue;
253 for (
unsigned int i = 0;
i < customHeaderFieldsToSave.size(); ++
i)
255 fieldValue = trackedFrameList->GetCustomString(customHeaderFieldsToSave[
i]);
256 customHeaderValuesToSave.push_back(fieldValue);
260 trackedFrameList->Clear();
262 LOG_INFO(
"Number of frames added to the volume: " << numberOfFramesAddedToVolume <<
" out of " << numberOfFrames);
264 LOG_INFO(
"Saving volume to file...");
265 if (!customHeaderValuesToSave.empty())
267 reconstructor->SaveReconstructedVolumeToFile(outputVolumeFileName,
false, !disableCompression, &customHeaderFieldsToSave, &customHeaderValuesToSave);
270 reconstructor->SaveReconstructedVolumeToFile(outputVolumeFileName,
false, !disableCompression,
nullptr,
nullptr);
273 if (!outputVolumeAccumulationFileName.empty())
275 reconstructor->SaveReconstructedVolumeToFile(outputVolumeAccumulationFileName,
true, !disableCompression, &customHeaderFieldsToSave, &customHeaderValuesToSave);
const char char * errorDetail
vtkPlusCommonExport PlusStatus WriteToFile(igsioTrackedFrame *frame, const std::string &filename, vtkMatrix4x4 *imageToTracker)
int main(int argc, char *argv[])
static vtkIGSIOLogger * Instance()
static PlusStatus ReadDeviceSetConfigurationFromFile(vtkXMLDataElement *config, const char *filename)