From 186750b2903bf4caafa104e7fe61ffa6f5c94198 Mon Sep 17 00:00:00 2001 From: Ina Vernikouskaya Date: Tue, 8 Sep 2020 12:10:18 +0200 Subject: [PATCH] (1) fix relative path problem for MR_Volume during scene loading (2) fix update of slice_spacing problem for loading MR volume from folder (3) read image size from dicom header instead of using fixed 512x512 matrix size --- src/geometry/SystemGeometryDefinitions.cxx | 8 --- src/geometry/SystemGeometryDefinitions.h | 4 -- src/gui/MainWindow.cpp | 11 +++- src/pipeline/DICOMVisualizer.cxx | 12 +++- src/pipeline/OverlayScene.cxx | 37 ++++++----- src/pipeline/OverlayScene.h | 8 +-- src/pipeline/XRAYReader.cxx | 74 ++++++++++++++++++++++ src/pipeline/XRAYReader.h | 2 + 8 files changed, 119 insertions(+), 37 deletions(-) diff --git a/src/geometry/SystemGeometryDefinitions.cxx b/src/geometry/SystemGeometryDefinitions.cxx index 398785f..04e6268 100644 --- a/src/geometry/SystemGeometryDefinitions.cxx +++ b/src/geometry/SystemGeometryDefinitions.cxx @@ -38,14 +38,6 @@ int SystemGeometryDefinitions::TABLE_POSITION_X = 0; // lat. int SystemGeometryDefinitions::TABLE_POSITION_Y = 0; // long. int SystemGeometryDefinitions::TABLE_POSITION_Z = 0; //vert. = höhe -// target size is set to keep the original ratio -int SystemGeometryDefinitions::TARGET_SIZE_X = 512; -int SystemGeometryDefinitions::TARGET_SIZE_Y = 512; - -// X-ray image size on the image plane (this is needed for positioning the X-ray plane) -int SystemGeometryDefinitions::IMAGE_SIZE_X = 512; -int SystemGeometryDefinitions::IMAGE_SIZE_Y = 512; - int SystemGeometryDefinitions::FIELD_DISTANCE = 25; double SystemGeometryDefinitions::DETECTOR_SIZE = 174.98; //174.98 mm - Detector size at FD = 25 cm; //double SystemGeometryDefinitions::DETECTOR_SIZE = 132.902; //132.902 mm - Detector size at FD = 19 cm; diff --git a/src/geometry/SystemGeometryDefinitions.h b/src/geometry/SystemGeometryDefinitions.h index d3f9309..7b83032 100644 --- a/src/geometry/SystemGeometryDefinitions.h +++ b/src/geometry/SystemGeometryDefinitions.h @@ -5,10 +5,6 @@ struct SystemGeometryDefinitions { static int CAMERA_SIZE_X; /// original width of the xray image (Live Signal format = monitor format) static int CAMERA_SIZE_Y; /// original height of the xray image - static int TARGET_SIZE_X; /// width of the xray image (it will be scaled if necessary) - static int TARGET_SIZE_Y; /// height of the xray image (it will be scaled if necessary) - static int IMAGE_SIZE_X; /// displayed width of the xray image (used to position the image plane) - static int IMAGE_SIZE_Y; /// displayed height of the xray image (used to position the image plane) static int LAPTOP_SIZE_X; static int LAPTOP_SIZE_Y; diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index 1760758..8e35e1f 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -543,7 +543,7 @@ void MainWindow::saveScene(const char* file) /*settings.setValue("MR_INPUT_YES", theOverlayScene->getMRInputFileForMesh());*/ settings.setValue("MESH_ORIENTATION", MeshOrientation); settings.setValue("MR_VOLUME", theOverlayScene->GetMRVisualizer()->getInputFile()); - + OverlayScene::MR_ITK; QString save = file; @@ -739,14 +739,16 @@ void MainWindow::loadScene(const char* file) QString MRVolumeFile = settings.value("MR_VOLUME").toString(); string MRVolumeFileString = qPrintable(MRVolumeFile); + QDir d = QFileInfo(MRVolumeFile).absoluteDir(); QString absoluteDir = d.absolutePath(); - string MRVolumeDirString = qPrintable(absoluteDir); - + string MRVolumeDirString = qPrintable(absoluteDir); if (MRVolumeFile.startsWith(".")) { MRVolumeFileString = qPrintable(dir.absoluteFilePath(MRVolumeFile)); + MRVolumeDirString = qPrintable(dir.absoluteFilePath(MRVolumeFile).section("/", 0, -2)); + } if (MRVolumeFile != QString("")) { @@ -756,6 +758,7 @@ void MainWindow::loadScene(const char* file) case 0: theOverlayScene->SetCTVisualizer(MRVolumeFileString, MRVolumeDirString, orientation); reloadFile = MRVolumeFileString; + reloadDir = MRVolumeDirString; MeshOrientation = 0; break; case 1: @@ -767,11 +770,13 @@ void MainWindow::loadScene(const char* file) case 2: theOverlayScene->SetCTVisualizer(MRVolumeFileString, MRVolumeDirString, orientation); reloadFile = MRVolumeFileString; + reloadDir = MRVolumeDirString; MeshOrientation = 2; break; case 3: theOverlayScene->SetCTVisualizer(MRVolumeFileString, MRVolumeDirString, orientation); reloadFile = MRVolumeFileString; + reloadDir = MRVolumeDirString; MeshOrientation = 3; break; default: diff --git a/src/pipeline/DICOMVisualizer.cxx b/src/pipeline/DICOMVisualizer.cxx index 388fbbb..7e765e6 100644 --- a/src/pipeline/DICOMVisualizer.cxx +++ b/src/pipeline/DICOMVisualizer.cxx @@ -96,7 +96,16 @@ DICOMVisualizer::~DICOMVisualizer() const char* DICOMVisualizer::getInputFile() const { - return theDICOMReader->GetFileName(); + const char* filename = theDICOMReader->GetFileName(); + + if (filename == NULL) + { + vtkStringArray *filenames = theDICOMReader->GetFileNames(); + filename = filenames->GetValue(0).c_str(); + + } + + return filename; } @@ -210,6 +219,7 @@ void DICOMVisualizer::setCTInputFile(string theFilename, string theFoldername, i s.SetComputeZSpacing(true); s.SetZSpacingTolerance(1e-3); + //std::cout << "z-spacing" << s.GetZSpacing() << std::endl; bool b = s.Sort(filenames); diff --git a/src/pipeline/OverlayScene.cxx b/src/pipeline/OverlayScene.cxx index eadad67..528e203 100644 --- a/src/pipeline/OverlayScene.cxx +++ b/src/pipeline/OverlayScene.cxx @@ -2278,7 +2278,7 @@ void OverlayScene::transformFromWorldToImageCoordinates(unsigned int streamNumbe } void OverlayScene::setBiplaneGeometry(unsigned int streamNumber, int SID, int sourcePatDist, double primAngle, double secAngle, - int lateralPos, int longitudinalPos, int verticalPos, double mmPerPxl) + int lateralPos, int longitudinalPos, int verticalPos, double mmPerPxl, int imageSizeX, int imageSizeY) { //printf("setting geometry with first SID: %.0f and second SID: %.0f\n", SID[0], SID[1]); /* compute geometry */ @@ -2295,8 +2295,8 @@ void OverlayScene::setBiplaneGeometry(unsigned int streamNumber, int SID, int so } geometry->setImageDimension( - SystemGeometryDefinitions::IMAGE_SIZE_X, - SystemGeometryDefinitions::IMAGE_SIZE_Y + imageSizeX, + imageSizeY ); geometry->setIsFramegrabber(isFramegrabber); geometry->setTablePosition((double)lateralPos, (double)longitudinalPos, (double)verticalPos); @@ -2489,13 +2489,13 @@ void OverlayScene::setupGeometryFromFramegrabber(int index) } -void OverlayScene::setMainGeometryByDICOM(int SID, int sourcePatDist, double primAngle, double secAngle, int lateralPos, int longitudinalPos, int verticalPos, double mmPerPixel) +void OverlayScene::setMainGeometryByDICOM(int SID, int sourcePatDist, double primAngle, double secAngle, int lateralPos, int longitudinalPos, int verticalPos, double mmPerPixel, int imageSizeX, int imageSizeY) { theBiplaneGeometry.mainSystem.setIsFramegrabber(isFramegrabber); theBiplaneGeometry.mainSystem.setImageDimension( - SystemGeometryDefinitions::IMAGE_SIZE_X, - SystemGeometryDefinitions::IMAGE_SIZE_Y + imageSizeX, + imageSizeY ); double angles[2] = { primAngle, secAngle}; @@ -3104,10 +3104,10 @@ void OverlayScene::showFrame(int index, int frame) void OverlayScene::setMainXRAYInputToFile(const char* file) { - int SID, sourcePatDist; + int SID, sourcePatDist, imageSizeX, imageSizeY; double primAngle, secAngle, mmPerPixel; int lateralPos, longitudinalPos, verticalPos; - bool ok[8]; + bool ok[10]; readerMainXRAY = XRAYReader::New(); @@ -3121,8 +3121,8 @@ void OverlayScene::setMainXRAYInputToFile(const char* file) theMotionCorrections->SetInputConnection(resliceMainXRAY->GetOutputPort(0)); actorMainXRAY->GetMapper()->SetInputConnection(theMotionCorrections->GetOutputPort()); - this->getDicomGeometryValues(SID, sourcePatDist, primAngle, secAngle, lateralPos, longitudinalPos, verticalPos, mmPerPixel, ok); - setMainGeometryByDICOM(SID, sourcePatDist, primAngle, secAngle, lateralPos, longitudinalPos, verticalPos, mmPerPixel); + this->getDicomGeometryValues(SID, sourcePatDist, primAngle, secAngle, lateralPos, longitudinalPos, verticalPos, mmPerPixel, imageSizeX, imageSizeY, ok); + setMainGeometryByDICOM(SID, sourcePatDist, primAngle, secAngle, lateralPos, longitudinalPos, verticalPos, mmPerPixel, imageSizeX, imageSizeY); //rendererMainXRAY->ResetCamera(); //renWinMainXRAY->Render(); @@ -3379,10 +3379,10 @@ void OverlayScene::setInputToFile(const char* file, int streamNumber) theXRAYReaders[streamNumber]->Delete(); - int SID, sourcePatDist; + int SID, sourcePatDist, imageSizeX, imageSizeY; double primAngle, secAngle, mmPerPixel; int lateralPos, longitudinalPos, verticalPos; - bool ok[8]; + bool ok[10]; XRAYReader* readerXRAY = XRAYReader::New(); readerXRAY->setInputFile(file); @@ -3396,7 +3396,7 @@ void OverlayScene::setInputToFile(const char* file, int streamNumber) theXRAYActors3D[streamNumber]->GetMapper()->SetInputConnection(theXRAYReslicers[streamNumber]->GetOutputPort()); theXRAYReslicers[streamNumber]->SetResliceAxesOrigin(0.0, 0.0, 0.0); // to display the first frame, even if there is only one image in a stream - this->getDicomReferenceGeometryValues(streamNumber, SID, sourcePatDist, primAngle, secAngle, lateralPos, longitudinalPos, verticalPos, mmPerPixel, ok); + this->getDicomReferenceGeometryValues(streamNumber, SID, sourcePatDist, primAngle, secAngle, lateralPos, longitudinalPos, verticalPos, mmPerPixel, imageSizeX, imageSizeY, ok); // berechnung fehlt!!!!!!!!!!!!!!!!! if (!alreadyConstructedPipelineDICOM[streamNumber]) { @@ -3412,7 +3412,7 @@ void OverlayScene::setInputToFile(const char* file, int streamNumber) } } - setBiplaneGeometry(streamNumber, SID, sourcePatDist, primAngle, secAngle, lateralPos, longitudinalPos, verticalPos, mmPerPixel); + setBiplaneGeometry(streamNumber, SID, sourcePatDist, primAngle, secAngle, lateralPos, longitudinalPos, verticalPos, mmPerPixel, imageSizeX, imageSizeY); renderer3D->ResetCamera(); renWin3D->Render(); @@ -3420,7 +3420,7 @@ void OverlayScene::setInputToFile(const char* file, int streamNumber) } void OverlayScene::getDicomReferenceGeometryValues(int streamNumber, int& SID, int& sourcePatDist, double& primAngle, double& secAngle, - int& lateralPos, int& longitudinalPos, int& verticalPos, double& mmPerPixel, bool ok[8]) + int& lateralPos, int& longitudinalPos, int& verticalPos, double& mmPerPixel, int& imageSizeX, int& imageSizeY, bool ok[10]) { SID = theXRAYReaders[streamNumber]->GetSID(&ok[0]); sourcePatDist = theXRAYReaders[streamNumber]->GetSourcePatientDistance(&ok[1]); @@ -3430,11 +3430,13 @@ void OverlayScene::getDicomReferenceGeometryValues(int streamNumber, int& SID, i longitudinalPos = theXRAYReaders[streamNumber]->GetTableTopLongitudinalPosition(&ok[5]); verticalPos = theXRAYReaders[streamNumber]->GetTableTopVerticalPosition(&ok[6]); mmPerPixel = theXRAYReaders[streamNumber]->GetMillimeterPerPixelScaling(&ok[7]); + imageSizeX = theXRAYReaders[streamNumber]->GetImageSizeX(&ok[8]); + imageSizeY = theXRAYReaders[streamNumber]->GetImageSizeY(&ok[9]); } void OverlayScene::getDicomGeometryValues(int& SID, int& sourcePatDist, double& primAngle, double& secAngle, - int& lateralPos, int& longitudinalPos, int& verticalPos, double& mmPerPixel, bool ok[8]) + int& lateralPos, int& longitudinalPos, int& verticalPos, double& mmPerPixel, int& imageSizeX, int&imageSizeY, bool ok[10]) { SID = readerMainXRAY->GetSID(&ok[0]); sourcePatDist = readerMainXRAY->GetSourcePatientDistance(&ok[1]); @@ -3444,7 +3446,8 @@ void OverlayScene::getDicomGeometryValues(int& SID, int& sourcePatDist, double& longitudinalPos = readerMainXRAY->GetTableTopLongitudinalPosition(&ok[5]); verticalPos = readerMainXRAY->GetTableTopVerticalPosition(&ok[6]); mmPerPixel = readerMainXRAY->GetMillimeterPerPixelScaling(&ok[7]); - + imageSizeX = readerMainXRAY->GetImageSizeX(&ok[8]); + imageSizeY = readerMainXRAY->GetImageSizeY(&ok[9]); } diff --git a/src/pipeline/OverlayScene.h b/src/pipeline/OverlayScene.h index 82f29ba..0fd7a89 100644 --- a/src/pipeline/OverlayScene.h +++ b/src/pipeline/OverlayScene.h @@ -102,8 +102,8 @@ class OverlayScene { void reloadPipelineFramegrabber(); void setBiplaneGeometry(unsigned int streamNumber, int SID, int sourcePatDist, double primAngle, double secAngle, - int lateralPos, int longitudinalPos, int verticalPos, double mmPerPxl); - void setMainGeometryByDICOM(int SID, int sourcePatDist, double primAngle, double secAngle, int lateralPos, int longitudinalPos, int verticalPos, double mmPerPixel); + int lateralPos, int longitudinalPos, int verticalPos, double mmPerPxl, int imageSizeX, int imageSizeY); + void setMainGeometryByDICOM(int SID, int sourcePatDist, double primAngle, double secAngle, int lateralPos, int longitudinalPos, int verticalPos, double mmPerPixel, int imageSizeX, int imageSizeY); void setFramegrabberGeometry(int index, int SID, double primAngle, double secAngle, int lateralPos, int longitudinalPos, int verticalPos, double FDoderMMPerPxl, bool play); void setFramegrabberGeometryLive(int index); void setFramegrabberGeometryBiplaneLive(int index); @@ -207,9 +207,9 @@ class OverlayScene { void setDICOMAnglesToWindowRef(int index, double primAngle, double secAngle); void getDICOMAnglesToWindowRef(int index, double& primAngle, double& secAngle); void getDicomReferenceGeometryValues(int streamNumber, int& SID, int& sourcePatDist, double& primAngle, double& secAngle, - int& lateralPos, int& longitudinalPos, int& verticalPos, double& mmPerPixel, bool ok[8]); + int& lateralPos, int& longitudinalPos, int& verticalPos, double& mmPerPixel, int& imageSizeX, int& imageSizeY, bool ok[10]); void getDicomGeometryValues(int& SID, int& sourcePatDist, double& primAngle, double& secAngle, - int& lateralPos, int& longitudinalPos, int& verticalPos, double& mmPerPixel, bool ok[8]); + int& lateralPos, int& longitudinalPos, int& verticalPos, double& mmPerPixel, int& imageSizeX, int& imageSizeY, bool ok[10]); /// set/get input file (CT or MR) in order to calculate correct mesh position in OverlayScene->AddOverlayMesh(), because for CT file with wrong spacing the mesh position has to be recalculated void setMRInputFileForMesh(int meshOrientation); int getMRInputFileForMesh(); diff --git a/src/pipeline/XRAYReader.cxx b/src/pipeline/XRAYReader.cxx index b9f4bd4..4d4b010 100644 --- a/src/pipeline/XRAYReader.cxx +++ b/src/pipeline/XRAYReader.cxx @@ -798,3 +798,77 @@ double XRAYReader::GetTableTopLateralPosition(bool* valid) *valid = true; return lateralPos; } + + +int XRAYReader::GetImageSizeX(bool* valid) +{ + gdcm::Reader* dicomReader = new gdcm::Reader; + dicomReader->SetFileName(theFilename.c_str()); + + int imageSizeX = 0; + + if (!dicomReader->CanRead()) + { + std::cout << "DICOM header is not readable! " << + "Can not retrieve image size (columns) from file!" << std::endl; + *valid = false; return -1; + } + + bool success = dicomReader->Read(); + if (!success) + { + std::cerr << "cannot read DICOM!" << std::endl; + *valid = false; return -1; + } + + gdcm::File dicomFile = dicomReader->GetFile(); + gdcm::StringFilter* dicomStringFilter = new gdcm::StringFilter; + dicomStringFilter->SetFile(dicomFile); + + gdcm::Tag tag = gdcm::Tag(0x0028, 0x0011); + std::string strImageSizeX = dicomStringFilter->ToString(tag); + imageSizeX = atoi(strImageSizeX.c_str()); + + //delete(dicomStringFilter); //TODO + delete(dicomReader); + + *valid = true; + return imageSizeX; +} + + +int XRAYReader::GetImageSizeY(bool* valid) +{ + gdcm::Reader* dicomReader = new gdcm::Reader; + dicomReader->SetFileName(theFilename.c_str()); + + int imageSizeY = 0; + + if (!dicomReader->CanRead()) + { + std::cout << "DICOM header is not readable! " << + "Can not retrieve image size (rows) from file!" << std::endl; + *valid = false; return -1; + } + + bool success = dicomReader->Read(); + if (!success) + { + std::cerr << "cannot read DICOM!" << std::endl; + *valid = false; return -1; + } + + gdcm::File dicomFile = dicomReader->GetFile(); + gdcm::StringFilter* dicomStringFilter = new gdcm::StringFilter; + dicomStringFilter->SetFile(dicomFile); + + gdcm::Tag tag = gdcm::Tag(0x0028, 0x0010); + std::string strImageSizeY = dicomStringFilter->ToString(tag); + imageSizeY = atoi(strImageSizeY.c_str()); + + //delete(dicomStringFilter); //TODO + delete(dicomReader); + + *valid = true; + return imageSizeY; +} \ No newline at end of file diff --git a/src/pipeline/XRAYReader.h b/src/pipeline/XRAYReader.h index c23c13e..0a7db98 100644 --- a/src/pipeline/XRAYReader.h +++ b/src/pipeline/XRAYReader.h @@ -45,6 +45,8 @@ class XRAYReader : public vtkImageReader2 double GetTableTopVerticalPosition(bool* valid); double GetTableTopLongitudinalPosition(bool* valid); double GetTableTopLateralPosition(bool* valid); + int GetImageSizeX(bool* valid); + int GetImageSizeY(bool* valid); void ReadGeometryFramegrabber(double& primAngleRead, double& secAngleRead, int& longRead, int& latRead, int& HoeheRead, int& SIDRead, double& mmPerPxlRead, int& FDRead, int& SODRead); void ReadGeometryFramegrabberAngle(double& primAngleRead, double& secAngleRead);