X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=tools%2FclitkTransformLandmarks.cxx;h=df5dbe8e390521e8705019f14dea0defd66db44c;hb=543b72e23ad001ac2a7743b9beacf48e2d0054ac;hp=fc92886a82f9b256d4140f5d789502a4546cb9af;hpb=aba2595cd9d47d81d74e873f758877c56e9a79b7;p=clitk.git diff --git a/tools/clitkTransformLandmarks.cxx b/tools/clitkTransformLandmarks.cxx index fc92886..df5dbe8 100644 --- a/tools/clitkTransformLandmarks.cxx +++ b/tools/clitkTransformLandmarks.cxx @@ -1,3 +1,20 @@ +/*========================================================================= + Program: vv http://www.creatis.insa-lyon.fr/rio/vv + + Authors belong to: + - University of LYON http://www.universite-lyon.fr/ + - Léon Bérard cancer center http://www.centreleonberard.fr + - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the copyright notices for more information. + + It is distributed under dual licence + + - BSD See included LICENSE.txt file + - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html +===========================================================================*/ #include "clitkTransformLandmarks_ggo.h" #include "clitkTransformUtilities.h" @@ -6,64 +23,201 @@ #include #include +#include +#include +#include +#include "vtkPolyDataReader.h" +#include "vtkPolyDataWriter.h" +#include +#include + typedef itk::Matrix MatrixType; typedef itk::Point PointType; typedef std::vector PointArrayType; +typedef itk::FixedArray TxtDataType; +typedef std::vector TxtDataArrayType; -void read_points(const std::string& fileName, PointArrayType& points); + +void read_points_txt(const std::string& fileName, PointArrayType& points, TxtDataArrayType& data); +void write_points_txt(const std::string& fileName, const PointArrayType& points, const TxtDataArrayType& data); + +void read_points_pts(const std::string& fileName, PointArrayType& points); +void write_points_pts(const std::string& fileName, const PointArrayType& points); + +void apply_spacing(const PointArrayType& input, const double* spacing, PointArrayType& output); void transform_points(const PointArrayType& input, const MatrixType& matrix, PointArrayType& output); -void write_points(const PointArrayType& points); + bool verbose = false; int main(int argc, char** argv) { GGO(clitkTransformLandmarks, args_info); + verbose = args_info.verbose_flag; + TxtDataArrayType data; PointArrayType inputPoints; - read_points(args_info.input_arg, inputPoints); - - MatrixType matrix = clitk::ReadMatrix3D(args_info.matrix_arg); + if (strcmp(args_info.type_arg, "txt") == 0) { + read_points_txt(args_info.input_arg, inputPoints, data); + } + else if (strcmp(args_info.type_arg, "vtk") == 0) { + vtkSmartPointer reader = vtkSmartPointer::New(); + reader->SetFileName(args_info.input_arg); + reader->Update(); + vtkSmartPointer writer = vtkSmartPointer::New(); + writer->SetFileName( args_info.output_arg ); + + if (args_info.matrix_given) { + vtkSmartPointer transformFilter = vtkSmartPointer::New(); + vtkSmartPointer transform = vtkSmartPointer::New(); + vtkMatrix4x4* matrix = clitk::ReadVTKMatrix3D(args_info.matrix_arg); + vtkSmartPointer matrixT = vtkSmartPointer::New(); + vtkMatrix4x4::Invert(matrix, matrixT); //not sure why, but this seems necessary for using the same .mat as when loading file with vv (probably due to the inversion trick performed in the vv reader...) + transform->SetMatrix(matrixT); + transformFilter->SetInputConnection(reader->GetOutputPort()); + transformFilter->SetTransform(transform); + writer->SetInputConnection(transformFilter->GetOutputPort()); + + } + else { //just write the output + writer->SetInputConnection( reader->GetOutputPort() ); + } + writer->Write(); + return 0; + } + else { + read_points_pts(args_info.input_arg, inputPoints); + } + PointArrayType outputPoints; - transform_points(inputPoints, matrix, outputPoints); + PointArrayType spacingPoints; + PointArrayType* workingInputPoints = &inputPoints; + PointArrayType* workingOutputPoints = &outputPoints; + if (args_info.spacing_given) { + if (verbose) std::cout << "Processing spacing..." << std::endl; + + apply_spacing(*workingInputPoints, args_info.spacing_arg, spacingPoints); + workingInputPoints = &spacingPoints; + workingOutputPoints = &spacingPoints; + } + + MatrixType matrix; + if (args_info.matrix_given) { + matrix = clitk::ReadMatrix3D(args_info.matrix_arg); + transform_points(*workingInputPoints, matrix, outputPoints); + workingOutputPoints = &outputPoints; + } + + if (strcmp(args_info.type_arg, "txt") == 0) { + write_points_txt(args_info.output_arg, *workingOutputPoints, data); + } + else { + write_points_pts(args_info.output_arg, *workingOutputPoints); + } - write_points(outputPoints); return 0; } -void read_points(const std::string& fileName, PointArrayType& points) +void read_points_txt(const std::string& fileName, PointArrayType& points, TxtDataArrayType& data) { std::ifstream landmarksFile(fileName.c_str()); if (landmarksFile.fail()) { - std::cout << "ERROR: could not open '" << fileName << "'" << std::endl; + std::cerr << "ERROR: could not open '" << fileName << "'" << std::endl; exit(-2); } std::string line; std::getline(landmarksFile, line); if (line.find("LANDMARKS") == std::string::npos) { - std::cout << "ERROR: invalid landmarks file '" << fileName << "'" << std::endl; + std::cerr << "ERROR: invalid landmarks file '" << fileName << "'" << std::endl; exit(-3); } - int id = 0; - PointType point; - point.Fill(1); + PointType p; + p.Fill(1); + + TxtDataType d; - std::istringstream linestr; while (!landmarksFile.eof()) { - std::getline(landmarksFile, line); - if (verbose) std::cout << "line " << line << std::endl; + // read id, x, y, z, d1, d2 + landmarksFile >> d[0] >> p[0] >> p[1] >> p[2] >> d[1];// >> d[2]; + if (landmarksFile.fail()) + break; - if (!line.empty()) { - linestr.str(line); - linestr >> id >> point[0] >> point[1] >> point[2]; - - if (verbose) std::cout << "point " << point << std::endl; - - points.push_back(point); + if (verbose){ + std::cout << "point " << p << std::endl; + std::cout << "data " << " " << d[0] << " " << d[1] << std::endl; } + + points.push_back(p); + data.push_back(d); + } +} + +void write_points_txt(const std::string& fileName, const PointArrayType& points, const TxtDataArrayType& data) +{ + std::ofstream landmarksFile(fileName.c_str()); + + landmarksFile << "LANDMARKS1" << std::endl; + for (size_t i = 0; i < points.size(); i++) + landmarksFile << data[i][0] << " " << points[i][0] << " " << points[i][1] << " " << points[i][2] << " " << data[i][1] << " " << std::endl; +} + +void read_points_pts(const std::string& fileName, PointArrayType& points) +{ + std::ifstream landmarksFile(fileName.c_str()); + if (landmarksFile.fail()) { + std::cerr << "ERROR: could not open '" << fileName << "'" << std::endl; + exit(-2); + } + + std::string line; + std::getline(landmarksFile, line); + if (line.find("#X") != 0) { + std::cerr << "ERROR: invalid landmarks file '" << fileName << "'" << std::endl; + exit(-3); + } + + PointType p; + p.Fill(1); + + while (!landmarksFile.eof()) { + // read id, x, y, z, d1, d2 + landmarksFile >> p[0] >> p[1] >> p[2]; + if (landmarksFile.fail()) + break; + + if (verbose){ + std::cout << "point " << p << std::endl; + } + + points.push_back(p); + } +} + +void write_points_pts(const std::string& fileName, const PointArrayType& points) +{ + std::ofstream landmarksFile(fileName.c_str()); + + landmarksFile << "#X\tY\tZ" << std::endl; + for (size_t i = 0; i < points.size(); i++) + landmarksFile << points[i][0] << "\t" << points[i][1] << "\t" << points[i][2] << "\t" << std::endl; +} + +void apply_spacing(const PointArrayType& input, const double* spacing, PointArrayType& output) +{ + PointType out; + out.Fill(1); + + for (size_t i = 0; i < input.size(); i++) { + out[0] = input[i][0] * spacing[0]; + out[1] = input[i][1] * spacing[1]; + out[2] = input[i][2] * spacing[2]; + if (verbose){ + std::cout << "output " << out << std::endl; + } + output.push_back(out); } } @@ -74,9 +228,3 @@ void transform_points(const PointArrayType& input, const MatrixType& matrix, Poi } } -void write_points(const PointArrayType& points) -{ - std::cout << "LANDMARKS1" << std::endl; - for (size_t i = 0; i < points.size(); i++) - std::cout << i << " " << points[i][0] << " " << points[i][1] << " " << points[i][2] << " " << "0" << " " << std::endl; -} \ No newline at end of file