From e932ae0c97b71040627a372ff4a07fabc068d9be Mon Sep 17 00:00:00 2001 From: viar Date: Tue, 19 Jul 2022 18:58:38 +0200 Subject: [PATCH 01/49] Closing issue #23. The crash is caused by calling render in when the ui handler receives a DRT. As to why this is happening a little more work is required. In general the pipeline needs improvement --- .../itkDTRrecon/itkImageProcessor.cpp | 211 ++++++++++-------- .../itkDTRrecon/itkImageProcessor.h | 1 + 2 files changed, 114 insertions(+), 98 deletions(-) diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp index 5fb3ad1..4247ab2 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp @@ -331,6 +331,11 @@ void itkImageProcessor::SetCustom_ProjectionCenterFixedAxes_IEC( void itkImageProcessor::SetCustom_2Dres(double nX1,double nY1,double nX2,double nY2) { + std::cout << "SetCustom_2Dres " + << nX1 << " " + << nY1 << " " + << nX2 << " " + << nY2 << std::endl; if(m_DRTGeometryMetaInfo == NULL) { // todo @@ -352,6 +357,12 @@ void itkImageProcessor::SetCustom_2Dres(double nX1,double nY1,double nX2,double void itkImageProcessor::SetCustom_2Dsize(int nX1, int nY1,int nX2,int nY2) { + std::cout << "SetCustom_2Dsize " + << nX1 << " " + << nY1 << " " + << nX2 << " " + << nY2 << std::endl; + if(m_DRTGeometryMetaInfo == NULL) { // todo } @@ -370,6 +381,10 @@ void itkImageProcessor::SetCustom_2Dsize(int nX1, int nY1,int nX2,int nY2) //TODO UPDATE TO FOLLOW } +void itkImageProcessor::SetCustom_UpdateMetaInfo(){ + this->UpdateProjectionGeometryMeta(); +} + int itkImageProcessor::load3DSerieFromFiles( std::vector v_fnames){ tPatOrientation m_PatOrientation @@ -460,7 +475,7 @@ int itkImageProcessor::load3DSerieFromFiles( std::vector v_fnames){ } catch (itk::ExceptionObject & ex) { - std::cout << ex << std::endl; +// std::cout << ex << std::endl; return EXIT_FAILURE; } @@ -668,22 +683,22 @@ int itkImageProcessor::fill3DVolumeMeta( m_DRTGeometryMetaInfo->GetSCD2Offset() ); - std::cout<< "///////////////// 3D VOLUME BEG ///////////////" <GetOriginLPS() <GetCOV() <GetImportOffset() <GetLPS2IECDirections() <GetSize() <GetSpacing() <GetOriginLPS() <GetCOV() <GetImportOffset() <GetLPS2IECDirections() <GetSize() <GetSpacing() <GetProjectionAngleLPS() <GetSCD() <GetProjectionAngleLPS() <GetSCD() <GetProjectionAngleLPS() <GetSCD() <GetProjectionAngleLPS() <GetSCD() <UpdateProjectionGeometryMeta(); @@ -860,7 +875,7 @@ int itkImageProcessor::load2D(const char * pcFName){ strcpy( sTmpString,gGetStringValueFromTag( gdcm::Tag(0x0008,0x0008), ds)); std::string sLocalizerString = "LOCALIZER"; if (std::string(sTmpString).find(sLocalizerString) != std::string::npos) { - std::cout << "Loading Localizer: "<GetOutput()->GetDirection(); - std::cout<<"LocalizerImagDirectionDCM " <Update(); - std::cout<< " ////////////// 2D Topo BEG " <GetOutput()->GetDirection()<GetOutput()->GetOrigin()<GetOutput()->GetSpacing()<GetOutput()->GetLargestPossibleRegion().GetSize()<GetOutput()->GetDirection()<GetOutput()->GetOrigin()<GetOutput()->GetSpacing()<GetOutput()->GetLargestPossibleRegion().GetSize()<SetCenter( m_DRTImage1MetaInfo->GetProjectionOriginLPSZero() ); - transform1->Print(std::cout); +// transform1->Print(std::cout); // 2D Image 1 interpolator1->SetProjectionAngle( @@ -1496,7 +1511,7 @@ void itkImageProcessor::InitializeProjector() filter1->ChangeOriginOn(); filter1->UpdateOutputInformation(); - std::cout<< "itkImageProcessor::InitializeProjector() " <GetOutput(); - std::cout<< "itkImageProcessor::InitializeProjector() END" <GetImportOffset() " - <GetImportOffset() <GetImportOffset() " +// <GetImportOffset() <UpdateProjectionGeometryMeta(); this->InitializeProjector(); @@ -1632,12 +1647,12 @@ void itkImageProcessor::UpdateProjectionGeometryMeta(){ m_DRTGeometryMetaInfo->GetProjectionCenter() ); - std::cout<< "///////////////// PGEOM META BEG ///////////////" <GetProjectionCenter() <GetProjectionCenter() <GetProjectionOriginLPS() ); - std::cout<<"Bounds1: " - <SetSizeWithBounds( vBounds.data(), @@ -1720,16 +1735,16 @@ void itkImageProcessor::UpdateProjectionGeometryMeta(){ Std_DRT2LPS) ); - std::cout<<"IsocenterOffsetLPS"<< IsocenterOffsetLPS <GetSize()"<< m_DRTImage1MetaInfo->GetSize() <GetSpacing()"<< m_DRTImage1MetaInfo->GetSpacing() <GetOrigin()"<< m_DRTImage1MetaInfo->GetOrigin() <GetCOV()"<< m_DRTImage1MetaInfo->GetCOV() <GetOriginLPS()"<< m_DRTImage1MetaInfo->GetOriginLPS() <GetProjectionAngleLPS()"<GetProjectionAngleLPS()<GetImageDirectionsLPS()"<< m_DRTImage1MetaInfo->GetImageDirectionsLPS() <GetSize()"<< m_DRTImage1MetaInfo->GetSize() <GetSpacing()"<< m_DRTImage1MetaInfo->GetSpacing() <GetOrigin()"<< m_DRTImage1MetaInfo->GetOrigin() <GetCOV()"<< m_DRTImage1MetaInfo->GetCOV() <GetOriginLPS()"<< m_DRTImage1MetaInfo->GetOriginLPS() <GetProjectionAngleLPS()"<GetProjectionAngleLPS()<GetImageDirectionsLPS()"<< m_DRTImage1MetaInfo->GetImageDirectionsLPS() <GetProjectionOriginLPS() ); - std::cout<<"Bounds2: " - <SetSizeWithBounds( vBounds.data(), @@ -1808,16 +1823,16 @@ void itkImageProcessor::UpdateProjectionGeometryMeta(){ Std_DRT2LPS) ); - std::cout<<"IsocenterOffsetLPS"<< IsocenterOffsetLPS <GetSize()"<< m_DRTImage2MetaInfo->GetSize() <GetSpacing()"<< m_DRTImage2MetaInfo->GetSpacing() <GetOrigin()"<< m_DRTImage2MetaInfo->GetOrigin() <GetCOV()"<< m_DRTImage2MetaInfo->GetCOV() <GetOriginLPS()"<< m_DRTImage2MetaInfo->GetOriginLPS() <GetProjectionAngleLPS()"<GetProjectionAngleLPS()<GetImageDirectionsLPS()"<< m_DRTImage2MetaInfo->GetImageDirectionsLPS() <GetSize()"<< m_DRTImage2MetaInfo->GetSize() <GetSpacing()"<< m_DRTImage2MetaInfo->GetSpacing() <GetOrigin()"<< m_DRTImage2MetaInfo->GetOrigin() <GetCOV()"<< m_DRTImage2MetaInfo->GetCOV() <GetOriginLPS()"<< m_DRTImage2MetaInfo->GetOriginLPS() <GetProjectionAngleLPS()"<GetProjectionAngleLPS()<GetImageDirectionsLPS()"<< m_DRTImage2MetaInfo->GetImageDirectionsLPS() <GetProjectionOriginLPS( // m_DRTGeometryMetaInfo->GetProjectionCenter()); - std::cout<<"pFakeIsoLPS: "<GetAngleZ() ); - std::cout<< "itkImageProcessor::GetProjectionImages" <SetCenter( m_DRTImage1MetaInfo->GetProjectionOriginLPSZero()); - std::cout<<"Angle1 "<GetProjectionAngleLPS() <GetProjectionOriginLPSZero() <GetProjectionOriginLPS()<GetProjectionAngleLPS() <GetProjectionOriginLPSZero() <GetProjectionOriginLPS()<GetProjectionAngleLPS() <GetProjectionOriginLPSZero() <GetProjectionOriginLPS()<GetProjectionAngleLPS() <GetProjectionOriginLPSZero() <GetProjectionOriginLPS()<Print(std::cout); @@ -1968,7 +1983,7 @@ void itkImageProcessor::GetProjectionImages(){ //m_CTMetaInfo->GetProjectionOriginLPS( // m_DRTGeometryMetaInfo->GetProjectionCenter()); - std::cout<<"pFakeIsoLPS: "<SetTransform(transform2); //finalTransform); interpolator2->Initialize(); - std::cout<<"pFakeIsoLPS: "<Update(); filter2->Update(); imageDRT1In = filter1->GetOutput(); imageDRT2In = filter2->GetOutput(); - std::cout<< "itkImageProcessor::GetProjectionImages END" <GetInverseTransform()->GetMatrix()<GetOutput()->GetBounds(); - std::cout<< "-------- Localizer 1 VTK --------" <Update(); } catch (itk::ExceptionObject & err) @@ -2493,7 +2508,7 @@ void itkImageProcessor::WriteProjectionImages() try { - std::cout << "Writing image 2" << std::endl; +// std::cout << "Writing image 2" << std::endl; writer2->Update(); } catch (itk::ExceptionObject & err) diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.h b/reg23Topograms/itkDTRrecon/itkImageProcessor.h index 2be4ca8..1086963 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.h +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.h @@ -109,6 +109,7 @@ public: void SetCustom_2Dsize(int,int,int,int); void SetCustom_ImportTransform(double, double, double, double, double, double); + void SetCustom_UpdateMetaInfo(); /** Set transform parameters for 3D Volume */ From a2bd350ea209672b80be1aee52a6011f2ec8c455 Mon Sep 17 00:00:00 2001 From: viar Date: Thu, 21 Jul 2022 18:15:46 +0200 Subject: [PATCH 02/49] Issue #27 - Started working on implementation of the Registration Supervisor. It works as it is supposed to. Could be improved visualisation when using TranslationWidget --- .../itkDTRrecon/itkImageProcessor.cpp | 25 +++++++++++++++++++ .../itkDTRrecon/itkImageProcessor.h | 5 +++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp index 4247ab2..a9de5de 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp @@ -2548,8 +2548,33 @@ void itkImageProcessor::SetInitialRotations(double dX, double dY, double dZ) m_TransformMetaInfo->SetRotations(Rotations); + } +double* itkImageProcessor::GetTransformParameters(){ + + + ImageType3D::PointType Translations; + ImageType3D::PointType Rotations; + + Translations = m_TransformMetaInfo->GetTranslations(); + Rotations = m_TransformMetaInfo->GetRotations(); + + dTransfParam[0] = Translations[0]; + dTransfParam[1] = Translations[1]; + dTransfParam[2] = Translations[2]; + + dTransfParam[3] = Rotations[0]; + dTransfParam[4] = Rotations[1]; + dTransfParam[5] = Rotations[2]; + + return dTransfParam; +} + + + + + } // end namespace itk diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.h b/reg23Topograms/itkDTRrecon/itkImageProcessor.h index 1086963..079e33a 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.h +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.h @@ -116,6 +116,8 @@ public: void SetInitialTranslations(double, double, double); void SetInitialRotations(double, double, double); + /** Get transform parameters for 3D Volume */ + double* GetTransformParameters(); /** Initialize projection geometry */ void InitializeProjector(); @@ -306,7 +308,8 @@ private: * m_Projection1VTKTransform, * m_Projection2VTKTransform; - + /*Transformation Parameters */ + double dTransfParam[6]; /** * Many meta containers From b88eb17d40340d808ecc05661729c98ec3ccd88e Mon Sep 17 00:00:00 2001 From: viar Date: Thu, 28 Jul 2022 09:21:01 +0200 Subject: [PATCH 03/49] Clean-up of Visualisation Handler --- reg23Topograms/itkDTRrecon/itkImageProcessor.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp index a9de5de..ac9d8d4 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp @@ -1604,8 +1604,8 @@ void itkImageProcessor::loadRTPlanInfo( ) ); -// std::cout<< "m_CTMetaInfo->GetImportOffset() " -// <GetImportOffset() <GetImportOffset() " + <GetImportOffset() <UpdateProjectionGeometryMeta(); this->InitializeProjector(); From 70a063c636271689558abecfefb77a3a23bfe9a4 Mon Sep 17 00:00:00 2001 From: Fattori Giovanni Date: Mon, 22 Aug 2022 17:02:27 +0200 Subject: [PATCH 04/49] DICOM write Example write for REG and DRR --- reg23Topograms/itkDTRrecon/itkImageProcessor.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp index a9de5de..f4873ee 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp @@ -554,7 +554,7 @@ int itkImageProcessor::load3DSerieFromFolder(const char * pcDirName) imageSeriesReader3D->SetImageIO(dicomIO); imageSeriesReader3D->SetFileNames(fileNames); - imageSeriesReader3D->SetNumberOfWorkUnits(8); + imageSeriesReader3D->SetNumberOfWorkUnits(12); imageSeriesReader3D->ForceOrthogonalDirectionOff(); // properly read CTs with gantry tilt imageSeriesReader3D->Update(); @@ -1462,7 +1462,7 @@ void itkImageProcessor::InitializeProjector() image3DIn); resampleFilter1->SetDefaultPixelValue(0); - resampleFilter1->SetNumberOfWorkUnits(8); + resampleFilter1->SetNumberOfWorkUnits(12); // The parameters of interpolator1, such as ProjectionAngle and FocalPointToIsocenterDistance // have been set before registration. Here we only need to replace the initial @@ -1481,7 +1481,7 @@ void itkImageProcessor::InitializeProjector() resampleFilter2->SetInput( image3DIn); resampleFilter2->SetDefaultPixelValue(0); - resampleFilter2->SetNumberOfWorkUnits(8); + resampleFilter2->SetNumberOfWorkUnits(12); // The parameters of interpolator2, such as ProjectionAngle and FocalPointToIsocenterDistance From 101ae5ff00905b60ff77280240c2fa21d1b00671 Mon Sep 17 00:00:00 2001 From: viar Date: Fri, 9 Sep 2022 15:51:01 +0200 Subject: [PATCH 05/49] Completed writing of Dicom File for Spatial Registration --- reg23Topograms/itkDTRrecon/itkImageProcessor.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp index 9619ce0..90f2cef 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp @@ -2553,7 +2553,6 @@ void itkImageProcessor::SetInitialRotations(double dX, double dY, double dZ) double* itkImageProcessor::GetTransformParameters(){ - ImageType3D::PointType Translations; ImageType3D::PointType Rotations; From 9fc929083843384c94f1faa5d376082e31de5177 Mon Sep 17 00:00:00 2001 From: viar Date: Mon, 12 Sep 2022 17:50:58 +0200 Subject: [PATCH 06/49] Completed writing of DRRs. Only final checks yet to be done --- reg23Topograms/itkDTRrecon/itkImageProcessor.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp index 90f2cef..39c1673 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp @@ -2571,9 +2571,5 @@ double* itkImageProcessor::GetTransformParameters(){ } - - - - } // end namespace itk From edf28c6a57bae44b9f61a9ac2cd078c609a5a44f Mon Sep 17 00:00:00 2001 From: viar Date: Tue, 13 Sep 2022 17:04:13 +0200 Subject: [PATCH 07/49] Fixed crashed when unloading Scout and fixed unloading of RTPlan --- .../itkDTRrecon/DRTMetaInformation.cpp | 144 +++++++++--------- .../itkDTRrecon/itkImageProcessor.cpp | 71 ++++----- 2 files changed, 106 insertions(+), 109 deletions(-) diff --git a/reg23Topograms/itkDTRrecon/DRTMetaInformation.cpp b/reg23Topograms/itkDTRrecon/DRTMetaInformation.cpp index 8368cc7..d1943e4 100644 --- a/reg23Topograms/itkDTRrecon/DRTMetaInformation.cpp +++ b/reg23Topograms/itkDTRrecon/DRTMetaInformation.cpp @@ -36,7 +36,7 @@ void TopogramImageMetaInformation ::PrintSelf(std::ostream& os, itk::Indent indent) const { - Superclass::PrintSelf(os, indent); + Superclass::PrintSelf(os, indent); } @@ -53,21 +53,21 @@ SetPatientOrientation(tPatOrientation m_orient) this->m_PatientOrientation = m_orient; for(int iIdx = 0 ; iIdx < 3; iIdx++){ - for(int jIdx = 0 ; jIdx < 3; jIdx++){ + for(int jIdx = 0 ; jIdx < 3; jIdx++){ - switch (this->m_PatientOrientation) { - case tPatOrientation::HFS: - m_LPS2IECDirections.GetVnlMatrix()[iIdx][jIdx] = HFS2IEC[jIdx+iIdx*3]; - break; - case tPatOrientation ::FFS: - m_LPS2IECDirections.GetVnlMatrix()[iIdx][jIdx] = FFS2IEC[jIdx+iIdx*3]; - break; - default: - m_LPS2IECDirections.SetIdentity(); - break; - } + switch (this->m_PatientOrientation) { + case tPatOrientation::HFS: + m_LPS2IECDirections.GetVnlMatrix()[iIdx][jIdx] = HFS2IEC[jIdx+iIdx*3]; + break; + case tPatOrientation ::FFS: + m_LPS2IECDirections.GetVnlMatrix()[iIdx][jIdx] = FFS2IEC[jIdx+iIdx*3]; + break; + default: + m_LPS2IECDirections.SetIdentity(); + break; } } + } } @@ -100,7 +100,7 @@ void DRTImageMetaInformation ::PrintSelf(std::ostream& os, itk::Indent indent) const { - Superclass::PrintSelf(os, indent); + Superclass::PrintSelf(os, indent); } @@ -182,24 +182,20 @@ void DRTImageMetaInformation::SetSizeWithBounds( dPixMaxOverlap =dNPixMin1; if(dPixMaxOverlap > dNPixMax1){ - dPixMaxOverlap = dNPixMax1; - } + dPixMaxOverlap = dNPixMax1; + } + if(floor(dPixMaxOverlap*2) > MaxSize[1]) { - m_Size[1] = MaxSize[1]; - } else { - m_Size[1] = floor(dPixMaxOverlap*2); - } + m_Size[1] = MaxSize[1]; + } else { + m_Size[1] = floor(dPixMaxOverlap*2); + } m_Size[2] = 1; m_Spacing = Spacing; - - - return; - - - + return; } @@ -263,9 +259,9 @@ CTVolumeImageMetaInformation::GetProjectionOriginLPS( PointType ProjectionCenter) { -// PointType Origin; -// Origin = this->m_OriginLPS; -// Origin = Origin - this->m_ImportOffset; + // PointType Origin; + // Origin = this->m_OriginLPS; + // Origin = Origin - this->m_ImportOffset; DirectionType IECtoLPS_Directions; IECtoLPS_Directions = this->m_LPS2IECDirections.GetTranspose(); @@ -279,8 +275,8 @@ CTVolumeImageMetaInformation::GetProjectionOriginLPS( * middle of the volume */ m_ProjectionOriginLPS[2] = this->GetCOV()[2] - this->m_ImportOffset[2]; - return - m_ProjectionOriginLPS; + return + m_ProjectionOriginLPS; } @@ -305,8 +301,8 @@ CTVolumeImageMetaInformation::GetProjectionOriginLPSZero( m_ProjectionOriginLPS[2] = this->GetCOV()[2] - this->m_ImportOffset[2]; - return - m_ProjectionOriginLPS - Origin; + return + m_ProjectionOriginLPS - Origin; } @@ -315,29 +311,29 @@ CTVolumeImageMetaInformation::CalculateRegions(PointType pProjectionOriginLPS) { /* calculate image size in 3D Space by finding the last voxel position */ - PointType Dest; - Dest[0]=(m_Size[0]-1) * m_Spacing [0]; - Dest[1]=(m_Size[1]-1) * m_Spacing [1]; - Dest[2]=(m_Size[2]-1) * m_Spacing [2]; + PointType Dest; + Dest[0]=(m_Size[0]-1) * m_Spacing [0]; + Dest[1]=(m_Size[1]-1) * m_Spacing [1]; + Dest[2]=(m_Size[2]-1) * m_Spacing [2]; - PointType LastVoxelPosition = - (m_ImageDirections * Dest); + PointType LastVoxelPosition = + (m_ImageDirections * Dest); - LastVoxelPosition [0] += m_OriginLPS[0]; - LastVoxelPosition [1] += m_OriginLPS[1]; - LastVoxelPosition [2] += m_OriginLPS[2]; + LastVoxelPosition [0] += m_OriginLPS[0]; + LastVoxelPosition [1] += m_OriginLPS[1]; + LastVoxelPosition [2] += m_OriginLPS[2]; - std::vector vBounds; - vBounds.clear(); - vBounds.push_back( pProjectionOriginLPS[0] - LastVoxelPosition [0] ); - vBounds.push_back( pProjectionOriginLPS[1] - LastVoxelPosition [1] ); - vBounds.push_back( pProjectionOriginLPS[2] - LastVoxelPosition [2] ); - vBounds.push_back( pProjectionOriginLPS[0] - m_OriginLPS [0] ); - vBounds.push_back( pProjectionOriginLPS[1] - m_OriginLPS [1] ); - vBounds.push_back( pProjectionOriginLPS[2] - m_OriginLPS [2] ); + std::vector vBounds; + vBounds.clear(); + vBounds.push_back( pProjectionOriginLPS[0] - LastVoxelPosition [0] ); + vBounds.push_back( pProjectionOriginLPS[1] - LastVoxelPosition [1] ); + vBounds.push_back( pProjectionOriginLPS[2] - LastVoxelPosition [2] ); + vBounds.push_back( pProjectionOriginLPS[0] - m_OriginLPS [0] ); + vBounds.push_back( pProjectionOriginLPS[1] - m_OriginLPS [1] ); + vBounds.push_back( pProjectionOriginLPS[2] - m_OriginLPS [2] ); - return - vBounds; + return + vBounds; } @@ -365,7 +361,7 @@ void CTVolumeImageMetaInformation ::PrintSelf(std::ostream& os, itk::Indent indent) const { - Superclass::PrintSelf(os, indent); + Superclass::PrintSelf(os, indent); } @@ -381,21 +377,21 @@ SetPatientOrientation(tPatOrientation m_orient) this->m_PatientOrientation = m_orient; for(int iIdx = 0 ; iIdx < 3; iIdx++){ - for(int jIdx = 0 ; jIdx < 3; jIdx++){ + for(int jIdx = 0 ; jIdx < 3; jIdx++){ - switch (this->m_PatientOrientation) { - case tPatOrientation::HFS: - m_LPS2IECDirections.GetVnlMatrix()[iIdx][jIdx] = HFS2IEC[jIdx+iIdx*3]; - break; - case tPatOrientation ::FFS: - m_LPS2IECDirections.GetVnlMatrix()[iIdx][jIdx] = FFS2IEC[jIdx+iIdx*3]; - break; - default: - m_LPS2IECDirections.SetIdentity(); - break; - } + switch (this->m_PatientOrientation) { + case tPatOrientation::HFS: + m_LPS2IECDirections.GetVnlMatrix()[iIdx][jIdx] = HFS2IEC[jIdx+iIdx*3]; + break; + case tPatOrientation ::FFS: + m_LPS2IECDirections.GetVnlMatrix()[iIdx][jIdx] = FFS2IEC[jIdx+iIdx*3]; + break; + default: + m_LPS2IECDirections.SetIdentity(); + break; } } + } } @@ -478,7 +474,7 @@ void DRTProjectionGeometryImageMetaInformation ::PrintSelf(std::ostream& os, itk::Indent indent) const { - Superclass::PrintSelf(os, indent); + Superclass::PrintSelf(os, indent); } @@ -505,7 +501,7 @@ void RTGeometryMetaInformation ::PrintSelf(std::ostream& os, itk::Indent indent) const { - Superclass::PrintSelf(os, indent); + Superclass::PrintSelf(os, indent); } @@ -521,17 +517,17 @@ RTGeometryMetaInformation TransformMetaInformation :: TransformMetaInformation (){ - m_Translations.Fill(0.); + m_Translations.Fill(0.); - m_Rotations.Fill(0.); + m_Rotations.Fill(0.); - m_UserRotations.Fill(0.); + m_UserRotations.Fill(0.); - m_UserTranslations.Fill(0.); + m_UserTranslations.Fill(0.); - m_ReferenceTransform.Fill(0.); + m_ReferenceTransform.Fill(0.); - m_CurrentTransform.Fill(0.); + m_CurrentTransform.Fill(0.); } @@ -539,7 +535,7 @@ void TransformMetaInformation ::PrintSelf(std::ostream& os, itk::Indent indent) const { - Superclass::PrintSelf(os, indent); + Superclass::PrintSelf(os, indent); } diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp index 39c1673..19af153 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp @@ -1692,16 +1692,17 @@ void itkImageProcessor::UpdateProjectionGeometryMeta(){ // This is based on the calibrated iso to be sure... std::vector vBounds = m_CTMetaInfo->CalculateRegions( - NominalIsocenter_wZcorrectionLPS//m_DRTImage1MetaInfo->GetProjectionOriginLPS() + NominalIsocenter_wZcorrectionLPS +// m_DRTImage1MetaInfo->GetProjectionOriginLPS() ); -// std::cout<<"Bounds1: " -// <SetSizeWithBounds( vBounds.data(), @@ -1735,16 +1736,16 @@ void itkImageProcessor::UpdateProjectionGeometryMeta(){ Std_DRT2LPS) ); -// std::cout<<"IsocenterOffsetLPS"<< IsocenterOffsetLPS <GetSize()"<< m_DRTImage1MetaInfo->GetSize() <GetSpacing()"<< m_DRTImage1MetaInfo->GetSpacing() <GetOrigin()"<< m_DRTImage1MetaInfo->GetOrigin() <GetCOV()"<< m_DRTImage1MetaInfo->GetCOV() <GetOriginLPS()"<< m_DRTImage1MetaInfo->GetOriginLPS() <GetProjectionAngleLPS()"<GetProjectionAngleLPS()<GetImageDirectionsLPS()"<< m_DRTImage1MetaInfo->GetImageDirectionsLPS() <GetSize()"<< m_DRTImage1MetaInfo->GetSize() <GetSpacing()"<< m_DRTImage1MetaInfo->GetSpacing() <GetOrigin()"<< m_DRTImage1MetaInfo->GetOrigin() <GetCOV()"<< m_DRTImage1MetaInfo->GetCOV() <GetOriginLPS()"<< m_DRTImage1MetaInfo->GetOriginLPS() <GetProjectionAngleLPS()"<GetProjectionAngleLPS()<GetImageDirectionsLPS()"<< m_DRTImage1MetaInfo->GetImageDirectionsLPS() <GetProjectionOriginLPS() ); -// std::cout<<"Bounds2: " -// <SetSizeWithBounds( vBounds.data(), @@ -1823,16 +1824,16 @@ void itkImageProcessor::UpdateProjectionGeometryMeta(){ Std_DRT2LPS) ); -// std::cout<<"IsocenterOffsetLPS"<< IsocenterOffsetLPS <GetSize()"<< m_DRTImage2MetaInfo->GetSize() <GetSpacing()"<< m_DRTImage2MetaInfo->GetSpacing() <GetOrigin()"<< m_DRTImage2MetaInfo->GetOrigin() <GetCOV()"<< m_DRTImage2MetaInfo->GetCOV() <GetOriginLPS()"<< m_DRTImage2MetaInfo->GetOriginLPS() <GetProjectionAngleLPS()"<GetProjectionAngleLPS()<GetImageDirectionsLPS()"<< m_DRTImage2MetaInfo->GetImageDirectionsLPS() <GetSize()"<< m_DRTImage2MetaInfo->GetSize() <GetSpacing()"<< m_DRTImage2MetaInfo->GetSpacing() <GetOrigin()"<< m_DRTImage2MetaInfo->GetOrigin() <GetCOV()"<< m_DRTImage2MetaInfo->GetCOV() <GetOriginLPS()"<< m_DRTImage2MetaInfo->GetOriginLPS() <GetProjectionAngleLPS()"<GetProjectionAngleLPS()<GetImageDirectionsLPS()"<< m_DRTImage2MetaInfo->GetImageDirectionsLPS() < Date: Tue, 13 Sep 2022 18:55:56 +0200 Subject: [PATCH 08/49] PLEASE CHECK changes in DRTMetaInformation.cpp. Possible reason for cut of image? --- .../itkDTRrecon/DRTMetaInformation.cpp | 3 +- .../itkDTRrecon/itkImageProcessor.cpp | 43 ++++++++++--------- 2 files changed, 24 insertions(+), 22 deletions(-) diff --git a/reg23Topograms/itkDTRrecon/DRTMetaInformation.cpp b/reg23Topograms/itkDTRrecon/DRTMetaInformation.cpp index d1943e4..4aeaaff 100644 --- a/reg23Topograms/itkDTRrecon/DRTMetaInformation.cpp +++ b/reg23Topograms/itkDTRrecon/DRTMetaInformation.cpp @@ -287,7 +287,8 @@ CTVolumeImageMetaInformation::GetProjectionOriginLPSZero( PointType Origin; Origin = this->m_OriginLPS; - Origin = Origin - this->m_ImportOffset; + // Is this the trick? that cut out images? +// Origin = Origin - this->m_ImportOffset; DirectionType IECtoLPS_Directions; diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp index 19af153..e5bc174 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp @@ -157,7 +157,7 @@ itkImageProcessor::itkImageProcessor() Point3D[1]=0.; Point3D[2]=175.; m_DRTGeometryMetaInfo->SetProjectionCenter(Point3D); - m_DRTGeometryMetaInfo->SetProjectionCenter(Point3D); +// m_DRTGeometryMetaInfo->SetProjectionCenter(Point3D); ImageType3D::SizeType ImageSize; ImageSize[0]=512; @@ -1649,10 +1649,10 @@ void itkImageProcessor::UpdateProjectionGeometryMeta(){ // std::cout<< "///////////////// PGEOM META BEG ///////////////" <GetProjectionCenter() <GetProjectionCenter() <GetProjectionCenterOffset1()); + std::cout<<"CALIBRATION IsocenterOffsetLPS "<GetProjectionOriginLPS() ); - std::cout<<"Bounds2: " - <SetSizeWithBounds( vBounds.data(), @@ -1824,16 +1825,16 @@ void itkImageProcessor::UpdateProjectionGeometryMeta(){ Std_DRT2LPS) ); - std::cout<<"IsocenterOffsetLPS"<< IsocenterOffsetLPS <GetSize()"<< m_DRTImage2MetaInfo->GetSize() <GetSpacing()"<< m_DRTImage2MetaInfo->GetSpacing() <GetOrigin()"<< m_DRTImage2MetaInfo->GetOrigin() <GetCOV()"<< m_DRTImage2MetaInfo->GetCOV() <GetOriginLPS()"<< m_DRTImage2MetaInfo->GetOriginLPS() <GetProjectionAngleLPS()"<GetProjectionAngleLPS()<GetImageDirectionsLPS()"<< m_DRTImage2MetaInfo->GetImageDirectionsLPS() <GetSize()"<< m_DRTImage2MetaInfo->GetSize() <GetSpacing()"<< m_DRTImage2MetaInfo->GetSpacing() <GetOrigin()"<< m_DRTImage2MetaInfo->GetOrigin() <GetCOV()"<< m_DRTImage2MetaInfo->GetCOV() <GetOriginLPS()"<< m_DRTImage2MetaInfo->GetOriginLPS() <GetProjectionAngleLPS()"<GetProjectionAngleLPS()<GetImageDirectionsLPS()"<< m_DRTImage2MetaInfo->GetImageDirectionsLPS() < Date: Fri, 16 Sep 2022 16:53:03 +0200 Subject: [PATCH 09/49] Fixed bugs: - Interpolating all available space in DRT geometry. - Isocenter visualisation based on same filter as contours - Wrting SOP Class and SOP Instance UID in SRO --- .../itkDTRrecon/DRTMetaInformation.cpp | 87 ++++++++++--------- .../itkDTRrecon/itkImageProcessor.cpp | 4 +- ...nJacobsRayCastInterpolateImageFunction.hxx | 13 +++ .../vtkContourTopogramProjectionFilter.cxx | 3 + 4 files changed, 62 insertions(+), 45 deletions(-) diff --git a/reg23Topograms/itkDTRrecon/DRTMetaInformation.cpp b/reg23Topograms/itkDTRrecon/DRTMetaInformation.cpp index 4aeaaff..befd3b7 100644 --- a/reg23Topograms/itkDTRrecon/DRTMetaInformation.cpp +++ b/reg23Topograms/itkDTRrecon/DRTMetaInformation.cpp @@ -137,60 +137,62 @@ void DRTImageMetaInformation::SetSizeWithBounds( SpacingType Spacing) { - double dXmin = dBounds[0]; - double dYmin = dBounds[1]; - double dZmin = dBounds[2]; - double dXmax = dBounds[3]; - double dYmax = dBounds[4]; - double dZmax = dBounds[5]; +// double dXmin = dBounds[0]; +// double dYmin = dBounds[1]; +// double dZmin = dBounds[2]; +// double dXmax = dBounds[3]; +// double dYmax = dBounds[4]; +// double dZmax = dBounds[5]; - double - dNPixMin1 = 0., - dNPixMin2 = 0., - dNPixMax1 = 0., - dNPixMax2 = 0.; +// double +// dNPixMin1 = 0., +// dNPixMin2 = 0., +// dNPixMax1 = 0., +// dNPixMax2 = 0.; - dNPixMin1 = abs(dXmin / Spacing[0]); - dNPixMin2 = abs(dYmin / Spacing[0]); - dNPixMax1 = abs(dXmax / Spacing[0]); - dNPixMax2 = abs(dYmax / Spacing[0]); +// dNPixMin1 = abs(dXmin / Spacing[0]); +// dNPixMin2 = abs(dYmin / Spacing[0]); +// dNPixMax1 = abs(dXmax / Spacing[0]); +// dNPixMax2 = abs(dYmax / Spacing[0]); - double dPixMaxOverlap =dNPixMin1; +// double dPixMaxOverlap =dNPixMin1; - if(dPixMaxOverlap > dNPixMin2){ - dPixMaxOverlap = dNPixMin2; - } +// if(dPixMaxOverlap > dNPixMin2){ +// dPixMaxOverlap = dNPixMin2; +// } - if(dPixMaxOverlap > dNPixMax1){ - dPixMaxOverlap = dNPixMax1; - } +// if(dPixMaxOverlap > dNPixMax1){ +// dPixMaxOverlap = dNPixMax1; +// } - if(dPixMaxOverlap > dNPixMax2){ - dPixMaxOverlap = dNPixMax2; - } +// if(dPixMaxOverlap > dNPixMax2){ +// dPixMaxOverlap = dNPixMax2; +// } - if(floor(dPixMaxOverlap*2) > MaxSize[0]) { - m_Size[0] = MaxSize[0]; - } else { - m_Size[0] = floor(dPixMaxOverlap*2); - } +// if(floor(dPixMaxOverlap*2) > MaxSize[0]) { +// m_Size[0] = MaxSize[0]; +// } else { +// m_Size[0] = floor(dPixMaxOverlap*2); +// } - dNPixMin1 = abs(dZmin / Spacing[1]); - dNPixMax1 = abs(dZmax / Spacing[1]); +// dNPixMin1 = abs(dZmin / Spacing[1]); +// dNPixMax1 = abs(dZmax / Spacing[1]); - dPixMaxOverlap =dNPixMin1; - if(dPixMaxOverlap > dNPixMax1){ - dPixMaxOverlap = dNPixMax1; - } +// dPixMaxOverlap =dNPixMin1; +// if(dPixMaxOverlap > dNPixMax1){ +// dPixMaxOverlap = dNPixMax1; +// } - if(floor(dPixMaxOverlap*2) > MaxSize[1]) { - m_Size[1] = MaxSize[1]; - } else { - m_Size[1] = floor(dPixMaxOverlap*2); - } +// if(floor(dPixMaxOverlap*2) > MaxSize[1]) { +// m_Size[1] = MaxSize[1]; +// } else { +// m_Size[1] = floor(dPixMaxOverlap*2); +// } + m_Size[0] = MaxSize[0]; + m_Size[1] = MaxSize[1]; m_Size[2] = 1; m_Spacing = Spacing; @@ -287,8 +289,7 @@ CTVolumeImageMetaInformation::GetProjectionOriginLPSZero( PointType Origin; Origin = this->m_OriginLPS; - // Is this the trick? that cut out images? -// Origin = Origin - this->m_ImportOffset; + Origin = Origin - this->m_ImportOffset; DirectionType IECtoLPS_Directions; diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp index e5bc174..d4e67f5 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp @@ -1462,7 +1462,7 @@ void itkImageProcessor::InitializeProjector() image3DIn); resampleFilter1->SetDefaultPixelValue(0); - resampleFilter1->SetNumberOfWorkUnits(12); + resampleFilter1->SetNumberOfWorkUnits(8); // The parameters of interpolator1, such as ProjectionAngle and FocalPointToIsocenterDistance // have been set before registration. Here we only need to replace the initial @@ -1481,7 +1481,7 @@ void itkImageProcessor::InitializeProjector() resampleFilter2->SetInput( image3DIn); resampleFilter2->SetDefaultPixelValue(0); - resampleFilter2->SetNumberOfWorkUnits(12); + resampleFilter2->SetNumberOfWorkUnits(8); // The parameters of interpolator2, such as ProjectionAngle and FocalPointToIsocenterDistance diff --git a/reg23Topograms/itkDTRrecon/itkgSiddonJacobsRayCastInterpolateImageFunction.hxx b/reg23Topograms/itkDTRrecon/itkgSiddonJacobsRayCastInterpolateImageFunction.hxx index e6eb7df..db4048a 100644 --- a/reg23Topograms/itkDTRrecon/itkgSiddonJacobsRayCastInterpolateImageFunction.hxx +++ b/reg23Topograms/itkDTRrecon/itkgSiddonJacobsRayCastInterpolateImageFunction.hxx @@ -173,8 +173,21 @@ gSiddonJacobsRayCastInterpolateImageFunction::Evaluate(c regionCT = inputPtr->GetLargestPossibleRegion(); sizeCT = regionCT.GetSize(); + // If Pixel position (in mm) is outside bounds of CT (zero-based) + // assign 0 at the pixel and move on. Ensures regular spacing of resulting + // DRR + float xSizeCT = sizeCT[0] * ctPixelSpacing[0]; + float ySizeCT = sizeCT[1] * ctPixelSpacing[1]; + float zSizeCT = sizeCT[2] * ctPixelSpacing[2]; + float xDrrPix = drrPixelWorld[0];float yDrrPix = drrPixelWorld[1];float zDrrPix = drrPixelWorld[2]; +// if(zDrrPix < 0 /*|| yDrrPix < 0 || xDrrPix < 0*/) +// std::cout << drrPixelWorld[0]<<" " <xSizeCT || yDrrPix>ySizeCT || zDrrPix>zSizeCT){ + pixval = static_cast(0.0); + return pixval; + } // calculate the detector position for this pixel center by moving // 2*m_FocalPointToIsocenterDistance from the source in the pixel // directions diff --git a/reg23Topograms/itkDTRrecon/vtkContourTopogramProjectionFilter.cxx b/reg23Topograms/itkDTRrecon/vtkContourTopogramProjectionFilter.cxx index c3bd7bb..194d5f0 100644 --- a/reg23Topograms/itkDTRrecon/vtkContourTopogramProjectionFilter.cxx +++ b/reg23Topograms/itkDTRrecon/vtkContourTopogramProjectionFilter.cxx @@ -94,6 +94,7 @@ int vtkContourTopogramProjectionFilter::RequestData( // If no points, then nothing to do. if (points == nullptr) { + std::cout << "Cannot Project; no input points" << std::endl; vtkDebugMacro("Cannot Project; no input points"); return 1; } @@ -101,6 +102,7 @@ int vtkContourTopogramProjectionFilter::RequestData( // If reference transform, then nothing to do. if (m_RefTransform == nullptr) { + std::cout << "Cannot Project; no input reference projection transform" << std::endl; vtkDebugMacro("Cannot Project; no input reference projection transform"); return 1; } @@ -108,6 +110,7 @@ int vtkContourTopogramProjectionFilter::RequestData( // If transform, then nothing to do. if (m_Transform == nullptr) { + std::cout << "Cannot Project; no input projection transform" << std::endl; vtkDebugMacro("Cannot Project; no input projection transform"); return 1; } From 113dbafd6b5af97cd6899908690bd15ed0f1478f Mon Sep 17 00:00:00 2001 From: viar Date: Mon, 19 Sep 2022 10:40:39 +0200 Subject: [PATCH 10/49] Fix bugs on projection filter for contour and ISO on multiple loading. Clean up fo filter implemented --- .../vtkContourTopogramProjectionFilter.cxx | 16 ++++++++++++++++ .../vtkContourTopogramProjectionFilter.h | 2 ++ 2 files changed, 18 insertions(+) diff --git a/reg23Topograms/itkDTRrecon/vtkContourTopogramProjectionFilter.cxx b/reg23Topograms/itkDTRrecon/vtkContourTopogramProjectionFilter.cxx index 194d5f0..602abf9 100644 --- a/reg23Topograms/itkDTRrecon/vtkContourTopogramProjectionFilter.cxx +++ b/reg23Topograms/itkDTRrecon/vtkContourTopogramProjectionFilter.cxx @@ -66,6 +66,22 @@ vtkContourTopogramProjectionFilter::~vtkContourTopogramProjectionFilter() } } +void vtkContourTopogramProjectionFilter::cleanUpFilter(){ + + this->dProjectionLPSOffset[0]=0.; + this->dProjectionLPSOffset[1]=0.; + this->dProjectionLPSOffset[2]=0.; + + this->dImportOffsetLPS[0] = 0.; + this->dImportOffsetLPS[1] = 0.; + this->dImportOffsetLPS[2] = 0.; + + this->dSCD = 0.; + + this->m_RefTransform = nullptr; + this->m_Transform = nullptr; + +} int vtkContourTopogramProjectionFilter::RequestData( vtkInformation* request, vtkInformationVector** inputVector, vtkInformationVector* outputVector) diff --git a/reg23Topograms/itkDTRrecon/vtkContourTopogramProjectionFilter.h b/reg23Topograms/itkDTRrecon/vtkContourTopogramProjectionFilter.h index 568d308..da0f84a 100644 --- a/reg23Topograms/itkDTRrecon/vtkContourTopogramProjectionFilter.h +++ b/reg23Topograms/itkDTRrecon/vtkContourTopogramProjectionFilter.h @@ -41,6 +41,8 @@ public: void SetSCD(const double dVal); void SetImportOffsetLPS(const double *); + void cleanUpFilter(); + protected: vtkContourTopogramProjectionFilter(); ~vtkContourTopogramProjectionFilter() override; From 573527393400fcb42fd8f98f8d4410c78c7953dd Mon Sep 17 00:00:00 2001 From: viar Date: Mon, 19 Sep 2022 11:26:58 +0200 Subject: [PATCH 11/49] Closing issue #36. Fixed bugs on Manual transformation coloring XYZwidget orange --- .../itkDTRrecon/itkImageProcessor.cpp | 52 +++++++++---------- 1 file changed, 24 insertions(+), 28 deletions(-) diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp index d4e67f5..a89f9da 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp @@ -1589,8 +1589,8 @@ void itkImageProcessor::loadRTPlanInfo( m_RTMetaInfo->SetIsocenterLPS(Point); Point[0] = dLAT; - Point[1] = dVRT; - Point[2] = dLNG; + Point[1] = dLNG; + Point[2] = dVRT; m_RTMetaInfo->SetIsocenterIECS(Point); @@ -1647,21 +1647,17 @@ void itkImageProcessor::UpdateProjectionGeometryMeta(){ m_DRTGeometryMetaInfo->GetProjectionCenter() ); -// std::cout<< "///////////////// PGEOM META BEG ///////////////" <GetProjectionCenter() <ConvertIECPointToLPSPoint( m_DRTGeometryMetaInfo->GetProjectionCenterOffset1()); - - std::cout<<"CALIBRATION IsocenterOffsetLPS "<GetProjectionCenter() <GetProjectionOriginLPS() ); - std::cout<<"Bounds1: " - <SetSizeWithBounds( vBounds.data(), @@ -1737,16 +1733,16 @@ void itkImageProcessor::UpdateProjectionGeometryMeta(){ Std_DRT2LPS) ); - std::cout<<"IsocenterOffsetLPS"<< IsocenterOffsetLPS <GetSize()"<< m_DRTImage1MetaInfo->GetSize() <GetSpacing()"<< m_DRTImage1MetaInfo->GetSpacing() <GetOrigin()"<< m_DRTImage1MetaInfo->GetOrigin() <GetCOV()"<< m_DRTImage1MetaInfo->GetCOV() <GetOriginLPS()"<< m_DRTImage1MetaInfo->GetOriginLPS() <GetProjectionAngleLPS()"<GetProjectionAngleLPS()<GetImageDirectionsLPS()"<< m_DRTImage1MetaInfo->GetImageDirectionsLPS() <GetSize()"<< m_DRTImage1MetaInfo->GetSize() <GetSpacing()"<< m_DRTImage1MetaInfo->GetSpacing() <GetOrigin()"<< m_DRTImage1MetaInfo->GetOrigin() <GetCOV()"<< m_DRTImage1MetaInfo->GetCOV() <GetOriginLPS()"<< m_DRTImage1MetaInfo->GetOriginLPS() <GetProjectionAngleLPS()"<GetProjectionAngleLPS()<GetImageDirectionsLPS()"<< m_DRTImage1MetaInfo->GetImageDirectionsLPS() < Date: Thu, 27 Oct 2022 10:43:49 +0200 Subject: [PATCH 12/49] Closing Issue #39. Keyboard arrows for transform are completed for functionalities for both HFS and FFS. N.B. changes to files in itkDTRecon are not doing anything to the library --- .../itkDTRrecon/itkImageProcessor.cpp | 18 ++---------------- ...onJacobsRayCastInterpolateImageFunction.hxx | 1 + 2 files changed, 3 insertions(+), 16 deletions(-) diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp index a89f9da..7120366 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp @@ -1363,10 +1363,6 @@ void itkImageProcessor::InitializeProjector() - - - - //CurrTransform->SetComputeZYX(true); //CurrTransform->SetIdentity(); @@ -1435,12 +1431,6 @@ void itkImageProcessor::InitializeProjector() interpolator2->SetTransform(transform2); interpolator2->Initialize(); - - - - - - // // 2D Image 2 // interpolator2->SetProjectionAngle( // dtr * @@ -1454,14 +1444,10 @@ void itkImageProcessor::InitializeProjector() // interpolator2->Initialize(); - - - resampleFilter1 = ResampleFilterType::New(); resampleFilter1->SetInput( image3DIn); resampleFilter1->SetDefaultPixelValue(0); - resampleFilter1->SetNumberOfWorkUnits(8); // The parameters of interpolator1, such as ProjectionAngle and FocalPointToIsocenterDistance @@ -1604,8 +1590,8 @@ void itkImageProcessor::loadRTPlanInfo( ) ); - std::cout<< "m_CTMetaInfo->GetImportOffset() " - <GetImportOffset() <GetImportOffset() " +// <GetImportOffset() <UpdateProjectionGeometryMeta(); this->InitializeProjector(); diff --git a/reg23Topograms/itkDTRrecon/itkgSiddonJacobsRayCastInterpolateImageFunction.hxx b/reg23Topograms/itkDTRrecon/itkgSiddonJacobsRayCastInterpolateImageFunction.hxx index db4048a..e574b22 100644 --- a/reg23Topograms/itkDTRrecon/itkgSiddonJacobsRayCastInterpolateImageFunction.hxx +++ b/reg23Topograms/itkDTRrecon/itkgSiddonJacobsRayCastInterpolateImageFunction.hxx @@ -184,6 +184,7 @@ gSiddonJacobsRayCastInterpolateImageFunction::Evaluate(c // if(zDrrPix < 0 /*|| yDrrPix < 0 || xDrrPix < 0*/) // std::cout << drrPixelWorld[0]<<" " <xSizeCT || yDrrPix>ySizeCT || zDrrPix>zSizeCT){ pixval = static_cast(0.0); return pixval; From 42c9360b210e9ea9cb8c0ccd6db7b81a8a29e115 Mon Sep 17 00:00:00 2001 From: Proton local user Date: Thu, 3 Nov 2022 17:22:34 +0100 Subject: [PATCH 13/49] Issue #8. A solution (psiReto) is now in the code. Possibly dirty --- .../itkDTRrecon/itkImageProcessor.cpp | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp index 7120366..c1d01e4 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp @@ -466,6 +466,11 @@ int itkImageProcessor::load3DSerieFromFiles( std::vector v_fnames){ caster3D->SetInput(imageSeriesReader3D->GetOutput()); caster3D->Update(); + if (m_VolumeSourceDupli) { + m_VolumeSourceDupli = NULL; + m_VolumeSourceDupli = DuplicatorType::New(); + } + m_VolumeSourceDupli->SetInputImage(caster3D->GetOutput()); m_VolumeSourceDupli->Update(); @@ -595,6 +600,11 @@ int itkImageProcessor::load3DSerieFromFolder(const char * pcDirName) caster3D->SetInput(imageSeriesReader3D->GetOutput()); caster3D->Update(); + if (m_VolumeSourceDupli) { + m_VolumeSourceDupli = NULL; + m_VolumeSourceDupli = DuplicatorType::New(); + } + m_VolumeSourceDupli->SetInputImage(caster3D->GetOutput()); m_VolumeSourceDupli->Update(); @@ -623,18 +633,22 @@ int itkImageProcessor::fill3DVolumeMeta( if(m_CTMetaInfo != NULL){ + m_CTMetaInfo = NULL; // TODO UNLOAD } if(m_DRTImage1MetaInfo != NULL){ + m_DRTImage1MetaInfo = NULL; // TODO UNLOAD } if(m_DRTImage2MetaInfo != NULL){ + m_DRTImage2MetaInfo = NULL; // TODO UNLOAD } if(m_RTMetaInfo != NULL){ + m_RTMetaInfo = NULL; // TODO UNLOAD } @@ -711,6 +725,11 @@ int itkImageProcessor::fill3DVolumeMeta( pZeroOrigin[1] = 0.; pZeroOrigin[2] = 0.; + if (m_3DInputChangeInformationToZero) { + m_3DInputChangeInformationToZero = NULL; + m_3DInputChangeInformationToZero = ChangeInformationFilterType::New(); + } + m_3DInputChangeInformationToZero->SetInput( m_VolumeSourceDupli->GetOutput()); m_3DInputChangeInformationToZero->SetOutputOrigin( @@ -1024,6 +1043,11 @@ int itkImageProcessor::load2D(const char * pcFName){ switch (currProjOrientation) { case eProjectionOrientationType::PA: + if (m_PASourceDupli) { + m_PASourceDupli = NULL; + m_PASourceDupli = DuplicatorType::New(); + } + //m_ImageIntensity = d_image1IntensityWindow; m_Duplicator = m_PASourceDupli; m_TImageMeta = m_TImage1MetaInfo; @@ -1033,6 +1057,11 @@ int itkImageProcessor::load2D(const char * pcFName){ case eProjectionOrientationType::LAT: + if (m_LATSourceDupli) { + m_LATSourceDupli = NULL; + m_LATSourceDupli = DuplicatorType::New(); + } + //m_ImageIntensity = d_image2IntensityWindow; m_Duplicator = m_LATSourceDupli; // m_ImLoaded = &image2D2Loaded; From 80aecca90c92fc8c011994e406f93e140f25b68f Mon Sep 17 00:00:00 2001 From: viar Date: Fri, 25 Nov 2022 18:59:31 +0100 Subject: [PATCH 14/49] Working version of issue #32. Everything works fine. New settings.ini is noyt uploaded to repo has there is a minor inconsistency in settings on my MAC. Needs to double check modifications to itkImageProcessor (very minor) --- .../itkDTRrecon/itkImageProcessor.cpp | 48 +++++++++++++++++++ .../itkDTRrecon/itkImageProcessor.h | 1 + 2 files changed, 49 insertions(+) diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp index c1d01e4..6ccc350 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp @@ -239,6 +239,7 @@ void itkImageProcessor::SetSCDOffset(double dOff1, double dOff2) { m_DRTGeometryMetaInfo->SetSCD1Offset(dOff1); m_DRTGeometryMetaInfo->SetSCD2Offset(dOff2); + } void itkImageProcessor::SetSCD(double dDist1, double dDist2) @@ -382,6 +383,9 @@ void itkImageProcessor::SetCustom_2Dsize(int nX1, int nY1,int nX2,int nY2) } void itkImageProcessor::SetCustom_UpdateMetaInfo(){ + + + this->UpdateProjectionGeometryMeta(); } @@ -852,6 +856,8 @@ void itkImageProcessor::SetProjectionAngleOffsetIEC(double dOff1, double dOff2) { m_DRTGeometryMetaInfo->SetProjectionAngle1OffsetIEC(dOff1); m_DRTGeometryMetaInfo->SetProjectionAngle2OffsetIEC(dOff2); + + std::cout << "SetProjectionAngleOffsetIEC " << dOff1 << " " << dOff2 << std::endl; } @@ -1106,6 +1112,27 @@ int itkImageProcessor::load2D(const char * pcFName){ } +int itkImageProcessor::query2DimageReconstructionDiameter(const char *pcFName){ + + /* Check if we can open the file */ + gdcm::Reader R; + R.SetFileName(pcFName); + if(!R.Read()) + { cerr<<"ERROR: cannot read file: "<SetProjectionAngleLPS( + this->CalcProjectionAngleLPS( + m_CTMetaInfo->GetPatientOrientation(), + m_DRTGeometryMetaInfo->GetProjectionAngle1IEC() + + m_DRTGeometryMetaInfo->GetProjectionAngle1OffsetIEC()) + ); + m_DRTImage1MetaInfo->SetSCD( + m_DRTGeometryMetaInfo->GetSCD1() + + m_DRTGeometryMetaInfo->GetSCD1Offset() + ); m_DRTImage1MetaInfo->SetProjectionOriginLPS( CalibratedIsocenterLPS); @@ -1781,6 +1818,17 @@ void itkImageProcessor::UpdateProjectionGeometryMeta(){ IsocenterOffsetLPS[2]; + m_DRTImage2MetaInfo->SetProjectionAngleLPS( + this->CalcProjectionAngleLPS( + m_CTMetaInfo->GetPatientOrientation(), + m_DRTGeometryMetaInfo->GetProjectionAngle2IEC() + + m_DRTGeometryMetaInfo->GetProjectionAngle2OffsetIEC()) + ); + + m_DRTImage2MetaInfo->SetSCD( + m_DRTGeometryMetaInfo->GetSCD2()+ + m_DRTGeometryMetaInfo->GetSCD2Offset() + ); m_DRTImage2MetaInfo->SetProjectionOriginLPS( diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.h b/reg23Topograms/itkDTRrecon/itkImageProcessor.h index 079e33a..4ae4bbe 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.h +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.h @@ -76,6 +76,7 @@ public: int load3DSerieFromFiles( std::vector ); int load2D(const char *); + int query2DimageReconstructionDiameter(const char*); void loadRTPlanInfo(double, double, double, double, double ,double); From e304e1c00412df1a2fe3739f3b25766fe8920f4c Mon Sep 17 00:00:00 2001 From: Proton local user Date: Tue, 6 Dec 2022 16:48:08 +0100 Subject: [PATCH 15/49] Changed to 16 bit for image visualisation --- .../itkDTRrecon/itkImageProcessor.cpp | 34 +++++++++++++------ .../itkDTRrecon/itkImageProcessor.h | 2 +- 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp index 6ccc350..a62a769 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp @@ -1576,8 +1576,6 @@ void itkImageProcessor::InitializeProjector() imageDRT2In = filter2->GetOutput(); -// std::cout<< "itkImageProcessor::InitializeProjector() END" <; RescaleFilterType::Pointer rescaler1 = RescaleFilterType::New(); rescaler1->SetOutputMinimum(0); - rescaler1->SetOutputMaximum(255); + rescaler1->SetOutputMaximum(32768); rescaler1->SetInput(m_PASourceDupli->GetOutput()); rescaler1->Update(); @@ -2296,12 +2294,12 @@ vtkImageData* itkImageProcessor::GetLocalizer2VTK() { - // Rescale the intensity of the projection images to 0-255 for output. + // Rescale the intensity of the projection images to 0-32768 for output. using RescaleFilterType = itk::RescaleIntensityImageFilter; RescaleFilterType::Pointer rescaler2 = RescaleFilterType::New(); rescaler2->SetOutputMinimum(0); - rescaler2->SetOutputMaximum(255); + rescaler2->SetOutputMaximum(32768); rescaler2->SetInput(m_LATSourceDupli ->GetOutput()); rescaler2->Update(); @@ -2356,16 +2354,30 @@ vtkImageData* itkImageProcessor::GetLocalizer2VTK() vtkImageData* itkImageProcessor::GetProjection1VTK() { - // Rescale the intensity of the projection images to 0-255 for output. + // Rescale the intensity of the projection images to 0-32768 for output. using RescaleFilterType = itk::RescaleIntensityImageFilter; RescaleFilterType::Pointer rescaler1 = RescaleFilterType::New(); rescaler1->SetOutputMinimum(0); - rescaler1->SetOutputMaximum(255); + rescaler1->SetOutputMaximum(32768); rescaler1->SetInput( imageDRT1In ); - rescaler1->Update(); +// using ImageCalculatorFilterType = itk::MinimumMaximumImageCalculator; +// auto imageCalculatorFilter = ImageCalculatorFilterType::New(); +// imageCalculatorFilter->SetImage(imageDRT1In); +// imageCalculatorFilter->Compute(); + +// std::cout<< "itkImageProcessor::imageDRT1In() " << +// imageCalculatorFilter <; +// auto imageCalculatorFilter2 = ImageCalculatorFilterType2::New(); +// imageCalculatorFilter2->SetImage(rescaler1->GetOutput()); +// imageCalculatorFilter2->Compute(); +// std::cout<< "itkImageProcessor::imageDRT2In() " << +// imageCalculatorFilter2 <SetInput(rescaler1->GetOutput()); toVTK2D1->Update(); @@ -2471,12 +2483,12 @@ vtkMatrix4x4 * itkImageProcessor::GetProjection2VTKTransform() vtkImageData* itkImageProcessor::GetProjection2VTK() { - // Rescale the intensity of the projection images to 0-255 for output. + // Rescale the intensity of the projection images to 0-32768 for output. using RescaleFilterType = itk::RescaleIntensityImageFilter; RescaleFilterType::Pointer rescaler2 = RescaleFilterType::New(); rescaler2->SetOutputMinimum(0); - rescaler2->SetOutputMaximum(255); + rescaler2->SetOutputMaximum(32768); rescaler2->SetInput( imageDRT2In ); rescaler2->Update(); diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.h b/reg23Topograms/itkDTRrecon/itkImageProcessor.h index 4ae4bbe..5e2de92 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.h +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.h @@ -160,7 +160,7 @@ protected: using InternalPixelType = float; using PixelType2D = short; using PixelType3D = short; - using OutputPixelType = unsigned char; + using OutputPixelType = unsigned short; using ImageType3D = itk::Image; using InternalImageType = itk::Image; From 1f72aa4ba5bcf279b344ba2a6ebbfea69e1fc6e1 Mon Sep 17 00:00:00 2001 From: Proton local user Date: Thu, 8 Dec 2022 11:06:01 +0100 Subject: [PATCH 16/49] Added Interpolator for Reslice in DRT ad Topo. Working ok even though there is a discrepancy between visualistaion of single DRT and DRT and TOPO --- reg23Topograms/itkDTRrecon/itkImageProcessor.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp index a62a769..54ab2f0 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp @@ -1693,11 +1693,11 @@ void itkImageProcessor::UpdateProjectionGeometryMeta(){ IsocenterOffsetLPS = m_CTMetaInfo->ConvertIECPointToLPSPoint( m_DRTGeometryMetaInfo->GetProjectionCenterOffset1()); -// std::cout<< "///////////////// PGEOM META BEG ///////////////" <GetProjectionCenter() <GetProjectionCenter() <GetSize()"<< m_DRTImage1MetaInfo->GetSize() <GetSpacing()"<< m_DRTImage1MetaInfo->GetSpacing() <GetOrigin()"<< m_DRTImage1MetaInfo->GetOrigin() < Date: Wed, 21 Dec 2022 16:15:58 +0100 Subject: [PATCH 17/49] First integration of Automatic Registration is running (on Approve button). There is in this commit soem confusion and changes in the DRR writing for testing with Alex --- reg23Topograms/itkDTRrecon/CMakeLists.txt | 3 + .../itkDTRrecon/DRTMetaInformation.cpp | 2 + .../itkDTRrecon/DRTMetaInformation.h | 71 ++- .../itkDTRrecon/itkImageProcessor.cpp | 540 +++++++++++++++++- .../itkDTRrecon/itkImageProcessor.h | 176 +++++- 5 files changed, 749 insertions(+), 43 deletions(-) diff --git a/reg23Topograms/itkDTRrecon/CMakeLists.txt b/reg23Topograms/itkDTRrecon/CMakeLists.txt index c93893c..60032bc 100644 --- a/reg23Topograms/itkDTRrecon/CMakeLists.txt +++ b/reg23Topograms/itkDTRrecon/CMakeLists.txt @@ -2,6 +2,8 @@ cmake_minimum_required(VERSION 2.8.12) SET(LIB_NAME itkDTRrecon) +add_subdirectory(autoreg) + find_package(ITK REQUIRED) include(${ITK_USE_FILE}) INCLUDE_DIRECTORIES(${ITK_INCLUDE_DIRS}) @@ -34,6 +36,7 @@ SET(LINK_LIBS ${VTK_LIBRARIES} ${ITK_LIBRARIES} gdcmMSFF + autoreg ) TARGET_LINK_LIBRARIES( diff --git a/reg23Topograms/itkDTRrecon/DRTMetaInformation.cpp b/reg23Topograms/itkDTRrecon/DRTMetaInformation.cpp index befd3b7..748cded 100644 --- a/reg23Topograms/itkDTRrecon/DRTMetaInformation.cpp +++ b/reg23Topograms/itkDTRrecon/DRTMetaInformation.cpp @@ -531,6 +531,8 @@ TransformMetaInformation (){ m_CurrentTransform.Fill(0.); + m_DegreeOfFreedom = tDegreeOfFreedomEnum::UNKNOWN; + } void diff --git a/reg23Topograms/itkDTRrecon/DRTMetaInformation.h b/reg23Topograms/itkDTRrecon/DRTMetaInformation.h index 5ec3556..d79ffd1 100644 --- a/reg23Topograms/itkDTRrecon/DRTMetaInformation.h +++ b/reg23Topograms/itkDTRrecon/DRTMetaInformation.h @@ -11,15 +11,70 @@ namespace itk { -typedef enum eProjectionOrientationType -{NA = 0, LAT=2, PA=1} -tProjOrientationType; +typedef enum eProjectionOrientationType{ + NA = 0, + LAT=2, + PA=1 +} tProjOrientationType; /** Enum type for Orientation */ -typedef enum eImageOrientationType -{NotDefined = 0, HFS = 1, FFS = 2} -tPatOrientation; +typedef enum eImageOrientationType{ + NotDefined = 0, + HFS = 1, + FFS = 2 +} tPatOrientation; +typedef enum eDegreeOfFreedomType { + UNKNOWN = 0, + THREE_DOF, + SIX_DOF, + X_ONLY, + Y_ONLY, + Z_ONLY, + ROTATION_ONLY, + OTHER +} tDegreeOfFreedomEnum; + +inline int GetNumberOfDOF(eDegreeOfFreedomType dof) +{ + switch (dof) { + case SIX_DOF: + return 6; + break; + case THREE_DOF: + case ROTATION_ONLY: + return 3; + break; + case X_ONLY: + case Y_ONLY: + case Z_ONLY: + return 1; + break; + default: + return 0; + } +} + + +class DegreeOfFreedom : public itk::Object { + +public: + typedef DegreeOfFreedom Self; + typedef itk::Object Superclass; + typedef itk::SmartPointer Pointer; + + itkNewMacro(Self); + +protected: + bool + m_TranslationX, + m_TranslationY, + m_TranslationZ, + m_RotationX, + m_RotationY, + m_RotationZ; + tDegreeOfFreedomEnum m_dof; +}; class TopogramImageMetaInformation : public itk::Object{ @@ -490,6 +545,8 @@ public: itkSetMacro(CurrentTransform,TransformMatrixType); itkGetMacro(CurrentTransform,TransformMatrixType); + itkSetEnumMacro(DegreeOfFreedom, tDegreeOfFreedomEnum); + itkGetEnumMacro(DegreeOfFreedom, tDegreeOfFreedomEnum); protected: @@ -503,6 +560,8 @@ protected: m_ReferenceTransform, m_CurrentTransform; + tDegreeOfFreedomEnum + m_DegreeOfFreedom; /** Default Constructor **/ TransformMetaInformation (); diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp index 54ab2f0..e613dd6 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp @@ -14,6 +14,7 @@ gfattori 08.11.2021 #include "itkImageProcessor.h" #include "itkCreateObjectFunction.h" +#include "itkDRTHelpers.h" #include "itkVersion.h" #include #include @@ -24,6 +25,8 @@ gfattori 08.11.2021 #include "itkOrientImageFilter.h" #include +#include "itkTimeProbesCollectorBase.h" + #include @@ -31,34 +34,6 @@ gfattori 08.11.2021 namespace itk { -/* this is in the end a IEC to HFS... - * but we keep this for ourselves... - */ -static double Standard_DRT2LPS [9] = { - 1,0,0, - 0,0,-1, - 0,1,0 }; - -static double PAElementsIEC[9] = { - 1, 0, 0, - 0, -1, 0, - 0, 0, -1 }; - -static double LATElementsIEC[9] = { - 0, 0, -1, - 0, -1, 0, - -1, 0, 0}; - -static double HFS2IEC[9] = { - 1, 0, 0, - 0, 0, 1, - 0, -1, 0}; - -static double FFS2IEC[9] = { - -1, 0, 0, - 0, 0, -1, - 0, -1, 0}; - //FUNCTION DECLARATION NECESSARY FOR COPY/PASTE FROM vtkGDCMImageReader // const char *gGetStringValueFromTag(const gdcm::Tag& t, const gdcm::DataSet& ds); @@ -97,6 +72,8 @@ itkImageProcessor::itkImageProcessor() // TZero[0]=TZero[1]=TZero[2]=0.; // RZero[0]=RZero[1]=RZero[2]=0.; + + toVTK2D1 = ITKtoVTKFilterType::New(); toVTK2D2 = ITKtoVTKFilterType::New(); toVTKLocalizer1 = ITKtoVTKFilterType::New(); @@ -217,7 +194,37 @@ itkImageProcessor::itkImageProcessor() // }; + // setup the Automatic Registration + metric = MetricType::New(); + mimetric = MIMetricType::New(); + optimizer = OptimizerType::New(); + amoebaoptimizer = AmoebaOptimizerType::New(); + + optimizerObserver = CommandIterationUpdate::New(); + + exhaustiveOptimizer = ExhaustiveOptimizerType::New(); + exhaustiveOptimizerObserver = ExhaustiveCommandIterationUpdate::New(); + + registration = RegistrationType::New(); + + if (m_UseMutualInformation) { + registration->SetMetric(mimetric); + } else { + registration->SetMetric(metric); + } + + registration->SetOptimizer(optimizer); + registration->SetTransform1(transform1); + registration->SetTransform2(transform2); + registration->SetInterpolator1(interpolator1); + registration->SetInterpolator2(interpolator2); + + m_UseExhaustiveOptmizer = false; //if the exhaustive optimizer shal be used, ovverrides ameoba + m_UseAmeobaOptimizer = false; //if the ameoba optimzer shall be used, otherwise Powell. Overriden by Exhaustive option. + m_UseFullROI = true; // if the full image ROI shall be used + m_UseMutualInformation = false; //oterwise NCC is used + m_UseDumptoFile = false; //If each (!) optimzer result shall be dumpped into a file. } itkImageProcessor::~itkImageProcessor() @@ -257,6 +264,17 @@ double itkImageProcessor::GetSCD2(){ m_DRTImage1MetaInfo ->GetSCD(); } +void itkImageProcessor::SetDegreeOfFreedom(tDegreeOfFreedomEnum dof) +{ + m_TransformMetaInfo->SetDegreeOfFreedom(dof); +} + +tDegreeOfFreedomEnum +itkImageProcessor::GetDegreeOfFreedom() +{ + return m_TransformMetaInfo->GetDegreeOfFreedom(); +} + void itkImageProcessor::SetCustom_ImportTransform(double dTx, double dTy, double dTz, @@ -384,8 +402,6 @@ void itkImageProcessor::SetCustom_2Dsize(int nX1, int nY1,int nX2,int nY2) void itkImageProcessor::SetCustom_UpdateMetaInfo(){ - - this->UpdateProjectionGeometryMeta(); } @@ -1254,6 +1270,35 @@ itkImageProcessor::MapTransformToNewOrigin( return m_OutputTransform; } + +// This External User Transform thing need to be checked out +void itkImageProcessor::CalculateExternalUserTransform(TransformType::Pointer transform, DRTImageMetaInformation::Pointer imageMetaInfo) +{ + //crude hack to get from internal transform in LPS to external transform in IEC. + //result is stored in m_TransformMetaInfo + + //TODO: support for projectionTransformCenter and userTransformCenter which are not the same + //currentlz we support only pFakeIsoLPS situations. + + InternalImageType::DirectionType LPStoIEC_Directions; + LPStoIEC_Directions = m_CTMetaInfo->GetLPS2IECDirections(); + + auto parameters = transform->GetParameters(); + + ImageType3D::PointType translationUser; + translationUser[0] = parameters[3]; + translationUser[1] = parameters[4]; + translationUser[2] = parameters[5]; + ImageType3D::PointType rotationUser; + rotationUser[0] = parameters[0]; + rotationUser[1] = parameters[1]; + rotationUser[2] = parameters[2]; + + m_TransformMetaInfo->SetUserTranslations(LPStoIEC_Directions * translationUser); + m_TransformMetaInfo->SetUserRotations(LPStoIEC_Directions * rotationUser); +} + + itkImageProcessor::TransformType::Pointer itkImageProcessor::CalculateInternalTransform( ImageType3D::PointType m_TranslationOffset, //IEC @@ -1323,6 +1368,362 @@ itkImageProcessor::CalculateInternalTransform( m_OutputTransform; } +void itkImageProcessor::InitializeRegistration(int maximumIteration, double stepLength, double maxTranslation, eDegreeOfFreedomType dof) +{ + std::cout << "*" << __COMPACT_PRETTY_FUNCTION__ << std::endl; + + if (!m_PASourceDupli) { + itkExceptionMacro(<< "PA topogram not present"); + } + + if (!m_LATSourceDupli) { + itkExceptionMacro(<< "LAT topogram not present"); + } + + if (!m_VolumeSourceDupli) { + itkExceptionMacro(<< "CT data not present"); + } + + metric->ComputeGradientOff(); + metric->SetSubtractMean(true); + metric->SetMaxTranslation(maxTranslation); + + m_TransformMetaInfo->SetDegreeOfFreedom(dof); + + mimetric->ComputeGradientOff(); + + if (verbose) { + metric->DebugOn(); + } + + registration->SetFixedImage1(m_PASourceDupli->GetOutput()); + registration->SetFixedImage2(m_LATSourceDupli->GetOutput()); + registration->SetMovingImage(m_VolumeSourceDupli->GetOutput()); + + //TODO: Here we could set the ROI for image registartion + + auto region1 = m_PASourceDupli->GetOutput()->GetBufferedRegion(); + auto region2 = m_LATSourceDupli->GetOutput()->GetBufferedRegion(); + + // bool setROI = false; + // if (setROI) { + // auto index1 = region1.GetIndex(); + // auto size1 = region1.GetSize(); + // auto point1 = m_PASourceDupli->GetOutput()->GetOrigin(); + + // index1[0] = size1[0] / 2 - 50; + // index1[1] = size1[1] / 2 - 50; + + // size1[0] = 100; + // size1[1] = 100; + // size1[2] = 1; + + // region1.SetIndex(index1); + // region1.SetSize(size1); + // } + + registration->SetFixedImageRegion1(region1); + registration->SetFixedImageRegion2(region2); + + registration->SetTransformMetaInfo(m_TransformMetaInfo); + + registration->SetFilter1(filter1); + registration->SetFilter2(filter2); + + //CalculateInternalTransform(transform1, m_DRTImage1MetaInfo); + /********* BEGIN CALCULATION OF INTERNAL TRANSFORM FOR PROJ1 *********/ + ImageType3D::PointType ZeroPoint; + ZeroPoint.Fill(0.); + InternalImageType::DirectionType IECtoLPS_Directions; + IECtoLPS_Directions = + m_CTMetaInfo->GetLPS2IECDirections().GetTranspose(); + TransformType::Pointer CurrTransform; + if(m_RTMetaInfo == NULL) + { + + //AAAAAA TODOOOOO CERCA + ImageType3D::PointType pFakeIsoLPS = + m_DRTImage1MetaInfo->GetProjectionOriginLPS(); + //ImageType3D::PointType pFakeIsoLPS = + // m_CTMetaInfo->GetProjectionOriginLPS( + // m_DRTGeometryMetaInfo->GetProjectionCenter1()); + CurrTransform = + CalculateInternalTransform( + ZeroPoint, + ZeroPoint, + m_TransformMetaInfo->GetTranslations(), + m_TransformMetaInfo->GetRotations(), + m_DRTImage1MetaInfo->GetProjectionOriginLPS(), + pFakeIsoLPS, + ZeroPoint, + IECtoLPS_Directions + ); + } else { + + CurrTransform = + CalculateInternalTransform( + ZeroPoint , + m_DRTGeometryMetaInfo->GetIECS2IECScannerR(), + m_TransformMetaInfo->GetTranslations(), + m_TransformMetaInfo->GetRotations(), + m_DRTImage1MetaInfo->GetProjectionOriginLPS(), + m_RTMetaInfo->GetIsocenterLPS() - m_CTMetaInfo->GetImportOffset(), + m_CTMetaInfo->GetImportOffset(), + IECtoLPS_Directions + ); + + } + + + transform1->SetComputeZYX(true); + transform1->SetIdentity(); + transform1->SetTranslation( + CurrTransform->GetTranslation()); + transform1->SetRotation( + CurrTransform->GetAngleX(), + CurrTransform->GetAngleY(), + CurrTransform->GetAngleZ() + ); + transform1->SetCenter( + m_DRTImage1MetaInfo->GetProjectionOriginLPSZero() ); + /********* END OF CALCULATE INTERNAL TRANSFORM FOR PROJ1 *********/ + + + //CalculateInternalTransform(transform2, m_DRTImage2MetaInfo); + /********* BEGIN CALCULATION OF INTERNAL TRANSFORM FOR PROJ2 *********/ + if(m_RTMetaInfo == NULL) + { + ImageType3D::PointType pFakeIsoLPS = + m_DRTImage2MetaInfo->GetProjectionOriginLPS(); + + //ImageType3D::PointType pFakeIsoLPS = + // m_CTMetaInfo->GetProjectionOriginLPS( + // m_DRTGeometryMetaInfo->GetProjectionCenter2()); + + + + CurrTransform = + CalculateInternalTransform( + ZeroPoint, + ZeroPoint, + m_TransformMetaInfo->GetTranslations(), + m_TransformMetaInfo->GetRotations(), + m_DRTImage2MetaInfo->GetProjectionOriginLPS(), + pFakeIsoLPS, + ZeroPoint, + IECtoLPS_Directions + ); + } else { + + CurrTransform = + CalculateInternalTransform( + ZeroPoint , + m_DRTGeometryMetaInfo->GetIECS2IECScannerR(), + m_TransformMetaInfo->GetTranslations(), + m_TransformMetaInfo->GetRotations(), + m_DRTImage2MetaInfo->GetProjectionOriginLPS(), + m_RTMetaInfo->GetIsocenterLPS() - m_CTMetaInfo->GetImportOffset(), + m_CTMetaInfo->GetImportOffset(), + IECtoLPS_Directions + ); + + } + transform2->SetComputeZYX(true); + transform2->SetIdentity(); + transform2->SetTranslation( + CurrTransform->GetTranslation()); + transform2->SetRotation( + CurrTransform->GetAngleX(), + CurrTransform->GetAngleY(), + CurrTransform->GetAngleZ() + ); + transform2->SetCenter( + m_DRTImage2MetaInfo->GetProjectionOriginLPSZero() ); + /********* END OF CALCULATE INTERNAL TRANSFORM FOR PROJ1 *********/ + + + if (verbose) { + registration->DebugOn(); + registration->Print(std::cout); + } + + if (!m_UseExhaustiveOptmizer) { + if (!m_UseAmeobaOptimizer) { + + // The metric will return 0 or a "large" negative number in case of high correspondence of the images + // Thus, we need to minimze + optimizer->SetMaximize(false); // for NCC and MI + optimizer->SetMaximumIteration(maximumIteration); + optimizer->SetMaximumLineIteration(4); // for Powell's method + optimizer->SetStepLength(stepLength); + optimizer->SetStepTolerance(0.01); + optimizer->SetValueTolerance(0.000002); + if (verbose) { + optimizer->DebugOn(); + optimizer->Print(std::cout); + } + + optimizer->RemoveAllObservers(); + optimizer->AddObserver(itk::IterationEvent(), optimizerObserver); + + registration->SetOptimizer(optimizer); + } else { + + amoebaoptimizer->SetMinimize(true); + amoebaoptimizer->SetMaximumNumberOfIterations(100); + amoebaoptimizer->SetParametersConvergenceTolerance(0.1); + amoebaoptimizer->SetFunctionConvergenceTolerance(0.000002); + + amoebaoptimizer->SetAutomaticInitialSimplex(false); + //Initial size of the simplex (otherwise it is a very small number and optimizer stops immeditaly) + // 2 mm / 2 degrees seems to be a good value which performs well. + OptimizerType::ParametersType simplexDelta(3); + int numberOfDOF = GetNumberOfDOF(dof); + if (numberOfDOF == 0) { + itkExceptionMacro(<< "Unkown or unsupported degree of freedom"); + } + for (int i = 0; i < numberOfDOF; i++) { + simplexDelta[i] = 2.0; + } + amoebaoptimizer->SetInitialSimplexDelta(simplexDelta); + + amoebaoptimizer->RemoveAllObservers(); + amoebaoptimizer->AddObserver(itk::IterationEvent(), optimizerObserver); + + registration->SetOptimizer(amoebaoptimizer); + } + + } else { + //only support for 3DOF + const int numberOfSteps = 25; //In each direction. Total number of steps is ((2*numberOfSteps+1))^3. For 25 -> 132651. + const double stepLength = 0.1; + + auto parameters = transform1->GetParameters(); + transform1->SetParameters(parameters); + + ExhaustiveOptimizerType::StepsType steps(3); + steps[0] = numberOfSteps; + steps[1] = numberOfSteps; + steps[2] = numberOfSteps; + exhaustiveOptimizer->SetNumberOfSteps(steps); + exhaustiveOptimizer->SetStepLength(stepLength); + + exhaustiveOptimizer->RemoveAllObservers(); + exhaustiveOptimizer->AddObserver(itk::IterationEvent(), exhaustiveOptimizerObserver); + + exhaustiveOptimizer->SetStepLength(stepLength); + registration->SetOptimizer(exhaustiveOptimizer); + } + + std::cout << "#" << __COMPACT_PRETTY_FUNCTION__ << std::endl; +} + +int itkImageProcessor::StartRegistration(std::string extraInfo) +{ + + std::cout << "*" << __COMPACT_PRETTY_FUNCTION__ << std::endl; + // TODO: Check if the registartion pipeline has been initialized + using ParametersType = RegistrationType::ParametersType; + + auto startParameters = transform1->GetParameters(); + + time_t t = time(0); // get time now + struct tm* now = localtime(&t); + + bool useDumpToFile = false; + + char buffer[255]; + strftime(buffer, 255, "test-%F-%H%M%S.txt", now); + + std::fstream fs; + + if (useDumpToFile || m_UseExhaustiveOptmizer) { + fs.open(buffer, std::fstream::out); + fs << extraInfo; + fs << "Value\tX\tY\tZ " << std::endl; + + if (m_UseExhaustiveOptmizer) { + exhaustiveOptimizerObserver->set_stream(fs); + } + } + + // Start the registration + // ~~~~~~~~~~~~~~~~~~~~~~ + + // Create a timer to record calculation time. + itk::TimeProbesCollectorBase timer; + + if (verbose) { + std::cout << "Starting the registration now..." << std::endl; + } + + try { + timer.Start("Registration"); + // Start the registration. + registration->StartRegistration(); + timer.Stop("Registration"); + } catch (itk::ExceptionObject& err) { + std::cout << "ExceptionObject caught !" << std::endl; + std::cout << err << std::endl; + return -1; + } + + auto oldprecision = fs.precision(); + + if (m_UseExhaustiveOptmizer) { + fs.precision(std::numeric_limits::digits10 + 2); + fs << " MinimumMetricValue: " << exhaustiveOptimizer->GetMinimumMetricValue() << std::endl; + fs << " MaximumMetricValue: " << exhaustiveOptimizer->GetMaximumMetricValue() << std::endl; + fs.precision(oldprecision); + fs << " MinimumMetricValuePosition: " << exhaustiveOptimizer->GetMinimumMetricValuePosition() << std::endl; + fs << " MaximumMetricValuePosition: " << exhaustiveOptimizer->GetMaximumMetricValuePosition() << std::endl; + fs << " StopConditionDescription: " << exhaustiveOptimizer->GetStopConditionDescription() << std::endl; + fs << " MaximumMetricValuePosition: " << exhaustiveOptimizer->GetMaximumMetricValuePosition() << std::endl; + } else if (useDumpToFile) { + fs.precision(std::numeric_limits::digits10 + 2); + fs << " FinalMetricValue: " << optimizer->GetValue() << std::endl; //same as GetCurrentCost + fs.precision(oldprecision); + fs << " FinalPosition: " << optimizer->GetCurrentPosition() << std::endl; + fs << " Iterations: " << optimizer->GetCurrentIteration() << std::endl; + fs << " StopConditionDescription: " << optimizer->GetStopConditionDescription() << std::endl; + } + + fs.close(); + + m_OptmizerValue = optimizer->GetValue(); + + auto finalParameters = transform1->GetParameters(); + optimizer->GetCurrentPosition(); + finalParameters = finalParameters - startParameters; + + TransformType::Pointer offsetTransform = TransformType::New(); + offsetTransform->SetParameters(finalParameters); + + CalculateExternalUserTransform(offsetTransform, m_DRTImage1MetaInfo); + + const double translationAlongX = finalParameters[3]; + const double translationAlongY = finalParameters[4]; + const double translationAlongZ = finalParameters[5]; + const double rotationAlongX = finalParameters[0]; + const double rotationAlongY = finalParameters[1]; + const double rotationAlongZ = finalParameters[2]; + + const int numberOfIterations = optimizer->GetCurrentIteration(); + + std::cout << "Result = " << std::endl; + std::cout << " Rotation Along X = " << rotationAlongX / dtr << " deg" << std::endl; + std::cout << " Rotation Along Y = " << rotationAlongY / dtr << " deg" << std::endl; + std::cout << " Rotation Along Z = " << rotationAlongZ / dtr << " deg" << std::endl; + std::cout << " Translation X = " << translationAlongX << " mm" << std::endl; + std::cout << " Translation Y = " << translationAlongY << " mm" << std::endl; + std::cout << " Translation Z = " << translationAlongZ << " mm" << std::endl; + std::cout << " Number Of Iterations = " << numberOfIterations << std::endl; + std::cout << " Metric value = " << m_OptmizerValue << std::endl; + + std::cout << "#" << __COMPACT_PRETTY_FUNCTION__ << std::endl; + + return 0; +} void itkImageProcessor::InitializeProjector() { @@ -2643,6 +3044,85 @@ double* itkImageProcessor::GetTransformParameters(){ return dTransfParam; } +// Doubts about this user thing +void itkImageProcessor::GetFinalTranslations(double& dX, double& dY, double& dZ) +{ + ImageType3D::PointType translations = m_TransformMetaInfo->GetTranslations(); + ImageType3D::PointType userTranslations = m_TransformMetaInfo->GetUserTranslations(); + + dX = translations[0] + userTranslations[0]; + dY = translations[1] + userTranslations[1]; + dZ = translations[2] + userTranslations[2]; +} + +void itkImageProcessor::GetFinalRotations(double& dRX, double& dRY, double& dRZ) +{ + ImageType3D::PointType rotations = m_TransformMetaInfo->GetRotations(); + ImageType3D::PointType userRotations = m_TransformMetaInfo->GetUserRotations(); + + dRX = rotations[0] + userRotations[0]; + dRY = rotations[1] + userRotations[1]; + dRZ = rotations[2] + userRotations[2]; +} + + +double itkImageProcessor::GetOptimizerValue() +{ + return m_OptmizerValue; +} + +double itkImageProcessor::GetCurrentMetricValue() +{ + //Note: this fails if the metric has not been propperly initilzed. + + if (!m_UseMutualInformation) { + if (metric == NULL) { + return nan(""); + } + return metric->GetValue(); + } else { + if (mimetric == NULL) { + return nan(""); + } + return mimetric->GetValue(); + } +} + +void itkImageProcessor::SetROI(double, double, double, double) +{ + //TODO: Not implemanted yet. ROI are hard coded and can be enabled using SetFullROI. +} + +void itkImageProcessor::SetOptimizer(std::string optimizer) +{ + if (optimizer.compare("Powell") == 0) { + m_UseAmeobaOptimizer = false; + m_UseExhaustiveOptmizer = false; + } else if (optimizer.compare("Amoeba") == 0) { + m_UseExhaustiveOptmizer = false; + m_UseAmeobaOptimizer = true; + } else if (optimizer.compare("Exhaustive") == 0) { + m_UseExhaustiveOptmizer = true; + m_UseAmeobaOptimizer = false; + } else { + itkExceptionMacro(<< "Unkown optimzer string : " << optimizer); + } +} +void itkImageProcessor::SetMetric(std::string metric) +{ + if (metric.compare("NCC") == 0) { + m_UseMutualInformation = false; + } else if (metric.compare("MI") == 0) { + m_UseMutualInformation = true; + } else { + itkExceptionMacro(<< "Unkown metric string : " << optimizer); + } +} +void itkImageProcessor::SetFullROI(bool fullROI) +{ + m_UseFullROI = fullROI; + // TODO: Remove this function when ROI functinalitz has been implemented. +} } // end namespace itk diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.h b/reg23Topograms/itkDTRrecon/itkImageProcessor.h index 5e2de92..19ad4d8 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.h +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.h @@ -30,6 +30,13 @@ gfattori 08.11.2021 #include "itkObjectFactory.h" #include "itkSmartPointer.h" +#include "itkExhaustiveOptimizer.h" +#include "itkMutualInformationTwoImageToOneImageMetric.h" +#include "itkNormalizedCorrelationTwoImageToOneImageMetric.h" +#include "itkPowellOptimizer.h" +#include "itkTwoProjectionImageRegistrationMethod.h" +#include "itkAmoebaOptimizer.h" + #include "itkImageToVTKImageFilter.h" #include "itkImageFileReader.h" @@ -46,13 +53,104 @@ gfattori 08.11.2021 namespace itk { -/* reference string required for comparison with tag values */ -static const char *ImageOrientationStrings[] = { - "NotDefined", - "HFS", - "FFS" + +class CommandIterationUpdate : public itk::Command { + // TODO: Move to own files. + +public: + using Self = CommandIterationUpdate; + using Superclass = itk::Command; + using Pointer = itk::SmartPointer; + itkNewMacro(Self); + +protected: + CommandIterationUpdate() = default; + +public: + using OptimizerType = itk::PowellOptimizer; + using OptimizerPointer = const OptimizerType*; + + using AmoebaOptimizerType = itk::AmoebaOptimizer; + ; + using AmoebaOptimizerPointer = const OptimizerType*; + + void + Execute(itk::Object* caller, const itk::EventObject& event) override + { + Execute((const itk::Object*)caller, event); + } + + void + Execute(const itk::Object* object, const itk::EventObject& event) override + { + auto optimizer = dynamic_cast(object); + if (typeid(event) == typeid(itk::IterationEvent)) { + + //Feedback from the optimizer executed at the end of every itteration + // currently just print the result into the cout. We might add + // functionality to register and emit signals to update the UI. + + std::cout << "Iteration: " << optimizer->GetCurrentIteration() << std::endl; + auto oldprecision = std::cout.precision(); + std::cout.precision(std::numeric_limits::digits10 + 2); + std::cout << "Similarity: " << optimizer->GetValue() << std::endl; + std::cout.precision(oldprecision); + std::cout << "Position: " << optimizer->GetCurrentPosition() << std::endl; + } + return; + } }; +class ExhaustiveCommandIterationUpdate : public itk::Command { + // TODO: Move to own files. + +public: + using Self = ExhaustiveCommandIterationUpdate; + using Superclass = itk::Command; + using Pointer = itk::SmartPointer; + itkNewMacro(Self); + + std::ostream* os; + +protected: + ExhaustiveCommandIterationUpdate() = default; + +public: + using OptimizerType = itk::ExhaustiveOptimizer; + ; + using OptimizerPointer = const OptimizerType*; + + void set_stream(std::ostream& stream) + { + os = &stream; + } + + void + Execute(itk::Object* caller, const itk::EventObject& event) override + { + Execute((const itk::Object*)caller, event); + } + + void + Execute(const itk::Object* object, const itk::EventObject& event) override + { + auto optimizer = dynamic_cast(object); + if (typeid(event) == typeid(itk::IterationEvent)) { + + //crude LPS to IEC transform for HFS. + auto position = optimizer->GetCurrentPosition(); + + auto oldprecision = os->precision(); + os->precision(std::numeric_limits::digits10 + 2); + *os << optimizer->GetCurrentValue(); + os->precision(oldprecision); + *os << "\t" << position[0] << "\t" << position[2] << "\t" << -position[1] << std::endl; + } + return; + } +}; + + class ITK_EXPORT itkImageProcessor : public itk::Object { @@ -97,6 +195,10 @@ public: double GetSCD1(); double GetSCD2(); + /** Sets the degree of freedom for omptimzation*/ + void SetDegreeOfFreedom(tDegreeOfFreedomEnum); + tDegreeOfFreedomEnum GetDegreeOfFreedom(); + void SetCustom_ProjectionCenterOffsetFixedAxes_IEC(double,double,double,double,double,double); void SetCustom_ProjectionCenterFixedAxes_IEC(double,double,double); @@ -117,6 +219,19 @@ public: void SetInitialTranslations(double, double, double); void SetInitialRotations(double, double, double); + /** Get transform parameters for 3D Volume */ + void GetFinalTranslations(double&, double&, double&); + void GetFinalRotations(double&, double&, double&); + + /** Set user transform parameters for 3D Volume in LPS*/ + void SetUserTranslationsLPS(double, double, double); + void SetUserRotationsLPS(double, double, double); + + /** Initialize the registration pipeline*/ + void InitializeRegistration(int, double, double, eDegreeOfFreedomType); + /** Start the registration process*/ + int StartRegistration(std::string extraInfo); + /** Get transform parameters for 3D Volume */ double* GetTransformParameters(); @@ -129,8 +244,6 @@ public: /** Get Projection origin in LPS coordinates*/ const std::vector GetRTImportOffset(); - - /** Get the Localizer intensity window and * center for rendering */ double GetLocalizerDisplayWindowLevel(int ); @@ -153,6 +266,17 @@ public: void WriteProjectionImages(); void Write2DImages(); + /** Get the current cost function value from the optimizer*/ + double GetOptimizerValue(); + + /** Get the cost function value for the current transform*/ + double GetCurrentMetricValue(); + + void SetROI(double, double, double, double); + + void SetOptimizer(std::string); + void SetMetric(std::string); + void SetFullROI(bool); protected: @@ -189,6 +313,16 @@ private: using InterpolatorType = itk::gSiddonJacobsRayCastInterpolateImageFunction; using ResampleFilterType = itk::ResampleImageFilter; + /** Optimizer which tries to find the minimn (Powell Optimizer)*/ + using OptimizerType = itk::PowellOptimizer; + using AmoebaOptimizerType = itk::AmoebaOptimizer; + /** Optimizer which samples the whol space */ + using ExhaustiveOptimizerType = itk::ExhaustiveOptimizer; + /** Metric to calculate similarites between images*/ + using MetricType = itk::NormalizedCorrelationTwoImageToOneImageMetric; + using MIMetricType = itk::MutualInformationTwoImageToOneImageMetric; + /** The thing which actuall does the image registration*/ + using RegistrationType = itk::TwoProjectionImageRegistrationMethod; /** Image reader types */ using ImageReaderType2D = itk::ImageFileReader; @@ -206,6 +340,8 @@ private: /** ITK to VTK filter */ using ITKtoVTKFilterType = itk::ImageToVTKImageFilter; + void + CalculateExternalUserTransform(TransformType::Pointer transform, DRTImageMetaInformation::Pointer imageMetaInfo); TransformType::Pointer CalculateInternalTransform( @@ -239,6 +375,23 @@ private: imageDRT1In, imageDRT2In; + RegistrationType::Pointer + registration; + MetricType::Pointer + metric; + MIMetricType::Pointer + mimetric; + OptimizerType::Pointer + optimizer; + AmoebaOptimizerType::Pointer + amoebaoptimizer; + CommandIterationUpdate::Pointer + optimizerObserver; + ExhaustiveOptimizerType::Pointer + exhaustiveOptimizer; + ExhaustiveCommandIterationUpdate::Pointer + exhaustiveOptimizerObserver; + DuplicatorType::Pointer m_LATSourceDupli, m_PASourceDupli, @@ -335,6 +488,15 @@ private: TransformMetaInformation::Pointer m_TransformMetaInfo; + + double m_OptmizerValue; + + bool m_UseExhaustiveOptmizer; + bool m_UseAmeobaOptimizer; + bool m_UseFullROI; + bool m_UseMutualInformation; + bool m_UseDumptoFile; + }; From 13e49503a736257f7bf525aece0a47023911c920 Mon Sep 17 00:00:00 2001 From: Proton local user Date: Mon, 23 Jan 2023 16:35:14 +0100 Subject: [PATCH 18/49] Adding new files for Automatic Registration --- .../itkDTRrecon/autoreg/CMakeLists.txt | 32 ++ .../itkDTRrecon/autoreg/itkDRTHelpers.h | 93 +++++ ...utualInformationTwoImageToOneImageMetric.h | 117 ++++++ ...ualInformationTwoImageToOneImageMetric.hxx | 201 +++++++++ ...lizedCorrelationTwoImageToOneImageMetric.h | 127 ++++++ ...zedCorrelationTwoImageToOneImageMetric.hxx | 321 ++++++++++++++ .../itkTwoProjectionImageRegistrationMethod.h | 269 ++++++++++++ ...tkTwoProjectionImageRegistrationMethod.hxx | 327 +++++++++++++++ .../autoreg/itkgTwoImageToOneImageMetric.h | 300 +++++++++++++ .../autoreg/itkgTwoImageToOneImageMetric.hxx | 395 ++++++++++++++++++ 10 files changed, 2182 insertions(+) create mode 100644 reg23Topograms/itkDTRrecon/autoreg/CMakeLists.txt create mode 100644 reg23Topograms/itkDTRrecon/autoreg/itkDRTHelpers.h create mode 100644 reg23Topograms/itkDTRrecon/autoreg/itkMutualInformationTwoImageToOneImageMetric.h create mode 100644 reg23Topograms/itkDTRrecon/autoreg/itkMutualInformationTwoImageToOneImageMetric.hxx create mode 100644 reg23Topograms/itkDTRrecon/autoreg/itkNormalizedCorrelationTwoImageToOneImageMetric.h create mode 100644 reg23Topograms/itkDTRrecon/autoreg/itkNormalizedCorrelationTwoImageToOneImageMetric.hxx create mode 100644 reg23Topograms/itkDTRrecon/autoreg/itkTwoProjectionImageRegistrationMethod.h create mode 100644 reg23Topograms/itkDTRrecon/autoreg/itkTwoProjectionImageRegistrationMethod.hxx create mode 100644 reg23Topograms/itkDTRrecon/autoreg/itkgTwoImageToOneImageMetric.h create mode 100644 reg23Topograms/itkDTRrecon/autoreg/itkgTwoImageToOneImageMetric.hxx diff --git a/reg23Topograms/itkDTRrecon/autoreg/CMakeLists.txt b/reg23Topograms/itkDTRrecon/autoreg/CMakeLists.txt new file mode 100644 index 0000000..adee1d8 --- /dev/null +++ b/reg23Topograms/itkDTRrecon/autoreg/CMakeLists.txt @@ -0,0 +1,32 @@ +SET(LIB_NAME autoreg) +SET(CMAKE_CXX_FLAGS "-std=c++11 -fPIC") + + +find_package(ITK REQUIRED) +include(${ITK_USE_FILE}) +INCLUDE_DIRECTORIES(${ITK_INCLUDE_DIRS}) + + +SET(HDR +itkDRTHelpers.h +itkgTwoImageToOneImageMetric.h +itkgTwoImageToOneImageMetric.hxx +itkMutualInformationTwoImageToOneImageMetric.h +itkMutualInformationTwoImageToOneImageMetric.hxx +itkNormalizedCorrelationTwoImageToOneImageMetric.h +itkNormalizedCorrelationTwoImageToOneImageMetric.hxx +itkTwoProjectionImageRegistrationMethod.h +itkTwoProjectionImageRegistrationMethod.hxx +) + +ADD_LIBRARY(${LIB_NAME} ${HDR}) + +target_link_libraries( + ${LIB_NAME} + ${ITK_LIBRARIES} +) + +target_include_directories (${LIB_NAME} + PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) + + diff --git a/reg23Topograms/itkDTRrecon/autoreg/itkDRTHelpers.h b/reg23Topograms/itkDTRrecon/autoreg/itkDRTHelpers.h new file mode 100644 index 0000000..e8e563e --- /dev/null +++ b/reg23Topograms/itkDTRrecon/autoreg/itkDRTHelpers.h @@ -0,0 +1,93 @@ +#ifndef ITKDRTHELPERS_H +#define ITKDRTHELPERS_H + +#include "itkMath.h" +#include +#include +#include + +//Function to get method and class name for logging purposes. +template +const char* computeMethodName(const char (&function)[FL], const char (&prettyFunction)[PFL]) +{ + using reverse_ptr = std::reverse_iterator; + thread_local static char result[PFL]; + const char* locFuncName = std::search(prettyFunction, prettyFunction + PFL - 1, function, function + FL - 1); + const char* locClassName = std::find(reverse_ptr(locFuncName), reverse_ptr(prettyFunction), ' ').base(); + const char* endFuncName = std::find(locFuncName, prettyFunction + PFL - 1, '('); + result[0] = '\0'; + std::strncat(result, locClassName, endFuncName - locClassName + 1); + std::strcat(result, ")"); + return result; +} +#define __COMPACT_PRETTY_FUNCTION__ computeMethodName(__FUNCTION__, __PRETTY_FUNCTION__) + +namespace itk { +/* reference string required for comparison with tag values */ +static const char* ImageOrientationStrings[] = { + "NotDefined", + "HFS", + "FFS", + "HFP", + "FFP", +}; + +// constant for converting degrees into radians +const float dtr = itk::Math::pi_over_180; + +static const bool verbose = true; + +/* this is in the end a IEC to HFS... + * but we keep this for ourselves... + */ +static double Standard_DRT2LPS[9] = { + 1, 0, 0, + 0, 0, -1, + 0, 1, 0 +}; + +static double PAElementsIEC[9] = { + 1, 0, 0, + 0, -1, 0, + 0, 0, -1 +}; + +static double LATElementsIEC[9] = { + 0, 0, -1, + 0, -1, 0, + -1, 0, 0 +}; + +static double HFS2IEC[9] = { + 1, 0, 0, + 0, 0, 1, + 0, -1, 0 +}; + +static double FFS2IEC[9] = { + -1, 0, 0, + 0, 0, -1, + 0, -1, 0 +}; + +static double HFP2IEC[9] = { + -1, 0, 0, + 0, 0, 1, + 0, 1, 0 +}; + +static double FFP2IEC[9] = { + 1, 0, 0, + 0, 0, -1, + 0, 1, 0 +}; + +static double PAT2IEC[9] = { + 1, 0, 0, + 0, 0, 1, + 0, -1, 0 +}; + +} + +#endif // ITKDRTHELPERS_H diff --git a/reg23Topograms/itkDTRrecon/autoreg/itkMutualInformationTwoImageToOneImageMetric.h b/reg23Topograms/itkDTRrecon/autoreg/itkMutualInformationTwoImageToOneImageMetric.h new file mode 100644 index 0000000..678d7c0 --- /dev/null +++ b/reg23Topograms/itkDTRrecon/autoreg/itkMutualInformationTwoImageToOneImageMetric.h @@ -0,0 +1,117 @@ +/*========================================================================= + * + * Copyright NumFOCUS + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0.txt + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *=========================================================================*/ +#ifndef itkMutualInformationTwoImageToOneImageMetric_h +#define itkMutualInformationTwoImageToOneImageMetric_h + +#include "itkCovariantVector.h" +#include "itkMacro.h" +#include "itkPoint.h" +#include "itkgTwoImageToOneImageMetric.h" + +namespace itk { +/** \class NormalizedCorrelationTwoImageToOneImageMetric + * \brief Computes similarity between two fixed images and one moving image + * + * This metric computes the correlation between pixels in the two fixed images + * and pixels in the moving image. The spatial correspondance between + * two fixed images and the moving image is established through a Transform. Pixel values are + * taken from the fixed images, their positions are mapped to the moving + * image and result in general in non-grid position on it. Values at these + * non-grid position of the moving image are interpolated using user-selected + * Interpolators. The correlation is normalized by the autocorrelations of both + * the fixed and moving images. + * + * \ingroup RegistrationMetrics + * \ingroup TwoProjectionRegistration + */ +template +class MutualInformationTwoImageToOneImageMetric : public gTwoImageToOneImageMetric { +public: + ITK_DISALLOW_COPY_AND_ASSIGN(MutualInformationTwoImageToOneImageMetric); + + /** Standard class type alias. */ + using Self = MutualInformationTwoImageToOneImageMetric; + using Superclass = gTwoImageToOneImageMetric; + + using Pointer = SmartPointer; + using ConstPointer = SmartPointer; + + /** Method for creation through the object factory. */ + itkNewMacro(Self); + + /** Run-time type information (and related methods). */ + itkTypeMacro(MutualInformationTwoImageToOneImageMetric, Object); + + /** Types transferred from the base class */ + using RealType = typename Superclass::RealType; + using TransformType = typename Superclass::TransformType; + using TransformPointer = typename Superclass::TransformPointer; + using TransformParametersType = typename Superclass::TransformParametersType; + using TransformJacobianType = typename Superclass::TransformJacobianType; + using GradientPixelType = typename Superclass::GradientPixelType; + + using MeasureType = typename Superclass::MeasureType; + using DerivativeType = typename Superclass::DerivativeType; + using FixedImageType = typename Superclass::FixedImageType; + using MovingImageType = typename Superclass::MovingImageType; + using FixedImageConstPointer = typename Superclass::FixedImageConstPointer; + using MovingImageConstPointer = typename Superclass::MovingImageConstPointer; + + /** Get the derivatives of the match measure. */ + void + GetDerivative(const TransformParametersType& parameters, DerivativeType& Derivative) const override; + + /** Get the value for single valued optimizers. */ + MeasureType + GetValue(const TransformParametersType& parameters) const override; + + /** Get the value using the current transforms. */ + MeasureType + GetValue() const; + + /** Get value and derivatives for multiple valued optimizers. */ + void + GetValueAndDerivative(const TransformParametersType& parameters, + MeasureType& Value, + DerivativeType& Derivative) const override; + + /** Set/Get SubtractMean boolean. If true, the sample mean is subtracted + * from the sample values in the cross-correlation formula and + * typically results in narrower valleys in the cost fucntion. + * Default value is false. */ + itkSetMacro(SubtractMean, bool); + itkGetConstReferenceMacro(SubtractMean, bool); + itkBooleanMacro(SubtractMean); + +protected: + MutualInformationTwoImageToOneImageMetric(); + ~MutualInformationTwoImageToOneImageMetric() override = default; + void + PrintSelf(std::ostream& os, Indent indent) const override; + +private: + bool m_SubtractMean; +}; + +} // end namespace itk + +#ifndef ITK_MANUAL_INSTANTIATION +#include "itkMutualInformationTwoImageToOneImageMetric.hxx" +#endif + +#endif diff --git a/reg23Topograms/itkDTRrecon/autoreg/itkMutualInformationTwoImageToOneImageMetric.hxx b/reg23Topograms/itkDTRrecon/autoreg/itkMutualInformationTwoImageToOneImageMetric.hxx new file mode 100644 index 0000000..748df79 --- /dev/null +++ b/reg23Topograms/itkDTRrecon/autoreg/itkMutualInformationTwoImageToOneImageMetric.hxx @@ -0,0 +1,201 @@ +/*========================================================================= + * + * Copyright NumFOCUS + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0.txt + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *=========================================================================*/ +#ifndef itkMutualInformationTwoImageToOneImageMetric_hxx +#define itkMutualInformationTwoImageToOneImageMetric_hxx + +#include "itkImageRegionConstIteratorWithIndex.h" +#include "itkMattesMutualInformationImageToImageMetric.h" +#include "itkMutualInformationTwoImageToOneImageMetric.h" +#include "itkNearestNeighborInterpolateImageFunction.h" +#include "itkNormalizeImageFilter.h" +#include "itkTranslationTransform.h" + +#include + +namespace itk { + +template +MutualInformationTwoImageToOneImageMetric::MutualInformationTwoImageToOneImageMetric() +{ + m_SubtractMean = false; +} + +template +typename MutualInformationTwoImageToOneImageMetric::MeasureType +MutualInformationTwoImageToOneImageMetric::GetValue( + const TransformParametersType& parameters) const +{ + FixedImageConstPointer fixedImage1 = this->m_FixedImage1; + + if (!fixedImage1) { + itkExceptionMacro(<< "Fixed image1 has not been assigned"); + } + + FixedImageConstPointer fixedImage2 = this->m_FixedImage2; + + if (!fixedImage2) { + itkExceptionMacro(<< "Fixed image2 has not been assigned"); + } + + if (!this->m_Filter1) { + itkExceptionMacro(<< "Fixed filter1 has not been assigned"); + } + + if (!this->m_Filter2) { + itkExceptionMacro(<< "Fixed filter1 has not been assigned"); + } + + this->SetTransformParameters(parameters); + + return GetValue(); +} + +template +typename MutualInformationTwoImageToOneImageMetric::MeasureType +MutualInformationTwoImageToOneImageMetric::GetValue() const +{ + + FixedImageConstPointer fixedImage1 = this->m_FixedImage1; + + if (!fixedImage1) { + itkExceptionMacro(<< "Fixed image1 has not been assigned"); + } + + FixedImageConstPointer fixedImage2 = this->m_FixedImage2; + + if (!fixedImage2) { + itkExceptionMacro(<< "Fixed image2 has not been assigned"); + } + + if (!this->m_Filter1) { + itkExceptionMacro(<< "Fixed filter1 has not been assigned"); + } + + if (!this->m_Filter2) { + itkExceptionMacro(<< "Fixed filter1 has not been assigned"); + } + + this->m_Interpolator1->SetTransform(this->m_Transform1); + this->m_Interpolator1->Initialize(); + this->m_Filter1->Update(); + + using InternalMetricType = itk::MattesMutualInformationImageToImageMetric; + + using NearestNeighborType = itk::NearestNeighborInterpolateImageFunction; + + //We need to set transform and parameters. + auto dummyTransform = TransformType::New(); + auto dummyParameters = dummyTransform->GetParameters(); + auto dummyInterpolator1 = NearestNeighborType::New(); + + auto metric1 = InternalMetricType::New(); + metric1->SetTransform(dummyTransform); + metric1->SetTransformParameters(dummyParameters); + metric1->SetInterpolator(dummyInterpolator1); + + auto fixedImageRegion1 = fixedImage1->GetBufferedRegion(); + metric1->SetFixedImageRegion(fixedImageRegion1); + + auto movingImageRegion = this->m_Filter1->GetOutput()->GetBufferedRegion(); + unsigned int numberOfPixels = movingImageRegion.GetNumberOfPixels(); + + //auto numberOfSamples = static_cast(numberOfPixels * 0.50); //100% + metric1->UseAllPixelsOn(); + metric1->SetNumberOfHistogramBins(30); + + metric1->SetFixedImage(fixedImage1); + metric1->SetMovingImage(this->m_Filter1->GetOutput()); + + metric1->Initialize(); + + auto measure1 = metric1->GetValue(dummyParameters); + + this->m_Interpolator2->SetTransform(this->m_Transform2); + this->m_Interpolator2->Initialize(); + this->m_Filter2->Update(); + + auto dummyInterpolator2 = NearestNeighborType::New(); + auto metric2 = InternalMetricType::New(); + metric2->SetTransform(dummyTransform); + metric2->SetTransformParameters(dummyParameters); + metric2->SetInterpolator(dummyInterpolator2); + + auto fixedImageRegion2 = fixedImage1->GetBufferedRegion(); + metric2->SetFixedImageRegion(fixedImageRegion2); + + movingImageRegion = this->m_Filter2->GetOutput()->GetBufferedRegion(); + numberOfPixels = movingImageRegion.GetNumberOfPixels(); + + //numberOfSamples = static_cast(numberOfPixels * 0.50); //100% + //%metric2->SetNumberOfSpatialSamples(numberOfSamples); + metric2->UseAllPixelsOn(); + metric2->SetNumberOfHistogramBins(30); + + metric2->SetFixedImage(fixedImage2); + metric2->SetMovingImage(this->m_Filter2->GetOutput()); + + metric2->Initialize(); + + auto measure2 = metric2->GetValue(dummyParameters); + + //std::cout << "movingValueMin: " << movingValueMin << " movingValueMax: " << movingValueMax << std::endl; + //std::cout << "fixedValueMin: " << fixedValueMin << " fixedValueMax: " << fixedValueMax << std::endl; + + // Calculate the measure value between fixed image 2 and the moving image + + auto measure = (measure1 + measure2) / 2.0; + + auto oldprecision = std::cout.precision(); + std::cout.precision(std::numeric_limits::digits10 + 2); + std::cout << "Measure1: " << measure1 << " Counts: " << this->m_NumberOfPixelsCounted << std::endl; + std::cout << "Measure2: " << measure2 << " Counts: " << this->m_NumberOfPixelsCounted << std::endl; + std::cout << "Measure: " << measure << std::endl; + std::cout << "=======================================================" << std::endl; + std::cout.precision(oldprecision); + return measure; +} + +template +void MutualInformationTwoImageToOneImageMetric::GetDerivative( + const TransformParametersType& itkNotUsed(parameters), + DerivativeType& itkNotUsed(derivative)) const +{ + // under construction +} + +template +void MutualInformationTwoImageToOneImageMetric::GetValueAndDerivative( + const TransformParametersType& itkNotUsed(parameters), + MeasureType& itkNotUsed(value), + DerivativeType& itkNotUsed(derivative)) const +{ + // under construction +} + +template +void MutualInformationTwoImageToOneImageMetric::PrintSelf(std::ostream& os, + Indent indent) const +{ + Superclass::PrintSelf(os, indent); + os << indent << "SubtractMean: " << m_SubtractMean << std::endl; +} + +} // end namespace itk + +#endif diff --git a/reg23Topograms/itkDTRrecon/autoreg/itkNormalizedCorrelationTwoImageToOneImageMetric.h b/reg23Topograms/itkDTRrecon/autoreg/itkNormalizedCorrelationTwoImageToOneImageMetric.h new file mode 100644 index 0000000..0257965 --- /dev/null +++ b/reg23Topograms/itkDTRrecon/autoreg/itkNormalizedCorrelationTwoImageToOneImageMetric.h @@ -0,0 +1,127 @@ +/*========================================================================= + * + * Copyright NumFOCUS + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0.txt + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *=========================================================================*/ +#ifndef itkNormalizedCorrelationTwoImageToOneImageMetric_h +#define itkNormalizedCorrelationTwoImageToOneImageMetric_h + +#include "itkCovariantVector.h" +#include "itkMacro.h" +#include "itkNormalizedCorrelationImageToImageMetric.hxx" +#include "itkPoint.h" +#include "itkgTwoImageToOneImageMetric.h" + +namespace itk { +/** \class NormalizedCorrelationTwoImageToOneImageMetric + * \brief Computes similarity between two fixed images and one moving image + * + * This metric computes the correlation between pixels in the two fixed images + * and pixels in the moving image. The spatial correspondance between + * two fixed images and the moving image is established through a Transform. Pixel values are + * taken from the fixed images, their positions are mapped to the moving + * image and result in general in non-grid position on it. Values at these + * non-grid position of the moving image are interpolated using user-selected + * Interpolators. The correlation is normalized by the autocorrelations of both + * the fixed and moving images. + * + * \ingroup RegistrationMetrics + * \ingroup TwoProjectionRegistration + */ +template +class NormalizedCorrelationTwoImageToOneImageMetric : public gTwoImageToOneImageMetric { +public: + ITK_DISALLOW_COPY_AND_ASSIGN(NormalizedCorrelationTwoImageToOneImageMetric); + + /** Standard class type alias. */ + using Self = NormalizedCorrelationTwoImageToOneImageMetric; + using Superclass = gTwoImageToOneImageMetric; + + using Pointer = SmartPointer; + using ConstPointer = SmartPointer; + + /** Method for creation through the object factory. */ + itkNewMacro(Self); + + /** Run-time type information (and related methods). */ + itkTypeMacro(NormalizedCorrelationTwoImageToOneImageMetric, Object); + + /** Types transferred from the base class */ + using RealType = typename Superclass::RealType; + using TransformType = typename Superclass::TransformType; + using TransformPointer = typename Superclass::TransformPointer; + using TransformParametersType = typename Superclass::TransformParametersType; + using TransformJacobianType = typename Superclass::TransformJacobianType; + using GradientPixelType = typename Superclass::GradientPixelType; + + using MeasureType = typename Superclass::MeasureType; + using DerivativeType = typename Superclass::DerivativeType; + + using FixedImageType = typename Superclass::FixedImageType; + using FixedImageConstPointer = typename Superclass::FixedImageConstPointer; + using FixedImageMaskPointer = typename Superclass::FixedImageMaskPointer; + using FixedImageRegionType = typename Superclass::FixedImageRegionType; + + using MovingImageType = typename Superclass::MovingImageType; + using MovingImageConstPointer = typename Superclass::MovingImageConstPointer; + using MovingImageMaskPointer = typename Superclass::MovingImageMaskPointer; + + using ChangeInformationFilterPointer = typename Superclass::ChangeInformationFilterPointer; + + /** Get the derivatives of the match measure. */ + void + GetDerivative(const TransformParametersType& parameters, DerivativeType& Derivative) const override; + + /** Get the value for single valued optimizers, after applying paramters to the transforms. */ + MeasureType + GetValue(const TransformParametersType& parameters) const override; + + /** Get the value using the current transforms. */ + MeasureType + GetValue() const; + + /** Get value and derivatives for multiple valued optimizers. */ + void + GetValueAndDerivative(const TransformParametersType& parameters, + MeasureType& Value, + DerivativeType& Derivative) const override; + + /** Set/Get SubtractMean boolean. If true, the sample mean is subtracted + * from the sample values in the cross-correlation formula and + * typically results in narrower valleys in the cost fucntion. + * Default value is false. */ + itkSetMacro(SubtractMean, bool); + itkGetConstReferenceMacro(SubtractMean, bool); + itkBooleanMacro(SubtractMean); + +protected: + NormalizedCorrelationTwoImageToOneImageMetric(); + ~NormalizedCorrelationTwoImageToOneImageMetric() override = default; + void + PrintSelf(std::ostream& os, Indent indent) const override; + +private: + bool m_SubtractMean; + + MeasureType CalculateMeasure(int imageId) const; +}; + +} // end namespace itk + +#ifndef ITK_MANUAL_INSTANTIATION +#include "itkNormalizedCorrelationTwoImageToOneImageMetric.hxx" +#endif + +#endif diff --git a/reg23Topograms/itkDTRrecon/autoreg/itkNormalizedCorrelationTwoImageToOneImageMetric.hxx b/reg23Topograms/itkDTRrecon/autoreg/itkNormalizedCorrelationTwoImageToOneImageMetric.hxx new file mode 100644 index 0000000..f76c15f --- /dev/null +++ b/reg23Topograms/itkDTRrecon/autoreg/itkNormalizedCorrelationTwoImageToOneImageMetric.hxx @@ -0,0 +1,321 @@ +/*========================================================================= + * + * Copyright NumFOCUS + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0.txt + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *=========================================================================*/ +#ifndef itkNormalizedCorrelationTwoImageToOneImageMetric_hxx +#define itkNormalizedCorrelationTwoImageToOneImageMetric_hxx + +#include "itkImageRegionConstIteratorWithIndex.h" +#include "itkNormalizedCorrelationTwoImageToOneImageMetric.h" + +# + +namespace itk { + +template +NormalizedCorrelationTwoImageToOneImageMetric::NormalizedCorrelationTwoImageToOneImageMetric() +{ + m_SubtractMean = false; +} + +template +typename NormalizedCorrelationTwoImageToOneImageMetric::MeasureType +NormalizedCorrelationTwoImageToOneImageMetric::CalculateMeasure(int imageId) const +{ + + using FixedIteratorType = itk::ImageRegionConstIteratorWithIndex; + using MovingIteratorType = itk::ImageRegionConstIteratorWithIndex; + using AccumulateType = typename NumericTraits::AccumulateType; + + FixedImageConstPointer fixedImage; + ChangeInformationFilterPointer filter; + FixedImageMaskPointer fixedImageMask; + FixedImageRegionType fixedImageRegion; + MeasureType measure; + + typename FixedImageType::IndexType indexFixed; + typename MovingImageType::IndexType indexMoving; + typename Superclass::InputPointType inputPoint; + + if (imageId == 1) { + this->m_Interpolator1->SetTransform(this->m_Transform1); + this->m_Interpolator1->Initialize(); + + fixedImage = this->m_FixedImage1; + fixedImageMask = this->m_FixedImageMask1; + fixedImageRegion = this->GetFixedImageRegion1(); + filter = this->m_Filter1; + } else if (imageId == 2) { + this->m_Interpolator2->SetTransform(this->m_Transform2); + this->m_Interpolator2->Initialize(); + + fixedImage = this->m_FixedImage2; + fixedImageMask = this->m_FixedImageMask2; + fixedImageRegion = this->GetFixedImageRegion2(); + filter = this->m_Filter2; + } else { + itkExceptionMacro(<< "Non supported image id."); + } + + FixedIteratorType ti(fixedImage, fixedImageRegion); + + this->m_NumberOfPixelsCounted = 0; + int numberOfPixelsVisited = 0; + + //filter->Update(); + filter->Update(); + MovingImageConstPointer imageDRTIn = filter->GetOutput(); + //this->WriteImage(imageDRTIn, "", ""); + + AccumulateType sff = NumericTraits::ZeroValue(); + AccumulateType smm = NumericTraits::ZeroValue(); + AccumulateType sfm = NumericTraits::ZeroValue(); + AccumulateType sf = NumericTraits::ZeroValue(); + AccumulateType sm = NumericTraits::ZeroValue(); + + RealType movingValueMin = NumericTraits::max(); + RealType fixedValueMin = NumericTraits::max(); + RealType movingValueMax = NumericTraits::NonpositiveMin(); + RealType fixedValueMax = NumericTraits::NonpositiveMin(); + + RealType maxX = NumericTraits::NonpositiveMin(); + RealType maxY = NumericTraits::NonpositiveMin(); + RealType maxZ = NumericTraits::NonpositiveMin(); + RealType minX = NumericTraits::max(); + RealType minY = NumericTraits::max(); + RealType minZ = NumericTraits::max(); + + AccumulateType m_meanCurr_f = NumericTraits::ZeroValue(); + AccumulateType m_meanCurr_m = NumericTraits::ZeroValue(); + AccumulateType m_meanPrev_f = NumericTraits::ZeroValue(); + AccumulateType m_meanPrev_m = NumericTraits::ZeroValue(); + AccumulateType m_sPrev_f = NumericTraits::ZeroValue(); + AccumulateType m_sPrev_m = NumericTraits::ZeroValue(); + AccumulateType m_sCurr_f = NumericTraits::ZeroValue(); + AccumulateType m_sCurr_m = NumericTraits::ZeroValue(); + AccumulateType m_varianceCurr_f = NumericTraits::ZeroValue(); + AccumulateType m_varianceCurr_m = NumericTraits::ZeroValue(); + + while (!ti.IsAtEnd()) { + + indexFixed = ti.GetIndex(); + ++numberOfPixelsVisited; + + fixedImage->TransformIndexToPhysicalPoint(indexFixed, inputPoint); + + if (fixedImageMask && !fixedImageMask->IsInsideInWorldSpace(inputPoint)) { + ++ti; + continue; + } + + if (this->m_MovingImageMask && !this->m_MovingImageMask->IsInsideInWorldSpace(inputPoint)) { + ++ti; + continue; + } + + const RealType fixedValue = ti.Get(); + + if (fixedValue == -1024) { + ++ti; + continue; + } + + if (imageDRTIn->TransformPhysicalPointToIndex(inputPoint, indexMoving)) { + + double x = inputPoint[0]; + double y = inputPoint[1]; + double z = inputPoint[2]; + maxX = maxX > x ? maxX : x; + minX = minX < x ? minX : x; + maxY = maxY > y ? maxY : y; + minY = minY < y ? minY : y; + maxZ = maxZ > z ? maxZ : z; + minZ = minZ < z ? minZ : z; + + const RealType movingValue = imageDRTIn->GetPixel(indexMoving); + + if (NumericTraits::NonpositiveMin() == movingValue) { + ++ti; + continue; + } + + movingValueMin = movingValue < movingValueMin ? movingValue : movingValueMin; + movingValueMax = movingValue > movingValueMax ? movingValue : movingValueMax; + fixedValueMin = fixedValue < fixedValueMin ? fixedValue : fixedValueMin; + fixedValueMax = fixedValue > fixedValueMax ? fixedValue : fixedValueMax; + + sff += fixedValue * fixedValue; + smm += movingValue * movingValue; + sfm += fixedValue * movingValue; + if (this->m_SubtractMean) { + sf += fixedValue; + sm += movingValue; + } + this->m_NumberOfPixelsCounted++; + + if (this->m_NumberOfPixelsCounted == 1) { + m_meanCurr_f = fixedValue; + m_meanCurr_m = movingValue; + } else { + m_meanPrev_f = m_meanCurr_f; + m_meanPrev_m = m_meanCurr_m; + m_sPrev_f = m_sCurr_f; + m_sPrev_m = m_sCurr_m; + + m_meanCurr_f = m_meanPrev_f + (fixedValue - m_meanPrev_f) / this->m_NumberOfPixelsCounted; + m_sCurr_f = m_sPrev_f + (fixedValue - m_meanPrev_f) * (fixedValue - m_meanCurr_f); + m_varianceCurr_f = m_sCurr_f / (this->m_NumberOfPixelsCounted - 1); + + m_meanCurr_m = m_meanPrev_m + (movingValue - m_meanPrev_m) / this->m_NumberOfPixelsCounted; + m_sCurr_m = m_sPrev_m + (movingValue - m_meanPrev_m) * (movingValue - m_meanCurr_m); + m_varianceCurr_m = m_sCurr_m / (this->m_NumberOfPixelsCounted - 1); + } + } + + ++ti; + } + + // sfm = sfm - m_meanCurr_f * sm - m_meanCurr_m * sf + this->m_NumberOfPixelsCounted * m_meanCurr_m * m_meanCurr_f; + // const RealType denom = -1 * sqrt(m_varianceCurr_f * m_varianceCurr_m) * this->m_NumberOfPixelsCounted; + + // if (this->m_NumberOfPixelsCounted > 0 && denom != 0.0) { + // measure = sfm / denom; + // } else { + // measure = NumericTraits::ZeroValue(); + // } + + if (this->m_SubtractMean && this->m_NumberOfPixelsCounted > 0) { + sff -= (sf * sf / this->m_NumberOfPixelsCounted); + smm -= (sm * sm / this->m_NumberOfPixelsCounted); + sfm -= (sf * sm / this->m_NumberOfPixelsCounted); + } + + RealType denom = -1.0 * sqrt(sff * smm); + + if (this->m_NumberOfPixelsCounted > 0 && denom != 0.0) { + measure = sfm / denom; + } else { + measure = NumericTraits::Zero; + } + std::cout << "movingValueMin: " << movingValueMin << " movingValueMax: " << movingValueMax << std::endl; + std::cout << "fixedValueMin: " << fixedValueMin << " fixedValueMax: " << fixedValueMax << std::endl; + + std::cout << "max coordinates: " << maxX << " " << maxX << " " << maxZ << std::endl; + std::cout << "min coordinates: " << minX << " " << minY << " " << minZ << std::endl; + + return measure; +} + +template +typename NormalizedCorrelationTwoImageToOneImageMetric::MeasureType +NormalizedCorrelationTwoImageToOneImageMetric::GetValue( + const TransformParametersType& parameters) const +{ + if (!this->m_FixedImage1) { + itkExceptionMacro(<< "Fixed image1 has not been assigned"); + } + + if (!this->m_FixedImage2) { + itkExceptionMacro(<< "Fixed image2 has not been assigned"); + } + + if (!this->m_Filter1) { + itkExceptionMacro(<< "Fixed filter1 has not been assigned"); + } + + if (!this->m_Filter2) { + itkExceptionMacro(<< "Fixed filter1 has not been assigned"); + } + + if (!this->SetTransformParameters(parameters)) { + std::cout << "Measure: 0.0, transform Invalid!" << std::endl; + std::cout << "=======================================================" << std::endl; + + return 0.0; + } + return GetValue(); +} + +template +typename NormalizedCorrelationTwoImageToOneImageMetric::MeasureType +NormalizedCorrelationTwoImageToOneImageMetric::GetValue() const +{ + + if (!this->m_FixedImage1) { + itkExceptionMacro(<< "Fixed image1 has not been assigned"); + } + + if (!this->m_FixedImage2) { + itkExceptionMacro(<< "Fixed image2 has not been assigned"); + } + + if (!this->m_Filter1) { + itkExceptionMacro(<< "Fixed filter1 has not been assigned"); + } + + if (!this->m_Filter2) { + itkExceptionMacro(<< "Fixed filter1 has not been assigned"); + } + + // Calculate the measure value between fixed image 1 and the moving image + auto oldprecision = std::cout.precision(); + + MeasureType measure1 = CalculateMeasure(1); + std::cout.precision(std::numeric_limits::digits10 + 2); + std::cout << "Measure1: " << measure1 << " Counts: " << this->m_NumberOfPixelsCounted << std::endl; + std::cout.precision(oldprecision); + + MeasureType measure2 = CalculateMeasure(2); + std::cout.precision(std::numeric_limits::digits10 + 2); + std::cout << "Measure2: " << measure2 << " Counts: " << this->m_NumberOfPixelsCounted << std::endl; + + auto measure = (measure1 + measure2) / 2.0; + std::cout << "Measure: " << measure << std::endl; + std::cout << "=======================================================" << std::endl; + std::cout.precision(oldprecision); + + return measure; +} + +template +void NormalizedCorrelationTwoImageToOneImageMetric::GetDerivative( + const TransformParametersType& itkNotUsed(parameters), + DerivativeType& itkNotUsed(derivative)) const +{ + // under construction +} + +template +void NormalizedCorrelationTwoImageToOneImageMetric::GetValueAndDerivative( + const TransformParametersType& itkNotUsed(parameters), + MeasureType& itkNotUsed(value), + DerivativeType& itkNotUsed(derivative)) const +{ + // under construction +} + +template +void NormalizedCorrelationTwoImageToOneImageMetric::PrintSelf(std::ostream& os, + Indent indent) const +{ + Superclass::PrintSelf(os, indent); + os << indent << "SubtractMean: " << m_SubtractMean << std::endl; +} + +} // end namespace itk + +#endif diff --git a/reg23Topograms/itkDTRrecon/autoreg/itkTwoProjectionImageRegistrationMethod.h b/reg23Topograms/itkDTRrecon/autoreg/itkTwoProjectionImageRegistrationMethod.h new file mode 100644 index 0000000..de7a291 --- /dev/null +++ b/reg23Topograms/itkDTRrecon/autoreg/itkTwoProjectionImageRegistrationMethod.h @@ -0,0 +1,269 @@ +/*========================================================================= + * + * Copyright NumFOCUS + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0.txt + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *=========================================================================*/ +#ifndef itkTwoProjectionImageRegistrationMethod_h +#define itkTwoProjectionImageRegistrationMethod_h + +#include "itkChangeInformationImageFilter.h" +#include "itkDataObjectDecorator.h" +#include "itkImage.h" +#include "itkMacro.h" +#include "itkProcessObject.h" +#include "itkSingleValuedNonLinearOptimizer.h" +#include "itkgTwoImageToOneImageMetric.h" +#include + +namespace itk { + +/** \class TwoProjectionImageRegistrationMethod + * \brief Base class for Image Registration Methods + * + * This Class define the generic interface for a registration method. + * + * This class is templated over the type of the two image to be + * registered. A generic Transform is used by this class. That allows + * to select at run time the particular type of transformation that + * is to be applied for registering the images. + * + * This method use a generic Metric in order to compare the two images. + * the final goal of the registration method is to find the set of + * parameters of the Transformation that optimizes the metric. + * + * The registration method also support a generic optimizer that can + * be selected at run-time. The only restriction for the optimizer is + * that it should be able to operate in single-valued cost functions + * given that the metrics used to compare images provide a single + * value as output. + * + * The terms : Fixed image and Moving image are used in this class + * to indicate what image is being mapped by the transform. + * + * This class uses the coordinate system of the Fixed image as a reference + * and searchs for a Transform that will map points from the space of the + * Fixed image to the space of the Moving image. + * + * For doing so, a Metric will be continously applied to compare the Fixed + * image with the Transformed Moving image. This process also requires to + * interpolate values from the Moving image. + * + * \ingroup RegistrationFilters + * \ingroup TwoProjectionRegistration + */ +template +class TwoProjectionImageRegistrationMethod : public ProcessObject { +public: + ITK_DISALLOW_COPY_AND_ASSIGN(TwoProjectionImageRegistrationMethod); + + /** Standard class type alias. */ + using Self = TwoProjectionImageRegistrationMethod; + using Superclass = ProcessObject; + using Pointer = SmartPointer; + using ConstPointer = SmartPointer; + + /** Method for creation through the object factory. */ + itkNewMacro(Self); + + /** Run-time type information (and related methods). */ + itkTypeMacro(TwoProjectionImageRegistrationMethod, ProcessObject); + + /** Type of the Fixed image. */ + using FixedImageType = TFixedImage; + using FixedImageConstPointer = typename FixedImageType::ConstPointer; + + /** Type of the Moving image. */ + using MovingImageType = TMovingImage; + using MovingImageConstPointer = typename MovingImageType::ConstPointer; + using ChangeInformationFilterType = ChangeInformationImageFilter; + using ChangeInformationFilterPointer = typename ChangeInformationFilterType::Pointer; + + /** Type of the metric. */ + using MetricType = gTwoImageToOneImageMetric; + using MetricPointer = typename MetricType::Pointer; + using FixedImageRegionType = typename MetricType::FixedImageRegionType; + + /** Type of the Transform . */ + using TransformType = typename MetricType::TransformType; + using TransformPointer = typename TransformType::Pointer; + + /** Type for the output: Using Decorator pattern for enabling + * the Transform to be passed in the data pipeline */ + using TransformOutputType = DataObjectDecorator; + using TransformOutputPointer = typename TransformOutputType::Pointer; + using TransformOutputConstPointer = typename TransformOutputType::ConstPointer; + + /** Type of the Interpolator. */ + using InterpolatorType = typename MetricType::InterpolatorType; + using InterpolatorPointer = typename InterpolatorType::Pointer; + + /** Type of the optimizer. */ + using OptimizerType = SingleValuedNonLinearOptimizer; + + /** Type of the Transformation parameters This is the same type used to + * represent the search space of the optimization algorithm */ + using ParametersType = typename MetricType::TransformParametersType; + + /** Smart Pointer type to a DataObject. */ + using DataObjectPointer = typename DataObject::Pointer; + + /** Method that initiates the registration. This will Initialize and ensure + * that all inputs the registration needs are in place, via a call to + * Initialize() will then start the optimization process via a call to + * StartOptimization() */ + void + StartRegistration(); + + /** Method that initiates the optimization process. */ + void + StartOptimization(); + + /** Set/Get the Fixed images. */ + void + SetFixedImage1(const FixedImageType* fixedImage1); + void + SetFixedImage2(const FixedImageType* fixedImage2); + itkGetConstObjectMacro(FixedImage1, FixedImageType); + itkGetConstObjectMacro(FixedImage2, FixedImageType); + + /** Set/Get the Moving image. */ + void + SetMovingImage(const MovingImageType* movingImage); + itkGetConstObjectMacro(MovingImage, MovingImageType); + + /** Set/Get the Optimizer. */ + itkSetObjectMacro(Optimizer, OptimizerType); + itkGetConstObjectMacro(Optimizer, OptimizerType); + + /** Set/Get the Metric. */ + itkSetObjectMacro(Metric, MetricType); + itkGetConstObjectMacro(Metric, MetricType); + + /** Set/Get the Transfrom1. */ + itkSetObjectMacro(Transform1, TransformType); + itkGetConstObjectMacro(Transform1, TransformType); + + /** Set/Get the Transfrom2. */ + itkSetObjectMacro(Transform2, TransformType); + itkGetConstObjectMacro(Transform2, TransformType); + + /** Set/Get the Interpolators. */ + itkSetObjectMacro(Interpolator1, InterpolatorType); + itkSetObjectMacro(Interpolator2, InterpolatorType); + itkGetConstObjectMacro(Interpolator1, InterpolatorType); + itkGetConstObjectMacro(Interpolator2, InterpolatorType); + + /** Set/Get the Meta informations. */ + itkSetObjectMacro(TransformMetaInfo, TransformMetaInformation); + itkGetConstObjectMacro(TransformMetaInfo, TransformMetaInformation); + + /** Set/Get the output filters. */ + itkSetObjectMacro(Filter1, ChangeInformationFilterType); + itkGetConstObjectMacro(Filter1, ChangeInformationFilterType); + itkSetObjectMacro(Filter2, ChangeInformationFilterType); + itkGetConstObjectMacro(Filter2, ChangeInformationFilterType); + + /** Set the region of the fixed image to be considered as region of + interest during the registration. This region will be passed to + the ImageMetric in order to restrict the metric computation to + consider only this region. + \warning The same region can also be set directly into the metric. + please avoid to set the region in both places since this can lead + to inconsistent configurations. */ + void + SetFixedImageRegion1(const FixedImageRegionType& region1); + void + SetFixedImageRegion2(const FixedImageRegionType& region2); + /** Get the region of the fixed image to be considered as region of + interest during the registration. This region will be passed to + the ImageMetric in order to restrict the metric computation to + consider only this region. */ + itkGetConstReferenceMacro(FixedImageRegion1, FixedImageRegionType); + itkGetConstReferenceMacro(FixedImageRegion2, FixedImageRegionType); + /** True if a region has been defined for the fixed image to which + the ImageMetric will limit its computation */ + itkGetMacro(FixedImageRegionDefined1, bool); + itkGetMacro(FixedImageRegionDefined2, bool); + /** Turn on/off the use of a fixed image region to which + the ImageMetric will limit its computation. + \warning The region must have been previously defined using the + SetFixedImageRegion member function */ + itkSetMacro(FixedImageRegionDefined1, bool); + itkSetMacro(FixedImageRegionDefined2, bool); + + /** Initialize by setting the interconnects between the components. */ + virtual void + Initialize(); + + /** Returns the transform resulting from the registration process */ + const TransformOutputType* + GetOutput() const; + + /** Make a DataObject of the correct type to be used as the specified + * output. */ + using Superclass::MakeOutput; + DataObjectPointer + MakeOutput(DataObjectPointerArraySizeType idx) override; + +protected: + TwoProjectionImageRegistrationMethod(); + ~TwoProjectionImageRegistrationMethod() override = default; + void + PrintSelf(std::ostream& os, Indent indent) const override; + + /** Method invoked by the pipeline in order to trigger the computation of + * the registration. */ + void + GenerateData() override; + + /** Provides derived classes with the ability to set this private var */ + itkSetMacro(LastOptimizerParameters, ParametersType); + +private: + MetricPointer m_Metric; + OptimizerType::Pointer m_Optimizer; + + MovingImageConstPointer m_MovingImage; + FixedImageConstPointer m_FixedImage1; + FixedImageConstPointer m_FixedImage2; + + TransformPointer m_Transform1; + TransformPointer m_Transform2; + InterpolatorPointer m_Interpolator1; + InterpolatorPointer m_Interpolator2; + + TransformMetaInformation::Pointer + m_TransformMetaInfo; + + ChangeInformationFilterPointer + m_Filter1, + m_Filter2; + + ParametersType m_InitialOptimizerParameters; + ParametersType m_LastOptimizerParameters; + + bool m_FixedImageRegionDefined1; + bool m_FixedImageRegionDefined2; + FixedImageRegionType m_FixedImageRegion1; + FixedImageRegionType m_FixedImageRegion2; +}; + +} // end namespace itk + +#ifndef ITK_MANUAL_INSTANTIATION +#include "itkTwoProjectionImageRegistrationMethod.hxx" +#endif + +#endif diff --git a/reg23Topograms/itkDTRrecon/autoreg/itkTwoProjectionImageRegistrationMethod.hxx b/reg23Topograms/itkDTRrecon/autoreg/itkTwoProjectionImageRegistrationMethod.hxx new file mode 100644 index 0000000..fa77cd7 --- /dev/null +++ b/reg23Topograms/itkDTRrecon/autoreg/itkTwoProjectionImageRegistrationMethod.hxx @@ -0,0 +1,327 @@ +/*========================================================================= + * + * Copyright NumFOCUS + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0.txt + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *=========================================================================*/ +#ifndef itkTwoProjectionImageRegistrationMethod_hxx +#define itkTwoProjectionImageRegistrationMethod_hxx + +#include "itkTwoProjectionImageRegistrationMethod.h" + +namespace itk { + +// TwoProjectionImageRegistrationMethod from Jian Wu. +// This part is not really needed and functionality should be moved to +// to the itkImageProcessor.cpp. This is just abstraction with an additional step. + +template +TwoProjectionImageRegistrationMethod::TwoProjectionImageRegistrationMethod() +{ + this->SetNumberOfRequiredOutputs(1); // for the Transform + + m_FixedImage1 = nullptr; // has to be provided by the user. + m_FixedImage2 = nullptr; // has to be provided by the user. + m_MovingImage = nullptr; // has to be provided by the user. + m_Transform1 = nullptr; // has to be provided by the user. + m_Transform2 = nullptr; // has to be provided by the user. + m_TransformMetaInfo = nullptr; // has to be provided by the user. + m_Interpolator1 = nullptr; // has to be provided by the user. + m_Interpolator2 = nullptr; // has to be provided by the user. + m_Metric = nullptr; // has to be provided by the user. + m_Optimizer = nullptr; // has to be provided by the user. + + m_InitialOptimizerParameters = ParametersType(1); + m_LastOptimizerParameters = ParametersType(1); + + m_InitialOptimizerParameters.Fill(0.0f); + m_LastOptimizerParameters.Fill(0.0f); + + m_FixedImageRegionDefined1 = false; + m_FixedImageRegionDefined2 = false; + + TransformOutputPointer transformDecorator = static_cast(this->MakeOutput(0).GetPointer()); + + this->ProcessObject::SetNthOutput(0, transformDecorator.GetPointer()); +} + +/* + * Set the region of the fixed image 1 to be considered for registration + */ +template +void TwoProjectionImageRegistrationMethod::SetFixedImageRegion1( + const FixedImageRegionType& region1) +{ + m_FixedImageRegion1 = region1; + m_FixedImageRegionDefined1 = true; +} + +/* + * Set the region of the fixed image 2 to be considered for registration + */ +template +void TwoProjectionImageRegistrationMethod::SetFixedImageRegion2( + const FixedImageRegionType& region2) +{ + m_FixedImageRegion2 = region2; + m_FixedImageRegionDefined2 = true; +} + +/* + * Initialize by setting the interconnects between components. + */ +template +void TwoProjectionImageRegistrationMethod::Initialize() +{ + + if (!m_FixedImage1) { + itkExceptionMacro(<< "FixedImage1 is not present"); + } + + if (!m_FixedImage2) { + itkExceptionMacro(<< "FixedImage2 is not present"); + } + + if (!m_MovingImage) { + itkExceptionMacro(<< "MovingImage is not present"); + } + + if (!m_Metric) { + itkExceptionMacro(<< "Metric is not present"); + } + + if (!m_Optimizer) { + itkExceptionMacro(<< "Optimizer is not present"); + } + + if (!m_Transform1) { + itkExceptionMacro(<< "Transform1 is not present"); + } + + if (!m_Transform2) { + itkExceptionMacro(<< "Transform2 is not present"); + } + + // + // Connect the transform to the Decorator. + auto* transformOutput = static_cast(this->ProcessObject::GetOutput(0)); + + transformOutput->Set(m_Transform1.GetPointer()); + + if (!m_Interpolator1) { + itkExceptionMacro(<< "Interpolator1 is not present"); + } + + if (!m_Interpolator2) { + itkExceptionMacro(<< "Interpolator2 is not present"); + } + + if (!m_Filter1) { + itkExceptionMacro(<< "Filter1 is not present"); + } + + if (!m_Filter1) { + itkExceptionMacro(<< "Filter2 is not present"); + } + + if (!m_TransformMetaInfo) { + itkExceptionMacro(<< "TransformMetaInfo is not present"); + } + + // Setup the metric + m_Metric->SetMovingImage(m_MovingImage); + m_Metric->SetFixedImage1(m_FixedImage1); + m_Metric->SetFixedImage2(m_FixedImage2); + m_Metric->SetTransform1(m_Transform1); + m_Metric->SetTransform2(m_Transform2); + m_Metric->SetTransformMetaInfo(m_TransformMetaInfo); + m_Metric->SetFilter1(m_Filter1); + m_Metric->SetFilter2(m_Filter2); + + m_Metric->SetInterpolator1(m_Interpolator1); + m_Metric->SetInterpolator2(m_Interpolator2); + + if (m_FixedImageRegionDefined1) { + m_Metric->SetFixedImageRegion1(m_FixedImageRegion1); + } else { + m_Metric->SetFixedImageRegion1(m_FixedImage1->GetBufferedRegion()); + } + + if (m_FixedImageRegionDefined2) { + m_Metric->SetFixedImageRegion2(m_FixedImageRegion2); + } else { + m_Metric->SetFixedImageRegion2(m_FixedImage2->GetBufferedRegion()); + } + + m_Metric->Initialize(); + + // Setup the optimizer + m_Optimizer->SetScales(m_Metric->GetWeightings()); + m_Optimizer->SetCostFunction(m_Metric); + + m_InitialOptimizerParameters = m_Metric->GetParameters(); + + m_Optimizer->SetInitialPosition(m_InitialOptimizerParameters); +} + +/* + * Starts the Registration Process + */ +template +void TwoProjectionImageRegistrationMethod::StartRegistration() +{ + + ParametersType empty(1); + empty.Fill(0.0); + try { + // initialize the interconnects between components + this->Initialize(); + if (GetDebug()) { + m_Metric->Print(std::cout); + m_Optimizer->Print(std::cout); + this->Print(std::cout); + } + } catch (ExceptionObject& err) { + m_LastOptimizerParameters = empty; + + // pass exception to caller + throw err; + } + + this->StartOptimization(); +} + +/* + * Starts the Optimization process + */ +template +void TwoProjectionImageRegistrationMethod::StartOptimization() +{ + try { + // do the optimization + m_Optimizer->StartOptimization(); + + } catch (ExceptionObject& err) { + // An error has occurred in the optimization. + // Update the parameters + m_LastOptimizerParameters = m_Optimizer->GetCurrentPosition(); + + // Pass exception to caller + throw err; + } + + // get the results + m_LastOptimizerParameters = m_Optimizer->GetCurrentPosition(); + + //Update transform1 and transform2 with the last transform parameters from the optimizer. + m_Metric->SetTransformParameters(m_LastOptimizerParameters); +} + +template +void TwoProjectionImageRegistrationMethod::PrintSelf(std::ostream& os, Indent indent) const +{ + Superclass::PrintSelf(os, indent); + os << indent << "Metric: " << m_Metric.GetPointer() << std::endl; + os << indent << "Optimizer: " << m_Optimizer.GetPointer() << std::endl; + os << indent << "Transform1: " << m_Transform1.GetPointer() << std::endl; + os << indent << "Transform2: " << m_Transform2.GetPointer() << std::endl; + os << indent << "Interpolator 1: " << m_Interpolator1.GetPointer() << std::endl; + os << indent << "Interpolator 2: " << m_Interpolator2.GetPointer() << std::endl; + os << indent << "Fixed Image 1: " << m_FixedImage1.GetPointer() << std::endl; + os << indent << "Fixed Image 2: " << m_FixedImage2.GetPointer() << std::endl; + os << indent << "Moving Image: " << m_MovingImage.GetPointer() << std::endl; + os << indent << "Transform MetaInfo: " << m_TransformMetaInfo.GetPointer() << std::endl; + os << indent << "Fixed Image 1 Region Defined: " << m_FixedImageRegionDefined1 << std::endl; + os << indent << "Fixed Image 2 Region Defined: " << m_FixedImageRegionDefined2 << std::endl; + os << indent << "Fixed Image 1 Region: " << m_FixedImageRegion1 << std::endl; + os << indent << "Fixed Image 2 Region: " << m_FixedImageRegion2 << std::endl; + os << indent << "Initial Optimizer Parameters: " << m_InitialOptimizerParameters << std::endl; + os << indent << "Last Optimizer Parameters: " << m_LastOptimizerParameters << std::endl; +} + +template +void TwoProjectionImageRegistrationMethod::GenerateData() +{ + this->StartRegistration(); +} + +template +const typename TwoProjectionImageRegistrationMethod::TransformOutputType* +TwoProjectionImageRegistrationMethod::GetOutput() const +{ + return static_cast(this->ProcessObject::GetOutput(0)); +} + +template +DataObject::Pointer +TwoProjectionImageRegistrationMethod::MakeOutput(DataObjectPointerArraySizeType output) +{ + switch (output) { + case 0: + return static_cast(TransformOutputType::New().GetPointer()); + break; + default: + itkExceptionMacro("MakeOutput request for an output number larger than the expected number of outputs"); + return nullptr; + } +} + +template +void TwoProjectionImageRegistrationMethod::SetFixedImage1(const FixedImageType* fixedImage1) +{ + itkDebugMacro("setting Fixed Image 1 to " << fixedImage1); + + if (this->m_FixedImage1.GetPointer() != fixedImage1) { + this->m_FixedImage1 = fixedImage1; + + // Process object is not const-correct so the const_cast is required here + this->ProcessObject::SetNthInput(0, const_cast(fixedImage1)); + + this->Modified(); + } +} + +template +void TwoProjectionImageRegistrationMethod::SetFixedImage2(const FixedImageType* fixedImage2) +{ + itkDebugMacro("setting Fixed Image 2 to " << fixedImage2); + + if (this->m_FixedImage2.GetPointer() != fixedImage2) { + this->m_FixedImage2 = fixedImage2; + + // Process object is not const-correct so the const_cast is required here + this->ProcessObject::SetNthInput(0, const_cast(fixedImage2)); + + this->Modified(); + } +} + +template +void TwoProjectionImageRegistrationMethod::SetMovingImage(const MovingImageType* movingImage) +{ + itkDebugMacro("setting Moving Image to " << movingImage); + + if (this->m_MovingImage.GetPointer() != movingImage) { + this->m_MovingImage = movingImage; + + // Process object is not const-correct so the const_cast is required here + this->ProcessObject::SetNthInput(1, const_cast(movingImage)); + + this->Modified(); + } +} + +} // end namespace itk + +#endif diff --git a/reg23Topograms/itkDTRrecon/autoreg/itkgTwoImageToOneImageMetric.h b/reg23Topograms/itkDTRrecon/autoreg/itkgTwoImageToOneImageMetric.h new file mode 100644 index 0000000..9cb93cb --- /dev/null +++ b/reg23Topograms/itkDTRrecon/autoreg/itkgTwoImageToOneImageMetric.h @@ -0,0 +1,300 @@ +/*========================================================================= + * + * Copyright NumFOCUS + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0.txt + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *=========================================================================*/ +#ifndef itkgTwoImageToOneImageMetric_h +#define itkgTwoImageToOneImageMetric_h + +#include "DRTMetaInformation.h" +#include "itkChangeInformationImageFilter.h" +#include "itkDRTHelpers.h" +#include "itkGradientRecursiveGaussianImageFilter.h" +#include "itkImageBase.h" +#include "itkInterpolateImageFunction.h" +#include "itkOptimizer.h" +#include "itkResampleImageFilter.h" +#include "itkSingleValuedCostFunction.h" +#include "itkSpatialObject.h" +#include "itkTransform.h" +#include "itkgSiddonJacobsRayCastInterpolateImageFunction.h" + +#include "itkImageFileWriter.h" +#include "itkRescaleIntensityImageFilter.h" + +#include +#include +#include +#include +#include + +namespace itk { + +/** \class gTwoImageToOneImageMetric + * \brief Computes similarity between two fixed images and one fixed image. + * + * This Class is templated over the type of the two input images. + * It expects a Transform and two Interpolators to be plugged in. + * This particular class is the base class for a hierarchy of + * similarity metrics. + * + * This class computes a value that measures the similarity + * between two Fixed image and the transformed Moving images. + * The Interpolators are used to compute intensity values on + * non-grid positions resulting from mapping points through + * the Transform. + * + * + * \ingroup RegistrationMetrics + * \ingroup TwoProjectionRegistration + * + */ + +template +class gTwoImageToOneImageMetric : public SingleValuedCostFunction { +public: + ITK_DISALLOW_COPY_AND_ASSIGN(gTwoImageToOneImageMetric); + + /** Standard class type alias. */ + using Self = gTwoImageToOneImageMetric; + using Superclass = SingleValuedCostFunction; + using Pointer = SmartPointer; + using ConstPointer = SmartPointer; + + /** Type used for representing point components */ + using CoordinateRepresentationType = Superclass::ParametersValueType; + + /** Run-time type information (and related methods). */ + itkTypeMacro(gTwoImageToOneImageMetric, SingleValuedCostFunction); + + /** Type of the moving Image. */ + using MovingImageType = TMovingImage; + using MovingImagePixelType = typename TMovingImage::PixelType; + using MovingImageConstPointer = typename MovingImageType::ConstPointer; + + /** Type of the fixed Image. */ + using FixedImageType = TFixedImage; + using FixedImageConstPointer = typename FixedImageType::ConstPointer; + using FixedImageRegionType = typename FixedImageType::RegionType; + + /** Constants for the image dimensions */ + static constexpr unsigned int MovingImageDimension = TMovingImage::ImageDimension; + static constexpr unsigned int FixedImageDimension = TFixedImage::ImageDimension; + + /** Type of the Transform Base class */ + using TransformType = itk::Euler3DTransform; + + using TransformPointer = typename TransformType::Pointer; + using InputPointType = typename TransformType::InputPointType; + using OutputPointType = typename TransformType::OutputPointType; + using TransformParametersType = typename TransformType::ParametersType; + using TransformJacobianType = typename TransformType::JacobianType; + + /** Type of the Interpolator Base class */ + using InterpolatorType = gSiddonJacobsRayCastInterpolateImageFunction; + + /** Gaussian filter to compute the gradient of the Moving Image */ + using RealType = typename NumericTraits::RealType; + using GradientPixelType = CovariantVector; + using GradientImageType = Image; + using GradientImagePointer = SmartPointer; + using GradientImageFilterType = GradientRecursiveGaussianImageFilter; + using GradientImageFilterPointer = typename GradientImageFilterType::Pointer; + using InterpolatorPointer = typename InterpolatorType::Pointer; + + using ResampleImageFilterType = ResampleImageFilter; + using ResampleImageFilterPointer = typename ResampleImageFilterType::Pointer; + using ChangeInformationFilterType = ChangeInformationImageFilter; + using ChangeInformationFilterPointer = typename ChangeInformationFilterType::Pointer; + + /** Type for the mask of the fixed image. Only pixels that are "inside" + this mask will be considered for the computation of the metric */ + typedef SpatialObject FixedImageMaskType; + using FixedImageMaskPointer = typename FixedImageMaskType::Pointer; + + /** Type for the mask of the moving image. Only pixels that are "inside" + this mask will be considered for the computation of the metric */ + typedef SpatialObject MovingImageMaskType; + using MovingImageMaskPointer = typename MovingImageMaskType::Pointer; + + /** Type of the measure. */ + using MeasureType = Superclass::MeasureType; + + /** Type of the derivative. */ + using DerivativeType = Superclass::DerivativeType; + + /** Type of the Transformation parameters This is the same type used to + * represent the search space of the optimization algorithm */ + using ParametersType = Superclass::ParametersType; + + /** Connect the Fixed Image. */ + itkSetConstObjectMacro(FixedImage1, FixedImageType); + + /** Connect the Fixed Image. */ + itkSetConstObjectMacro(FixedImage2, FixedImageType); + + /** Get the Fixed Image. */ + itkGetConstObjectMacro(FixedImage1, FixedImageType); + + /** Get the Fixed Image. */ + itkGetConstObjectMacro(FixedImage2, FixedImageType); + + /** Connect the Moving Image. */ + itkSetConstObjectMacro(MovingImage, MovingImageType); + + /** Get the Moving Image. */ + itkGetConstObjectMacro(MovingImage, MovingImageType); + + /** Connect the Transform1. */ + itkSetObjectMacro(Transform1, TransformType); + + /** Get a pointer to the Transform1. */ + itkGetConstObjectMacro(Transform1, TransformType); + + /** Connect the Transform2. */ + itkSetObjectMacro(Transform2, TransformType); + + /** Get a pointer to the Transform2. */ + itkGetConstObjectMacro(Transform2, TransformType); + + /** Connect the Interpolator. */ + itkSetObjectMacro(Interpolator1, InterpolatorType); + + /** Get a pointer to the Interpolator. */ + itkGetConstObjectMacro(Interpolator1, InterpolatorType); + + /** Connect the Interpolator. */ + itkSetObjectMacro(Interpolator2, InterpolatorType); + + /** Get a pointer to the Interpolator. */ + itkGetConstObjectMacro(Interpolator2, InterpolatorType); + + /** Get the number of pixels considered in the computation. */ + itkGetConstReferenceMacro(NumberOfPixelsCounted, unsigned long); + + /** Connect the DRTGeometryMetaInfo. */ + itkSetObjectMacro(TransformMetaInfo, TransformMetaInformation); + + /** Get a pointer to the DRTGeometryMetaInfo. */ + itkGetConstObjectMacro(TransformMetaInfo, TransformMetaInformation); + + /** Set the region over which the metric will be computed */ + itkSetMacro(FixedImageRegion1, FixedImageRegionType); + + /** Set the region over which the metric will be computed */ + itkSetMacro(FixedImageRegion2, FixedImageRegionType); + + /** Get the region over which the metric will be computed */ + itkGetConstReferenceMacro(FixedImageRegion1, FixedImageRegionType); + + /** Get the region over which the metric will be computed */ + itkGetConstReferenceMacro(FixedImageRegion2, FixedImageRegionType); + + /** Set/Get the output filters. */ + itkSetObjectMacro(Filter1, ChangeInformationFilterType); + itkGetConstObjectMacro(Filter1, ChangeInformationFilterType); + itkSetObjectMacro(Filter2, ChangeInformationFilterType); + itkGetConstObjectMacro(Filter2, ChangeInformationFilterType); + + /** Set/Get the moving image mask. */ + itkSetObjectMacro(MovingImageMask, MovingImageMaskType); + itkGetConstObjectMacro(MovingImageMask, MovingImageMaskType); + + /** Set/Get the fixed image mask. */ + itkSetObjectMacro(FixedImageMask1, FixedImageMaskType); + itkSetObjectMacro(FixedImageMask2, FixedImageMaskType); + itkGetConstObjectMacro(FixedImageMask1, FixedImageMaskType); + itkGetConstObjectMacro(FixedImageMask2, FixedImageMaskType); + + /** Set/Get gradient computation. */ + itkSetMacro(ComputeGradient, bool); + itkGetConstReferenceMacro(ComputeGradient, bool); + itkBooleanMacro(ComputeGradient); + + itkSetMacro(MaxTranslation, double); + itkGetConstReferenceMacro(MaxTranslation, double); + + /** Get Gradient Image. */ + itkGetConstObjectMacro(GradientImage, GradientImageType); + + /** Set the parameters defining the Transform. */ + bool + SetTransformParameters(const ParametersType& parameters) const; + + /** Return the number of parameters required by the Transform */ + + unsigned int GetNumberOfParameters() const; + itk::Optimizer::ScalesType GetWeightings() const; + ParametersType GetParameters() const; + + /** Initialize the Metric by making sure that all the components + * are present and plugged together correctly */ + virtual void + Initialize(); + +protected: + gTwoImageToOneImageMetric(); + ~gTwoImageToOneImageMetric() override = default; + void + PrintSelf(std::ostream& os, Indent indent) const override; + + constexpr static unsigned int Dimension = 3; + + mutable unsigned long m_NumberOfPixelsCounted; + mutable double m_bestMeassure; + + FixedImageConstPointer m_FixedImage1; + FixedImageConstPointer m_FixedImage2; + MovingImageConstPointer m_MovingImage; + + mutable TransformPointer m_Transform1; + mutable TransformPointer m_Transform2; + InterpolatorPointer m_Interpolator1; + InterpolatorPointer m_Interpolator2; + + bool m_ComputeGradient; + GradientImagePointer m_GradientImage; + + using OutputPixelType = unsigned char; + using OutputImageType = itk::Image; + + mutable FixedImageMaskPointer m_FixedImageMask1; + mutable FixedImageMaskPointer m_FixedImageMask2; + mutable MovingImageMaskPointer m_MovingImageMask; + + TransformMetaInformation::Pointer + m_TransformMetaInfo; + + ChangeInformationFilterPointer + m_Filter1, + m_Filter2; + + double m_MaxTranslation; + + /* Writes the image to the disk. If path is empty it will be saved to /img/out/*/ + void WriteImage(MovingImageConstPointer img, std::string fileName, std::string path) const; + +private: + FixedImageRegionType m_FixedImageRegion1; + FixedImageRegionType m_FixedImageRegion2; +}; + +} // end namespace itk + +#ifndef ITK_MANUAL_INSTANTIATION +#include "itkgTwoImageToOneImageMetric.hxx" +#endif + +#endif diff --git a/reg23Topograms/itkDTRrecon/autoreg/itkgTwoImageToOneImageMetric.hxx b/reg23Topograms/itkDTRrecon/autoreg/itkgTwoImageToOneImageMetric.hxx new file mode 100644 index 0000000..0e9c600 --- /dev/null +++ b/reg23Topograms/itkDTRrecon/autoreg/itkgTwoImageToOneImageMetric.hxx @@ -0,0 +1,395 @@ +/*========================================================================= + * + * Copyright NumFOCUS + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0.txt + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *=========================================================================*/ +#ifndef itkgTwoImageToOneImageMetric_hxx +#define itkgTwoImageToOneImageMetric_hxx + +#include "itkgTwoImageToOneImageMetric.h" +#include + +namespace itk { + +template +gTwoImageToOneImageMetric::gTwoImageToOneImageMetric() +{ + m_FixedImage1 = nullptr; // has to be provided by the user. + m_FixedImage2 = nullptr; // has to be provided by the user. + m_MovingImage = nullptr; // has to be provided by the user. + m_Transform1 = nullptr; // has to be provided by the user. + m_Transform2 = nullptr; // has to be provided by the user. + m_TransformMetaInfo = nullptr; // has to be provided by the user. + m_Interpolator1 = nullptr; // has to be provided by the user. + m_Interpolator2 = nullptr; // has to be provided by the user. + m_GradientImage = nullptr; // will receive the output of the filter; + m_ComputeGradient = true; // metric computes gradient by default + m_NumberOfPixelsCounted = 0; // initialize to zero + m_bestMeassure = std::numeric_limits::max(); + m_MaxTranslation = std::numeric_limits::max(); +} + +/* + * Set the parameters that define a unique transform + */ +template +bool gTwoImageToOneImageMetric::SetTransformParameters(const ParametersType& parameters) const +{ + + if (!m_Transform1) { + itkExceptionMacro(<< "Transform 1 has not been assigned"); + } + if (!m_Transform2) { + itkExceptionMacro(<< "Transform 2 has not been assigned"); + } + + auto transformParameters = m_Transform1->GetParameters(); + double TranslationAlongX = transformParameters[3]; + double TranslationAlongY = transformParameters[4]; + double TranslationAlongZ = transformParameters[5]; + double RotationAlongX = transformParameters[0]; + double RotationAlongY = transformParameters[1]; + double RotationAlongZ = transformParameters[2]; + + switch (m_TransformMetaInfo->GetDegreeOfFreedom()) { + case X_ONLY: + TranslationAlongX = parameters[0]; + break; + case Y_ONLY: + TranslationAlongY = parameters[0]; + break; + case Z_ONLY: + TranslationAlongZ = parameters[0]; + break; + case THREE_DOF: + TranslationAlongX = parameters[0]; + TranslationAlongY = parameters[1]; + TranslationAlongZ = parameters[2]; + break; + case ROTATION_ONLY: + RotationAlongX = parameters[0]; + RotationAlongY = parameters[1]; + RotationAlongZ = parameters[2]; + break; + case SIX_DOF: + TranslationAlongX = parameters[0]; + TranslationAlongY = parameters[1]; + TranslationAlongZ = parameters[2]; + RotationAlongX = parameters[3]; + RotationAlongY = parameters[4]; + RotationAlongZ = parameters[5]; + break; + + default: + itkExceptionMacro(<< "Unsupported degree of freedeom"); + break; + } + + std::cout << "New Transform Parameters = " << std::endl; + std::cout << " Translation X = " << TranslationAlongX << " mm" << std::endl; + std::cout << " Translation Y = " << TranslationAlongY << " mm" << std::endl; + std::cout << " Translation Z = " << TranslationAlongZ << " mm" << std::endl; + std::cout << " Rotation Along X = " << RotationAlongX / dtr << " deg" << std::endl; + std::cout << " Rotation Along Y = " << RotationAlongY / dtr << " deg" << std::endl; + std::cout << " Rotation Along Z = " << RotationAlongZ / dtr << " deg" << std::endl; + std::cout << "+++++++++++++++++++++++++++++++++++++++++++++++++++++++" << std::endl; + + transformParameters[0] = RotationAlongX; + transformParameters[1] = RotationAlongY; + transformParameters[2] = RotationAlongZ; + transformParameters[3] = TranslationAlongX; + transformParameters[4] = TranslationAlongY; + transformParameters[5] = TranslationAlongZ; + + bool transformValid = (std::abs(TranslationAlongX) < m_MaxTranslation) && (std::abs(TranslationAlongY) < m_MaxTranslation) && (std::abs(TranslationAlongZ) < m_MaxTranslation); + + if (transformValid) { + m_Transform1->SetParameters(transformParameters); + m_Transform2->SetParameters(transformParameters); + } else { + std::cout << " Transform invalid, out of range!" << std::endl; + std::cout << "+++++++++++++++++++++++++++++++++++++++++++++++++++++++" << std::endl; + } + return transformValid; +} + +template +void gTwoImageToOneImageMetric::Initialize() +{ + + if (!m_Transform1) { + itkExceptionMacro(<< "Transform is not present"); + } + + if (!m_Transform1) { + itkExceptionMacro(<< "Transform is not present"); + } + + if (!m_Transform2) { + itkExceptionMacro(<< "Transform is not present"); + } + + if (!m_Interpolator1) { + itkExceptionMacro(<< "Interpolator1 is not present"); + } + if (!m_Interpolator2) { + itkExceptionMacro(<< "Interpolator2 is not present"); + } + + if (!m_FixedImage1) { + itkExceptionMacro(<< "FixedImage1 is not present"); + } + + if (!m_FixedImage2) { + itkExceptionMacro(<< "FixedImage2 is not present"); + } + + if (m_FixedImageRegion1.GetNumberOfPixels() == 0) { + itkExceptionMacro(<< "FixedImageRegion1 is empty"); + } + + if (m_FixedImageRegion2.GetNumberOfPixels() == 0) { + itkExceptionMacro(<< "FixedImageRegion2 is empty"); + } + + // If the image is provided by a source, update the source. + if (m_MovingImage->GetSource()) { + m_MovingImage->GetSource()->Update(); + } + + // If the image is provided by a source, update the source. + if (m_FixedImage1->GetSource()) { + m_FixedImage1->GetSource()->Update(); + } + + if (m_FixedImage2->GetSource()) { + m_FixedImage2->GetSource()->Update(); + } + + // Make sure the FixedImageRegion is within the FixedImage buffered region + if (!m_FixedImageRegion1.Crop(m_FixedImage1->GetBufferedRegion())) { + itkExceptionMacro(<< "FixedImageRegion1 does not overlap the fixed image buffered region"); + } + + if (!m_FixedImageRegion2.Crop(m_FixedImage2->GetBufferedRegion())) { + itkExceptionMacro(<< "FixedImageRegion2 does not overlap the fixed image buffered region"); + } + + this->SetTransformParameters(this->GetParameters()); + + if (m_ComputeGradient) { + + GradientImageFilterPointer gradientFilter = GradientImageFilterType::New(); + + gradientFilter->SetInput(m_MovingImage); + + const typename MovingImageType::SpacingType& spacing = m_MovingImage->GetSpacing(); + double maximumSpacing = 0.0; + for (unsigned int i = 0; i < MovingImageDimension; i++) { + if (spacing[i] > maximumSpacing) { + maximumSpacing = spacing[i]; + } + } + gradientFilter->SetSigma(maximumSpacing); + gradientFilter->SetNormalizeAcrossScale(true); + + gradientFilter->Update(); + + m_GradientImage = gradientFilter->GetOutput(); + } + + // If there are any observers on the metric, call them to give the + // user code a chance to set parameters on the metric + this->InvokeEvent(InitializeEvent()); +} + +template +unsigned int gTwoImageToOneImageMetric::GetNumberOfParameters() const +{ + if (!m_TransformMetaInfo) { + itkExceptionMacro(<< "TransformMetaInfo is missing"); + } + + switch (m_TransformMetaInfo->GetDegreeOfFreedom()) { + case X_ONLY: + case Y_ONLY: + case Z_ONLY: + return 1; + case THREE_DOF: + case ROTATION_ONLY: + return 3; + case SIX_DOF: + return 6; + default: + itkExceptionMacro(<< "Unsupported degree of freedeom"); + break; + } + + return m_Transform1->GetNumberOfParameters(); +} + +template +itk::Optimizer::ScalesType gTwoImageToOneImageMetric::GetWeightings() const +{ + itk::Optimizer::ScalesType weightings(this->GetNumberOfParameters()); + + switch (m_TransformMetaInfo->GetDegreeOfFreedom()) { + case X_ONLY: + case Y_ONLY: + case Z_ONLY: + weightings[0] = 1.0; + break; + ; + case THREE_DOF: + weightings[0] = 1.; + weightings[1] = 1.; + weightings[2] = 1.; + break; + case ROTATION_ONLY: + weightings[0] = 1. / dtr; + weightings[1] = 1. / dtr; + weightings[2] = 1. / dtr; + break; + case SIX_DOF: + weightings[0] = 1.; + weightings[1] = 1.; + weightings[2] = 1.; + weightings[3] = 1. / dtr; + weightings[4] = 1. / dtr; + weightings[5] = 1. / dtr; + break; + + default: + itkExceptionMacro(<< "Unsupported degree of freedeom"); + break; + } + return weightings; +} + +template +typename gTwoImageToOneImageMetric::ParametersType gTwoImageToOneImageMetric::GetParameters() const +{ + + ParametersType parametersTransform = m_Transform1->GetParameters(); //angleX, angleY, angleZ, transX, transY, transZ + ParametersType parameters(this->GetNumberOfParameters()); + switch (m_TransformMetaInfo->GetDegreeOfFreedom()) { + case X_ONLY: + parameters[0] = parametersTransform[3]; + break; + case Y_ONLY: + parameters[0] = parametersTransform[4]; + break; + case Z_ONLY: + parameters[0] = parametersTransform[5]; + break; + case THREE_DOF: + parameters[0] = parametersTransform[3]; + parameters[1] = parametersTransform[4]; + parameters[2] = parametersTransform[5]; + break; + case ROTATION_ONLY: + parameters[0] = parametersTransform[0]; + parameters[1] = parametersTransform[1]; + parameters[2] = parametersTransform[2]; + break; + case SIX_DOF: + parameters[0] = parametersTransform[3]; + parameters[1] = parametersTransform[4]; + parameters[2] = parametersTransform[5]; + parameters[3] = parametersTransform[0]; + parameters[4] = parametersTransform[1]; + parameters[5] = parametersTransform[2]; + break; + + default: + itkExceptionMacro(<< "Unsupported degree of freedeom"); + break; + } + return parameters; +} + +template +void gTwoImageToOneImageMetric::PrintSelf(std::ostream& os, Indent indent) const +{ + Superclass::PrintSelf(os, indent); + os << indent << "ComputeGradient: " << static_cast::PrintType>(m_ComputeGradient) + << std::endl; + os << indent << "Moving Image: " << m_MovingImage.GetPointer() << std::endl; + os << indent << "Fixed Image 1: " << m_FixedImage1.GetPointer() << std::endl; + os << indent << "Fixed Image 2: " << m_FixedImage2.GetPointer() << std::endl; + os << indent << "Gradient Image: " << m_GradientImage.GetPointer() << std::endl; + os << indent << "Transform1: " << m_Transform1.GetPointer() << std::endl; + os << indent << "Transform2: " << m_Transform2.GetPointer() << std::endl; + os << indent << "Interpolator 1: " << m_Interpolator1.GetPointer() << std::endl; + os << indent << "Interpolator 2: " << m_Interpolator2.GetPointer() << std::endl; + os << indent << "Filter 1: " << m_Filter1.GetPointer() << std::endl; + os << indent << "Filter 2: " << m_Filter2.GetPointer() << std::endl; + os << indent << "Transform MetaInfoe: " << m_TransformMetaInfo.GetPointer() << std::endl; + os << indent << "FixedImageRegion 1: " << m_FixedImageRegion1 << std::endl; + os << indent << "FixedImageRegion 2: " << m_FixedImageRegion2 << std::endl; + os << indent << "Moving Image Mask: " << m_MovingImageMask.GetPointer() << std::endl; + os << indent << "Fixed Image Mask 1: " << m_FixedImageMask1.GetPointer() << std::endl; + os << indent << "Fixed Image Mask 2: " << m_FixedImageMask2.GetPointer() << std::endl; + os << indent << "Number of Pixels Counted: " << m_NumberOfPixelsCounted << std::endl; +} + +template +void gTwoImageToOneImageMetric::WriteImage(MovingImageConstPointer img, std::string fileName, std::string path) const +{ + + using RescaleFilterType = itk::RescaleIntensityImageFilter; + using WriterType = itk::ImageFileWriter; + + if (img) { + + // Rescale the intensity of the projection images to 0-255 for output. + typename RescaleFilterType::Pointer rescaler1 = RescaleFilterType::New(); + rescaler1->SetOutputMinimum(0); + rescaler1->SetOutputMaximum(255); + rescaler1->SetInput(img); + + WriterType::Pointer writer1 = WriterType::New(); + + if (fileName.empty()) { + + char result[PATH_MAX]; + ssize_t count = readlink("/proc/self/exe", result, PATH_MAX); + if (count != -1) { + path = dirname(result); + path += "/img/out/"; + } + } + + if (fileName.empty()) { + + fileName = path; + fileName += "2D1.tif"; + } + writer1->SetFileName(fileName); + writer1->SetInput(rescaler1->GetOutput()); + + try { + std::cout << "Writing image: " << fileName << std::endl; + writer1->Update(); + } catch (itk::ExceptionObject& err) { + std::cerr << "ERROR: ExceptionObject caught !" << std::endl; + std::cerr << err << std::endl; + } + } +} + +} // end namespace itk + +#endif From 34fb002321d786ee751db1dd4b3380b8965fc850 Mon Sep 17 00:00:00 2001 From: Proton local user Date: Tue, 24 Jan 2023 17:58:32 +0100 Subject: [PATCH 19/49] Some minor UI changes for testing to MedPhys. User can not change between Data and Reg. Checkerboard and rulers are out. --- .../itkDTRrecon/vtkContourTopogramProjectionFilter.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reg23Topograms/itkDTRrecon/vtkContourTopogramProjectionFilter.cxx b/reg23Topograms/itkDTRrecon/vtkContourTopogramProjectionFilter.cxx index 602abf9..aace8c0 100644 --- a/reg23Topograms/itkDTRrecon/vtkContourTopogramProjectionFilter.cxx +++ b/reg23Topograms/itkDTRrecon/vtkContourTopogramProjectionFilter.cxx @@ -167,7 +167,7 @@ int vtkContourTopogramProjectionFilter::RequestData( pp2[1] -= dProjectionLPSOffset [1]; pp2[2] -= dProjectionLPSOffset [2]; -// std::cout << ii << " " << pp2[0] << " " << pp2[1] << " " << pp2[2] << std::endl; + std::cout << ii << " " << pp2[0] << " " << pp2[1] << " " << pp2[2] << std::endl; PrjPoints->InsertPoint(ii,pp2); } From d82bd12ef94883967126409fd07e013f12abf1e6 Mon Sep 17 00:00:00 2001 From: Proton local user Date: Wed, 25 Jan 2023 10:51:13 +0100 Subject: [PATCH 20/49] Fixed errors in Projecting and visualising Contours and Isocenter when loading RTPlan --- .../itkDTRrecon/vtkContourTopogramProjectionFilter.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reg23Topograms/itkDTRrecon/vtkContourTopogramProjectionFilter.cxx b/reg23Topograms/itkDTRrecon/vtkContourTopogramProjectionFilter.cxx index aace8c0..602abf9 100644 --- a/reg23Topograms/itkDTRrecon/vtkContourTopogramProjectionFilter.cxx +++ b/reg23Topograms/itkDTRrecon/vtkContourTopogramProjectionFilter.cxx @@ -167,7 +167,7 @@ int vtkContourTopogramProjectionFilter::RequestData( pp2[1] -= dProjectionLPSOffset [1]; pp2[2] -= dProjectionLPSOffset [2]; - std::cout << ii << " " << pp2[0] << " " << pp2[1] << " " << pp2[2] << std::endl; +// std::cout << ii << " " << pp2[0] << " " << pp2[1] << " " << pp2[2] << std::endl; PrjPoints->InsertPoint(ii,pp2); } From 085f8e090067b4f68f791af65fdda9e3b23a0d00 Mon Sep 17 00:00:00 2001 From: Proton local user Date: Wed, 22 Feb 2023 15:09:26 +0100 Subject: [PATCH 21/49] Added dialogs for approval and Automatic Registration. Added abort of auto registration --- reg23Topograms/itkDTRrecon/CMakeLists.txt | 1 + .../itkDTRrecon/autoreg/itkDRTHelpers.h | 2 +- ...ualInformationTwoImageToOneImageMetric.hxx | 2 + ...zedCorrelationTwoImageToOneImageMetric.hxx | 25 +-- .../itkTwoProjectionImageRegistrationMethod.h | 9 + ...tkTwoProjectionImageRegistrationMethod.hxx | 45 +++++ .../autoreg/itkgTwoImageToOneImageMetric.hxx | 16 +- .../itkDTRrecon/itkImageProcessor.cpp | 32 ++- .../itkDTRrecon/itkImageProcessor.h | 130 ++---------- .../itkDTRrecon/itkQtIterationUpdate.h | 185 ++++++++++++++++++ 10 files changed, 308 insertions(+), 139 deletions(-) create mode 100644 reg23Topograms/itkDTRrecon/itkQtIterationUpdate.h diff --git a/reg23Topograms/itkDTRrecon/CMakeLists.txt b/reg23Topograms/itkDTRrecon/CMakeLists.txt index 60032bc..fd530ce 100644 --- a/reg23Topograms/itkDTRrecon/CMakeLists.txt +++ b/reg23Topograms/itkDTRrecon/CMakeLists.txt @@ -23,6 +23,7 @@ SET(SRCS SET(HDR itkImageProcessor.h + itkQtIterationUpdate.h itkgSiddonJacobsRayCastInterpolateImageFunction.h itkgSiddonJacobsRayCastInterpolateImageFunction.hxx vtkContourTopogramProjectionFilter.h diff --git a/reg23Topograms/itkDTRrecon/autoreg/itkDRTHelpers.h b/reg23Topograms/itkDTRrecon/autoreg/itkDRTHelpers.h index e8e563e..36580ed 100644 --- a/reg23Topograms/itkDTRrecon/autoreg/itkDRTHelpers.h +++ b/reg23Topograms/itkDTRrecon/autoreg/itkDRTHelpers.h @@ -35,7 +35,7 @@ static const char* ImageOrientationStrings[] = { // constant for converting degrees into radians const float dtr = itk::Math::pi_over_180; -static const bool verbose = true; +static const bool verbose = false; /* this is in the end a IEC to HFS... * but we keep this for ourselves... diff --git a/reg23Topograms/itkDTRrecon/autoreg/itkMutualInformationTwoImageToOneImageMetric.hxx b/reg23Topograms/itkDTRrecon/autoreg/itkMutualInformationTwoImageToOneImageMetric.hxx index 748df79..089c7f9 100644 --- a/reg23Topograms/itkDTRrecon/autoreg/itkMutualInformationTwoImageToOneImageMetric.hxx +++ b/reg23Topograms/itkDTRrecon/autoreg/itkMutualInformationTwoImageToOneImageMetric.hxx @@ -25,6 +25,8 @@ #include "itkNormalizeImageFilter.h" #include "itkTranslationTransform.h" +#include "itkProgressReporter.h" + #include namespace itk { diff --git a/reg23Topograms/itkDTRrecon/autoreg/itkNormalizedCorrelationTwoImageToOneImageMetric.hxx b/reg23Topograms/itkDTRrecon/autoreg/itkNormalizedCorrelationTwoImageToOneImageMetric.hxx index f76c15f..06e9c34 100644 --- a/reg23Topograms/itkDTRrecon/autoreg/itkNormalizedCorrelationTwoImageToOneImageMetric.hxx +++ b/reg23Topograms/itkDTRrecon/autoreg/itkNormalizedCorrelationTwoImageToOneImageMetric.hxx @@ -211,11 +211,11 @@ NormalizedCorrelationTwoImageToOneImageMetric::Calcul } else { measure = NumericTraits::Zero; } - std::cout << "movingValueMin: " << movingValueMin << " movingValueMax: " << movingValueMax << std::endl; - std::cout << "fixedValueMin: " << fixedValueMin << " fixedValueMax: " << fixedValueMax << std::endl; - std::cout << "max coordinates: " << maxX << " " << maxX << " " << maxZ << std::endl; - std::cout << "min coordinates: " << minX << " " << minY << " " << minZ << std::endl; +// std::cout << "movingValueMin: " << movingValueMin << " movingValueMax: " << movingValueMax << std::endl; +// std::cout << "fixedValueMin: " << fixedValueMin << " fixedValueMax: " << fixedValueMax << std::endl; +// std::cout << "max coordinates: " << maxX << " " << maxX << " " << maxZ << std::endl; +// std::cout << "min coordinates: " << minX << " " << minY << " " << minZ << std::endl; return measure; } @@ -275,18 +275,19 @@ NormalizedCorrelationTwoImageToOneImageMetric::GetVal auto oldprecision = std::cout.precision(); MeasureType measure1 = CalculateMeasure(1); - std::cout.precision(std::numeric_limits::digits10 + 2); - std::cout << "Measure1: " << measure1 << " Counts: " << this->m_NumberOfPixelsCounted << std::endl; - std::cout.precision(oldprecision); +// std::cout.precision(std::numeric_limits::digits10 + 2); +// std::cout << "Measure1: " << measure1 << " Counts: " << this->m_NumberOfPixelsCounted << std::endl; +// std::cout.precision(oldprecision); MeasureType measure2 = CalculateMeasure(2); - std::cout.precision(std::numeric_limits::digits10 + 2); - std::cout << "Measure2: " << measure2 << " Counts: " << this->m_NumberOfPixelsCounted << std::endl; +// std::cout.precision(std::numeric_limits::digits10 + 2); +// std::cout << "Measure2: " << measure2 << " Counts: " << this->m_NumberOfPixelsCounted << std::endl; auto measure = (measure1 + measure2) / 2.0; - std::cout << "Measure: " << measure << std::endl; - std::cout << "=======================================================" << std::endl; - std::cout.precision(oldprecision); + +// std::cout << "Measure: " << measure << std::endl; +// std::cout << "=======================================================" << std::endl; +// std::cout.precision(oldprecision); return measure; } diff --git a/reg23Topograms/itkDTRrecon/autoreg/itkTwoProjectionImageRegistrationMethod.h b/reg23Topograms/itkDTRrecon/autoreg/itkTwoProjectionImageRegistrationMethod.h index de7a291..3dd6241 100644 --- a/reg23Topograms/itkDTRrecon/autoreg/itkTwoProjectionImageRegistrationMethod.h +++ b/reg23Topograms/itkDTRrecon/autoreg/itkTwoProjectionImageRegistrationMethod.h @@ -25,6 +25,10 @@ #include "itkProcessObject.h" #include "itkSingleValuedNonLinearOptimizer.h" #include "itkgTwoImageToOneImageMetric.h" + +#include "itkObject.h" +#include "itkEventObject.h" + #include namespace itk { @@ -231,6 +235,11 @@ protected: /** Provides derived classes with the ability to set this private var */ itkSetMacro(LastOptimizerParameters, ParametersType); + /** Entry-point for internal ITK filter observer. **/ + void OnInternalFilterProgressReceptor(itk::Object *caller, + const itk::EventObject &event); + + private: MetricPointer m_Metric; OptimizerType::Pointer m_Optimizer; diff --git a/reg23Topograms/itkDTRrecon/autoreg/itkTwoProjectionImageRegistrationMethod.hxx b/reg23Topograms/itkDTRrecon/autoreg/itkTwoProjectionImageRegistrationMethod.hxx index fa77cd7..b486ea0 100644 --- a/reg23Topograms/itkDTRrecon/autoreg/itkTwoProjectionImageRegistrationMethod.hxx +++ b/reg23Topograms/itkDTRrecon/autoreg/itkTwoProjectionImageRegistrationMethod.hxx @@ -18,6 +18,8 @@ #ifndef itkTwoProjectionImageRegistrationMethod_hxx #define itkTwoProjectionImageRegistrationMethod_hxx +#include "itkCommand.h" + #include "itkTwoProjectionImageRegistrationMethod.h" namespace itk { @@ -175,6 +177,32 @@ void TwoProjectionImageRegistrationMethod::Initialize m_Optimizer->SetInitialPosition(m_InitialOptimizerParameters); } +template +void TwoProjectionImageRegistrationMethod::OnInternalFilterProgressReceptor( + itk::Object *caller, const itk::EventObject &event) +{ + itk::ProcessObject *filter = dynamic_cast(caller); + + if(!itk::ProgressEvent().CheckEvent(&event) || !filter) + return; + + if (filter) + { +// double p = m_CurrentProgressStart; +// // filter->GetProgress() in [0;1] +// p += m_CurrentProgressSpan * filter->GetProgress(); +// // NOTE: filter is buggy - not in [0;1] if multi-threading is activated! +// if (p > (m_CurrentProgressStart + m_CurrentProgressSpan)) +// p = m_CurrentProgressStart + m_CurrentProgressSpan; +// TaskProgressInfo(m_CurrentProgressDirection, p); + +// if (m_CancelRequest) +// filter->SetAbortGenerateData(true); // may be handled by filter + + std::cout << "Porca Madonna " << std::endl; + } +} + /* * Starts the Registration Process */ @@ -182,6 +210,22 @@ template void TwoProjectionImageRegistrationMethod::StartRegistration() { +// typedef itk::MemberCommand ITKCommandType; +// typedef ITKCommandType::Pointer MemberPointer ; + + +// ITKCommandType::Pointer cmd = ITKCommandType::New(); +// itk::Command cmd= itk::Command::Pointer(this); + +// cmd->SetCallbackFunction(this, +// (ITKCommandType::Pointer)&TwoProjectionImageRegistrationMethod::OnInternalFilterProgressReceptor); + + itk::ProgressReporter progress( + this, + 1, 1000,100); + +// this->SetAbortGenerateData(true); + ParametersType empty(1); empty.Fill(0.0); try { @@ -253,6 +297,7 @@ void TwoProjectionImageRegistrationMethod::PrintSelf( template void TwoProjectionImageRegistrationMethod::GenerateData() { + this->StartRegistration(); } diff --git a/reg23Topograms/itkDTRrecon/autoreg/itkgTwoImageToOneImageMetric.hxx b/reg23Topograms/itkDTRrecon/autoreg/itkgTwoImageToOneImageMetric.hxx index 0e9c600..90a9548 100644 --- a/reg23Topograms/itkDTRrecon/autoreg/itkgTwoImageToOneImageMetric.hxx +++ b/reg23Topograms/itkDTRrecon/autoreg/itkgTwoImageToOneImageMetric.hxx @@ -97,14 +97,14 @@ bool gTwoImageToOneImageMetric::SetTransformParameter break; } - std::cout << "New Transform Parameters = " << std::endl; - std::cout << " Translation X = " << TranslationAlongX << " mm" << std::endl; - std::cout << " Translation Y = " << TranslationAlongY << " mm" << std::endl; - std::cout << " Translation Z = " << TranslationAlongZ << " mm" << std::endl; - std::cout << " Rotation Along X = " << RotationAlongX / dtr << " deg" << std::endl; - std::cout << " Rotation Along Y = " << RotationAlongY / dtr << " deg" << std::endl; - std::cout << " Rotation Along Z = " << RotationAlongZ / dtr << " deg" << std::endl; - std::cout << "+++++++++++++++++++++++++++++++++++++++++++++++++++++++" << std::endl; +// std::cout << "New Transform Parameters = " << std::endl; +// std::cout << " Translation X = " << TranslationAlongX << " mm" << std::endl; +// std::cout << " Translation Y = " << TranslationAlongY << " mm" << std::endl; +// std::cout << " Translation Z = " << TranslationAlongZ << " mm" << std::endl; +// std::cout << " Rotation Along X = " << RotationAlongX / dtr << " deg" << std::endl; +// std::cout << " Rotation Along Y = " << RotationAlongY / dtr << " deg" << std::endl; +// std::cout << " Rotation Along Z = " << RotationAlongZ / dtr << " deg" << std::endl; +// std::cout << "+++++++++++++++++++++++++++++++++++++++++++++++++++++++" << std::endl; transformParameters[0] = RotationAlongX; transformParameters[1] = RotationAlongY; diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp index e613dd6..aa2c7b8 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp @@ -1,4 +1,4 @@ - + /* @@ -25,6 +25,8 @@ gfattori 08.11.2021 #include "itkOrientImageFilter.h" #include +#include "itkCommand.h" + #include "itkTimeProbesCollectorBase.h" #include @@ -200,13 +202,14 @@ itkImageProcessor::itkImageProcessor() optimizer = OptimizerType::New(); amoebaoptimizer = AmoebaOptimizerType::New(); - optimizerObserver = CommandIterationUpdate::New(); + exhaustiveOptimizer = ExhaustiveOptimizerType::New(); exhaustiveOptimizerObserver = ExhaustiveCommandIterationUpdate::New(); registration = RegistrationType::New(); + optimizerObserver->SetProcess(registration); if (m_UseMutualInformation) { registration->SetMetric(mimetric); @@ -1368,7 +1371,7 @@ itkImageProcessor::CalculateInternalTransform( m_OutputTransform; } -void itkImageProcessor::InitializeRegistration(int maximumIteration, double stepLength, double maxTranslation, eDegreeOfFreedomType dof) +void itkImageProcessor::InitializeRegistration(double stepLength, double maxTranslation, eDegreeOfFreedomType dof) { std::cout << "*" << __COMPACT_PRETTY_FUNCTION__ << std::endl; @@ -1396,6 +1399,7 @@ void itkImageProcessor::InitializeRegistration(int maximumIteration, double step metric->DebugOn(); } + registration->SetFixedImage1(m_PASourceDupli->GetOutput()); registration->SetFixedImage2(m_LATSourceDupli->GetOutput()); registration->SetMovingImage(m_VolumeSourceDupli->GetOutput()); @@ -1553,7 +1557,7 @@ void itkImageProcessor::InitializeRegistration(int maximumIteration, double step // The metric will return 0 or a "large" negative number in case of high correspondence of the images // Thus, we need to minimze optimizer->SetMaximize(false); // for NCC and MI - optimizer->SetMaximumIteration(maximumIteration); + optimizer->SetMaximumIteration(m_MaxNumberOfIterations); optimizer->SetMaximumLineIteration(4); // for Powell's method optimizer->SetStepLength(stepLength); optimizer->SetStepTolerance(0.01); @@ -1563,10 +1567,13 @@ void itkImageProcessor::InitializeRegistration(int maximumIteration, double step optimizer->Print(std::cout); } + optimizer->RemoveAllObservers(); - optimizer->AddObserver(itk::IterationEvent(), optimizerObserver); + optimizer->AddObserver(itk::AnyEvent(), optimizerObserver); registration->SetOptimizer(optimizer); + registration->RemoveAllObservers(); + } else { amoebaoptimizer->SetMinimize(true); @@ -1658,11 +1665,13 @@ int itkImageProcessor::StartRegistration(std::string extraInfo) } try { - timer.Start("Registration"); +// timer.Start("Registration"); // Start the registration. registration->StartRegistration(); - timer.Stop("Registration"); +// timer.Stop("Registration"); } catch (itk::ExceptionObject& err) { + + registration->ResetPipeline(); std::cout << "ExceptionObject caught !" << std::endl; std::cout << err << std::endl; return -1; @@ -1728,7 +1737,8 @@ int itkImageProcessor::StartRegistration(std::string extraInfo) void itkImageProcessor::InitializeProjector() { -// std::cout<< "itkImageProcessor::InitializeProjector()" <; - itkNewMacro(Self); - -protected: - CommandIterationUpdate() = default; - -public: - using OptimizerType = itk::PowellOptimizer; - using OptimizerPointer = const OptimizerType*; - - using AmoebaOptimizerType = itk::AmoebaOptimizer; - ; - using AmoebaOptimizerPointer = const OptimizerType*; - - void - Execute(itk::Object* caller, const itk::EventObject& event) override - { - Execute((const itk::Object*)caller, event); - } - - void - Execute(const itk::Object* object, const itk::EventObject& event) override - { - auto optimizer = dynamic_cast(object); - if (typeid(event) == typeid(itk::IterationEvent)) { - - //Feedback from the optimizer executed at the end of every itteration - // currently just print the result into the cout. We might add - // functionality to register and emit signals to update the UI. - - std::cout << "Iteration: " << optimizer->GetCurrentIteration() << std::endl; - auto oldprecision = std::cout.precision(); - std::cout.precision(std::numeric_limits::digits10 + 2); - std::cout << "Similarity: " << optimizer->GetValue() << std::endl; - std::cout.precision(oldprecision); - std::cout << "Position: " << optimizer->GetCurrentPosition() << std::endl; - } - return; - } -}; - -class ExhaustiveCommandIterationUpdate : public itk::Command { - // TODO: Move to own files. - -public: - using Self = ExhaustiveCommandIterationUpdate; - using Superclass = itk::Command; - using Pointer = itk::SmartPointer; - itkNewMacro(Self); - - std::ostream* os; - -protected: - ExhaustiveCommandIterationUpdate() = default; - -public: - using OptimizerType = itk::ExhaustiveOptimizer; - ; - using OptimizerPointer = const OptimizerType*; - - void set_stream(std::ostream& stream) - { - os = &stream; - } - - void - Execute(itk::Object* caller, const itk::EventObject& event) override - { - Execute((const itk::Object*)caller, event); - } - - void - Execute(const itk::Object* object, const itk::EventObject& event) override - { - auto optimizer = dynamic_cast(object); - if (typeid(event) == typeid(itk::IterationEvent)) { - - //crude LPS to IEC transform for HFS. - auto position = optimizer->GetCurrentPosition(); - - auto oldprecision = os->precision(); - os->precision(std::numeric_limits::digits10 + 2); - *os << optimizer->GetCurrentValue(); - os->precision(oldprecision); - *os << "\t" << position[0] << "\t" << position[2] << "\t" << -position[1] << std::endl; - } - return; - } -}; - - class ITK_EXPORT itkImageProcessor : public itk::Object { @@ -169,6 +72,11 @@ public: /** Run-time type information (and related methods). */ itkTypeMacro(itkImageProcessor, Object); + + CommandIterationUpdate::Pointer + optimizerObserver; + + /** Input data load methods*/ int load3DSerieFromFolder(const char* ); int load3DSerieFromFiles( std::vector ); @@ -228,7 +136,7 @@ public: void SetUserRotationsLPS(double, double, double); /** Initialize the registration pipeline*/ - void InitializeRegistration(int, double, double, eDegreeOfFreedomType); + void InitializeRegistration(double, double, eDegreeOfFreedomType); /** Start the registration process*/ int StartRegistration(std::string extraInfo); @@ -277,7 +185,10 @@ public: void SetOptimizer(std::string); void SetMetric(std::string); void SetFullROI(bool); + void SetMaxNumberOfIterations(int); + /** Optimizer which tries to find the minimn (Powell Optimizer)*/ + using OptimizerType = itk::PowellOptimizer; protected: /** Various pixel types */ @@ -299,7 +210,7 @@ private: /** Fill Meta after 3D volume load */ int fill3DVolumeMeta(InternalImageType::Pointer, - tPatOrientation); + tPatOrientation); /** Image types */ using ImageType2D = itk::Image; @@ -314,7 +225,7 @@ private: using ResampleFilterType = itk::ResampleImageFilter; /** Optimizer which tries to find the minimn (Powell Optimizer)*/ - using OptimizerType = itk::PowellOptimizer; + // using OptimizerType = itk::PowellOptimizer; using AmoebaOptimizerType = itk::AmoebaOptimizer; /** Optimizer which samples the whol space */ using ExhaustiveOptimizerType = itk::ExhaustiveOptimizer; @@ -376,21 +287,19 @@ private: imageDRT2In; RegistrationType::Pointer - registration; + registration; MetricType::Pointer - metric; + metric; MIMetricType::Pointer - mimetric; + mimetric; OptimizerType::Pointer - optimizer; + optimizer; AmoebaOptimizerType::Pointer - amoebaoptimizer; - CommandIterationUpdate::Pointer - optimizerObserver; + amoebaoptimizer; ExhaustiveOptimizerType::Pointer - exhaustiveOptimizer; + exhaustiveOptimizer; ExhaustiveCommandIterationUpdate::Pointer - exhaustiveOptimizerObserver; + exhaustiveOptimizerObserver; DuplicatorType::Pointer m_LATSourceDupli, @@ -490,6 +399,7 @@ private: double m_OptmizerValue; + int m_MaxNumberOfIterations; bool m_UseExhaustiveOptmizer; bool m_UseAmeobaOptimizer; diff --git a/reg23Topograms/itkDTRrecon/itkQtIterationUpdate.h b/reg23Topograms/itkDTRrecon/itkQtIterationUpdate.h new file mode 100644 index 0000000..5c055d4 --- /dev/null +++ b/reg23Topograms/itkDTRrecon/itkQtIterationUpdate.h @@ -0,0 +1,185 @@ +#ifndef ITKQTITERATIONUPDATE_H +#define ITKQTITERATIONUPDATE_H + +#include "itkCommand.h" +#include +#include "itkPowellOptimizer.h" +#include "itkAmoebaOptimizer.h" +#include "itkExhaustiveOptimizer.h" + +#include "itkTwoProjectionImageRegistrationMethod.h" + + +class QObjectIterationUpdate : public QObject{ + Q_OBJECT +public: + QObjectIterationUpdate(){ + bAbortProcessCommand = false; + }; + + bool getAbortFlag(){ + return bAbortProcessCommand; + }; + void setAbortFlag(bool bVal){ + bAbortProcessCommand = bVal; + }; + +public slots: + void onAbortProcessCommand(){ + std::cout << " Abort STOCAZZO " << std::endl; + bAbortProcessCommand = true; + }; + void onIteration(double dI,double dX,double dY,double dZ){ + emit + sendRegistrationProgress(dI,dX,dY,dZ); + + } +private: + bool + bAbortProcessCommand; + + + + + +signals: +void sendRegistrationProgress(double,double,double,double); + +}; + +namespace itk +{ + + +class CommandIterationUpdate : public itk::Command { + // TODO: Move to own files. + + constexpr static unsigned int Dimension = 3; + +public: + QObjectIterationUpdate *objIterUpdate; + + using Self = CommandIterationUpdate; + using Superclass = itk::Command; + using Pointer = itk::SmartPointer; + itkNewMacro(CommandIterationUpdate); + + using InternalPixelType = float; + using InternalImageType = itk::Image; + using ProcesssType = typename itk::TwoProjectionImageRegistrationMethod; + using ProcesssPointer = typename ProcesssType::Pointer; + + /** Set/Get the Process. */ + itkSetObjectMacro(Process, ProcesssType); + itkGetConstObjectMacro(Process, ProcesssType); + +private: + +protected: + CommandIterationUpdate() { + objIterUpdate = new QObjectIterationUpdate; + } + ProcesssPointer m_Process; + +public: + using OptimizerType = itk::PowellOptimizer; + using OptimizerPointer = const OptimizerType*; + + using AmoebaOptimizerType = itk::AmoebaOptimizer; + using AmoebaOptimizerPointer = const OptimizerType*; + + void + Execute(itk::Object* caller, const itk::EventObject& event) override + { + Execute((const itk::Object*)caller, event); + } + + void + Execute(const itk::Object* object, const itk::EventObject& event) override + { + if(objIterUpdate->getAbortFlag()){ + std::cout << "Abortisci per piacere" << std::endl; + objIterUpdate->setAbortFlag(false); + throw itk::ProcessAborted(); + } +// std::cout << "Progress: " << this->m_Process->GetAbortGenerateData() << std::endl; + + auto optimizer = dynamic_cast(object); + + if (typeid(event) == typeid(itk::IterationEvent)) { + + //Feedback from the optimizer executed at the end of every itteration + // currently just print the result into the cout. We might add + // functionality to register and emit signals to update the UI. + + std::cout << "Iteration: " << optimizer->GetCurrentIteration() << std::endl; + auto oldprecision = std::cout.precision(); + std::cout.precision(std::numeric_limits::digits10 + 2); + std::cout << "Similarity: " << optimizer->GetValue() << std::endl; + std::cout.precision(oldprecision); + std::cout << "Position: " << optimizer->GetCurrentPosition() << std::endl; + + objIterUpdate->onIteration( + optimizer->GetCurrentIteration()+1, + optimizer->GetCurrentPosition()[0], + optimizer->GetCurrentPosition()[2], + -optimizer->GetCurrentPosition()[1] + ); + } + return; + } +}; + +class ExhaustiveCommandIterationUpdate : public itk::Command { + // TODO: Move to own files. + +public: + using Self = ExhaustiveCommandIterationUpdate; + using Superclass = itk::Command; + using Pointer = itk::SmartPointer; + itkNewMacro(Self); + + std::ostream* os; + +protected: + ExhaustiveCommandIterationUpdate() = default; + +public: + using OptimizerType = itk::ExhaustiveOptimizer; + ; + using OptimizerPointer = const OptimizerType*; + + void set_stream(std::ostream& stream) + { + os = &stream; + } + + void + Execute(itk::Object* caller, const itk::EventObject& event) override + { + Execute((const itk::Object*)caller, event); + } + + void + Execute(const itk::Object* object, const itk::EventObject& event) override + { + auto optimizer = dynamic_cast(object); + if (typeid(event) == typeid(itk::IterationEvent)) { + + //crude LPS to IEC transform for HFS. + auto position = optimizer->GetCurrentPosition(); + + auto oldprecision = os->precision(); + os->precision(std::numeric_limits::digits10 + 2); + *os << optimizer->GetCurrentValue(); + os->precision(oldprecision); + *os << "\t" << position[0] << "\t" << position[2] << "\t" << -position[1] << std::endl; + } + return; + } +}; + +} + +#endif + From c4811e32b79d60cfa19629cae6c3da04a95ed61f Mon Sep 17 00:00:00 2001 From: Proton local user Date: Tue, 21 Mar 2023 13:50:18 +0100 Subject: [PATCH 22/49] Cleanup of some cout and functioning undo and redo of Corrections --- reg23Topograms/itkDTRrecon/itkQtIterationUpdate.h | 1 - 1 file changed, 1 deletion(-) diff --git a/reg23Topograms/itkDTRrecon/itkQtIterationUpdate.h b/reg23Topograms/itkDTRrecon/itkQtIterationUpdate.h index 5c055d4..402c4b6 100644 --- a/reg23Topograms/itkDTRrecon/itkQtIterationUpdate.h +++ b/reg23Topograms/itkDTRrecon/itkQtIterationUpdate.h @@ -26,7 +26,6 @@ public: public slots: void onAbortProcessCommand(){ - std::cout << " Abort STOCAZZO " << std::endl; bAbortProcessCommand = true; }; void onIteration(double dI,double dX,double dY,double dZ){ From 7d7dc6010d523d4ac1742f3e5031a987b9e03ca9 Mon Sep 17 00:00:00 2001 From: Proton local user Date: Tue, 21 Mar 2023 14:24:53 +0100 Subject: [PATCH 23/49] Solved bug on Translation widget --- .../itkDTRrecon/itkImageProcessor.cpp | 29 +++++-------------- 1 file changed, 8 insertions(+), 21 deletions(-) diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp index aa2c7b8..75f0e3e 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp @@ -353,12 +353,6 @@ void itkImageProcessor::SetCustom_ProjectionCenterFixedAxes_IEC( void itkImageProcessor::SetCustom_2Dres(double nX1,double nY1,double nX2,double nY2) { - std::cout << "SetCustom_2Dres " - << nX1 << " " - << nY1 << " " - << nX2 << " " - << nY2 << std::endl; - if(m_DRTGeometryMetaInfo == NULL) { // todo } @@ -379,12 +373,6 @@ void itkImageProcessor::SetCustom_2Dres(double nX1,double nY1,double nX2,double void itkImageProcessor::SetCustom_2Dsize(int nX1, int nY1,int nX2,int nY2) { - std::cout << "SetCustom_2Dsize " - << nX1 << " " - << nY1 << " " - << nX2 << " " - << nY2 << std::endl; - if(m_DRTGeometryMetaInfo == NULL) { // todo } @@ -2104,11 +2092,11 @@ void itkImageProcessor::UpdateProjectionGeometryMeta(){ IsocenterOffsetLPS = m_CTMetaInfo->ConvertIECPointToLPSPoint( m_DRTGeometryMetaInfo->GetProjectionCenterOffset1()); - std::cout<< "///////////////// PGEOM META BEG ///////////////" <GetProjectionCenter() <GetProjectionCenter() <SetProjectionAngleLPS( this->CalcProjectionAngleLPS( m_CTMetaInfo->GetPatientOrientation(), @@ -2194,9 +2181,9 @@ void itkImageProcessor::UpdateProjectionGeometryMeta(){ Std_DRT2LPS) ); - std::cout<<"IsocenterOffsetLPS"<< IsocenterOffsetLPS <GetSize()"<< m_DRTImage1MetaInfo->GetSize() <GetSpacing()"<< m_DRTImage1MetaInfo->GetSpacing() <GetOrigin()"<< m_DRTImage1MetaInfo->GetOrigin() < Date: Wed, 22 Mar 2023 10:10:27 +0100 Subject: [PATCH 24/49] CleanUp code of ui_qvtk_handler.cpp. Bye Bye rendering of DRT and TOPO only --- reg23Topograms/itkDTRrecon/itkImageProcessor.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp index 75f0e3e..bccff5f 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp @@ -1954,8 +1954,6 @@ void itkImageProcessor::InitializeProjector() // std::cout<< "itkImageProcessor::InitializeProjector() " <Update(); filter2->SetInput( resampleFilter2 ->GetOutput() ); @@ -1965,16 +1963,12 @@ void itkImageProcessor::InitializeProjector() filter2->ChangeOriginOn(); filter2->UpdateOutputInformation(); - filter1->Update(); filter2->Update(); - - imageDRT1In = filter1->GetOutput(); imageDRT2In = filter2->GetOutput(); - } From abc594dac3632edc5d8392623eafd2ccb156f248 Mon Sep 17 00:00:00 2001 From: Proton local user Date: Wed, 22 Mar 2023 18:40:48 +0100 Subject: [PATCH 25/49] Implemented unload in imageProcessor. Fixed quite big bug on reloading of patient that kept trasformation matrix of previous alignment --- .../itkDTRrecon/itkImageProcessor.cpp | 101 +++++++++++++++--- .../itkDTRrecon/itkImageProcessor.h | 3 + 2 files changed, 88 insertions(+), 16 deletions(-) diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp index bccff5f..655eb81 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp @@ -115,14 +115,11 @@ itkImageProcessor::itkImageProcessor() m_RTMetaInfo = NULL; - m_DRTGeometryMetaInfo = NULL; - m_TransformMetaInfo = NULL; - - m_TransformMetaInfo = TransformMetaInformation::New(); /* Initialise the projection geoemtry with defaults */ + m_DRTGeometryMetaInfo = NULL; m_DRTGeometryMetaInfo = DRTProjectionGeometryImageMetaInformation::New(); m_DRTGeometryMetaInfo->SetSCD1(570.); @@ -396,6 +393,27 @@ void itkImageProcessor::SetCustom_UpdateMetaInfo(){ this->UpdateProjectionGeometryMeta(); } +int itkImageProcessor::unload3DVolumeAndMeta(){ + + std::cout << "*" << __COMPACT_PRETTY_FUNCTION__ << std::endl; + + if (m_VolumeSourceDupli) { + m_VolumeSourceDupli = NULL; + m_VolumeSourceDupli = DuplicatorType::New(); + } + + m_CTMetaInfo = NULL; + + m_DRTImage1MetaInfo = NULL; + m_DRTImage2MetaInfo = NULL; + + m_TransformMetaInfo = NULL; + m_TransformMetaInfo = TransformMetaInformation::New(); + + return 1; +} + + int itkImageProcessor::load3DSerieFromFiles( std::vector v_fnames){ tPatOrientation m_PatOrientation @@ -477,10 +495,14 @@ int itkImageProcessor::load3DSerieFromFiles( std::vector v_fnames){ caster3D->SetInput(imageSeriesReader3D->GetOutput()); caster3D->Update(); - if (m_VolumeSourceDupli) { - m_VolumeSourceDupli = NULL; - m_VolumeSourceDupli = DuplicatorType::New(); - } + if (m_VolumeSourceDupli == NULL) + std::cout << "NEVER HERE m_VolumeSourceDupli" << std::endl; + +// if (m_VolumeSourceDupli) { +// std::cout << "NEVER HERE m_VolumeSourceDupli" << std::endl; +// m_VolumeSourceDupli = NULL; +// m_VolumeSourceDupli = DuplicatorType::New(); +// } m_VolumeSourceDupli->SetInputImage(caster3D->GetOutput()); m_VolumeSourceDupli->Update(); @@ -644,23 +666,23 @@ int itkImageProcessor::fill3DVolumeMeta( if(m_CTMetaInfo != NULL){ + std::cout << "NEVER HERE m_CTMetaInfo" << std::endl; m_CTMetaInfo = NULL; - // TODO UNLOAD } if(m_DRTImage1MetaInfo != NULL){ + std::cout << "NEVER HERE m_DRTImage1MetaInfo" << std::endl; m_DRTImage1MetaInfo = NULL; - // TODO UNLOAD } if(m_DRTImage2MetaInfo != NULL){ - m_DRTImage2MetaInfo = NULL; - // TODO UNLOAD + std::cout << "NEVER HERE m_DRTImage2MetaInfo" << std::endl; + m_DRTImage2MetaInfo = NULL; } if(m_RTMetaInfo != NULL){ - m_RTMetaInfo = NULL; - // TODO UNLOAD + std::cout << "NEVER HERE m_RTMetaInfo" << std::endl; + m_RTMetaInfo = NULL; } @@ -889,6 +911,38 @@ double itkImageProcessor::GetProjectionAngle2LPS(){ m_DRTImage2MetaInfo->GetProjectionAngleLPS(); } +int itkImageProcessor::unload2DAndMeta(int iImgType){ + + + switch (iImgType) { + case eProjectionOrientationType::PA: + + std::cout << "*" << __COMPACT_PRETTY_FUNCTION__ << " PA "<< std::endl; + m_TImage1MetaInfo = NULL; + + if (m_PASourceDupli) { + m_PASourceDupli = NULL; + m_PASourceDupli = DuplicatorType::New(); + } + break; + + case eProjectionOrientationType::LAT: + + std::cout << "*" << __COMPACT_PRETTY_FUNCTION__ << " LAT "<< std::endl; + m_TImage2MetaInfo = NULL; + + if (m_LATSourceDupli) { + m_LATSourceDupli = NULL; + m_LATSourceDupli = DuplicatorType::New(); + } + + break; + } + + return 1; + +} + int itkImageProcessor::load2D(const char * pcFName){ /* Check if we can open the file */ @@ -1119,6 +1173,7 @@ int itkImageProcessor::load2D(const char * pcFName){ } + int itkImageProcessor::query2DimageReconstructionDiameter(const char *pcFName){ /* Check if we can open the file */ @@ -1725,8 +1780,6 @@ int itkImageProcessor::StartRegistration(std::string extraInfo) void itkImageProcessor::InitializeProjector() { - - if(m_DRTImage1MetaInfo == NULL || m_DRTImage2MetaInfo == NULL || m_DRTGeometryMetaInfo == NULL || @@ -1995,19 +2048,31 @@ itkImageProcessor::CalcDRTImageDirections( } +int itkImageProcessor::unloadRTPlanAndMeta(){ + + std::cout << "*" << __COMPACT_PRETTY_FUNCTION__ << std::endl; + m_RTMetaInfo = NULL; + + return 1; +} + + void itkImageProcessor::loadRTPlanInfo( double dIsoX, double dIsoY, double dIsoZ, double dLAT, double dVRT ,double dLNG){ if(m_RTMetaInfo != NULL){ + std::cout << " NEVER HERE loadRTPlanInfo m_RTMetaInfo" << std::endl; //TODO } if(m_CTMetaInfo != NULL){ + std::cout << " ALWAYS HERE loadRTPlanInfo m_CTMetaInfo" << std::endl; //TODO } if(m_DRTGeometryMetaInfo != NULL){ + std::cout << " ALWAYS HERE loadRTPlanInfo m_DRTGeometryMetaInfo" << std::endl; //TODO } @@ -2037,6 +2102,7 @@ void itkImageProcessor::loadRTPlanInfo( ) ); + // std::cout<< "m_CTMetaInfo->GetImportOffset() " // <GetImportOffset() < ); + int unload3DVolumeAndMeta(); int load2D(const char *); + int unload2DAndMeta(int); int query2DimageReconstructionDiameter(const char*); void loadRTPlanInfo(double, double, double, double, double ,double); + int unloadRTPlanAndMeta(); /** Projection angles - Gantry angle IEC */ void SetProjectionAngle1IEC(double); From 6af205e60e5b6772647eefb0a6ea9074bf89b29e Mon Sep 17 00:00:00 2001 From: Proton local user Date: Mon, 17 Apr 2023 13:33:18 +0200 Subject: [PATCH 26/49] ROI implemented - check functionalities on proper dataset --- ...tkTwoProjectionImageRegistrationMethod.hxx | 2 + .../itkDTRrecon/itkImageProcessor.cpp | 92 +++++++++++++++---- .../itkDTRrecon/itkImageProcessor.h | 9 ++ 3 files changed, 84 insertions(+), 19 deletions(-) diff --git a/reg23Topograms/itkDTRrecon/autoreg/itkTwoProjectionImageRegistrationMethod.hxx b/reg23Topograms/itkDTRrecon/autoreg/itkTwoProjectionImageRegistrationMethod.hxx index b486ea0..b6f4b12 100644 --- a/reg23Topograms/itkDTRrecon/autoreg/itkTwoProjectionImageRegistrationMethod.hxx +++ b/reg23Topograms/itkDTRrecon/autoreg/itkTwoProjectionImageRegistrationMethod.hxx @@ -156,12 +156,14 @@ void TwoProjectionImageRegistrationMethod::Initialize if (m_FixedImageRegionDefined1) { m_Metric->SetFixedImageRegion1(m_FixedImageRegion1); + std::cout << "m_FixedImageRegionDefined1 is defined " << std::endl; } else { m_Metric->SetFixedImageRegion1(m_FixedImage1->GetBufferedRegion()); } if (m_FixedImageRegionDefined2) { m_Metric->SetFixedImageRegion2(m_FixedImageRegion2); + std::cout << "m_FixedImageRegionDefined2 is defined " << std::endl; } else { m_Metric->SetFixedImageRegion2(m_FixedImage2->GetBufferedRegion()); } diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp index 655eb81..04b0fca 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp @@ -1414,7 +1414,10 @@ itkImageProcessor::CalculateInternalTransform( m_OutputTransform; } -void itkImageProcessor::InitializeRegistration(double stepLength, double maxTranslation, eDegreeOfFreedomType dof) +void itkImageProcessor::InitializeRegistration( + double stepLength, + double maxTranslation, + eDegreeOfFreedomType dof) { std::cout << "*" << __COMPACT_PRETTY_FUNCTION__ << std::endl; @@ -1449,28 +1452,33 @@ void itkImageProcessor::InitializeRegistration(double stepLength, double maxTran //TODO: Here we could set the ROI for image registartion - auto region1 = m_PASourceDupli->GetOutput()->GetBufferedRegion(); - auto region2 = m_LATSourceDupli->GetOutput()->GetBufferedRegion(); - // bool setROI = false; - // if (setROI) { - // auto index1 = region1.GetIndex(); - // auto size1 = region1.GetSize(); - // auto point1 = m_PASourceDupli->GetOutput()->GetOrigin(); + if (m_UseFullROI == false) { - // index1[0] = size1[0] / 2 - 50; - // index1[1] = size1[1] / 2 - 50; + auto region1 = m_PASourceDupli->GetOutput()->GetBufferedRegion(); + auto region2 = m_LATSourceDupli->GetOutput()->GetBufferedRegion(); + std::cout << "region1 of opti - NO ROI " << region1 << std::endl; + std::cout << "region2 of opti - NO ROI " << region2 << std::endl; - // size1[0] = 100; - // size1[1] = 100; - // size1[2] = 1; + registration->SetFixedImageRegion1(roiAutoReg1); + registration->SetFixedImageRegion2(roiAutoReg2); - // region1.SetIndex(index1); - // region1.SetSize(size1); - // } + std::cout << "using ROIs for Auto Reg " << std::endl; + + std::cout << "region1 of opti " << roiAutoReg1 << std::endl; + std::cout << "region2 of opti " << roiAutoReg2 << std::endl; + + }else{ + + auto region1 = m_PASourceDupli->GetOutput()->GetBufferedRegion(); + auto region2 = m_LATSourceDupli->GetOutput()->GetBufferedRegion(); + std::cout << "region1 of opti - NO ROI " << region1 << std::endl; + std::cout << "region2 of opti - NO ROI " << region2 << std::endl; + + registration->SetFixedImageRegion1(region1); + registration->SetFixedImageRegion2(region2); + } - registration->SetFixedImageRegion1(region1); - registration->SetFixedImageRegion2(region2); registration->SetTransformMetaInfo(m_TransformMetaInfo); @@ -2446,7 +2454,8 @@ void itkImageProcessor::GetProjectionImages(){ } - + std::cout<<"Curr GetCenter"<GetCenter()<GetIsocenterLPS()<SetComputeZYX(true); transform1->SetIdentity(); @@ -3190,5 +3199,50 @@ void itkImageProcessor::SetMaxNumberOfIterations(int iNum) // TODO: Remove this function when ROI functinalitz has been implemented. } +void itkImageProcessor::SetRegionFixed1( + int iIdx0, int iIdx1, int iSz0, int iSz1){ + + auto region1temp = m_PASourceDupli->GetOutput()->GetBufferedRegion(); + + auto index1 = region1temp.GetIndex(); + auto size1 = region1temp.GetSize(); + + index1[0] = iIdx0; + index1[1] = iIdx1; + + size1[0] = iSz0; + size1[1] = iSz1; + size1[2] = 1; + + roiAutoReg1.SetIndex(index1); + roiAutoReg1.SetSize(size1); + + std::cout << "itkImageProcessor " << std::endl; + std::cout << roiAutoReg1 << std::endl; +} + +void itkImageProcessor::SetRegionFixed2( + int iIdx0, int iIdx1, int iSz0, int iSz1){ + + auto region2temp = m_LATSourceDupli->GetOutput()->GetBufferedRegion(); + + auto index2 = region2temp.GetIndex(); + auto size2 = region2temp.GetSize(); + + index2[0] = iIdx0; + index2[1] = iIdx1; + + size2[0] = iSz0; + size2[1] = iSz1; + size2[2] = 1; + + roiAutoReg2.SetIndex(index2); + roiAutoReg2.SetSize(size2); + + std::cout << "itkImageProcessor " << std::endl; + std::cout << roiAutoReg2 << std::endl; + +} + } // end namespace itk diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.h b/reg23Topograms/itkDTRrecon/itkImageProcessor.h index 5a4b8bc..04adb49 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.h +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.h @@ -189,6 +189,8 @@ public: void SetMetric(std::string); void SetFullROI(bool); void SetMaxNumberOfIterations(int); + void SetRegionFixed1(int,int,int,int); + void SetRegionFixed2(int,int,int,int); /** Optimizer which tries to find the minimn (Powell Optimizer)*/ using OptimizerType = itk::PowellOptimizer; @@ -238,6 +240,8 @@ private: /** The thing which actuall does the image registration*/ using RegistrationType = itk::TwoProjectionImageRegistrationMethod; + using RoiForRegistration = itk::ImageRegion; + /** Image reader types */ using ImageReaderType2D = itk::ImageFileReader; using ImageReaderType3D = itk::ImageFileReader; @@ -404,6 +408,11 @@ private: double m_OptmizerValue; int m_MaxNumberOfIterations; + RoiForRegistration + roiAutoReg1, + roiAutoReg2; + + bool m_UseExhaustiveOptmizer; bool m_UseAmeobaOptimizer; bool m_UseFullROI; From 292032fca2186c9dc8c784c58bec31ed408e407f Mon Sep 17 00:00:00 2001 From: Proton local user Date: Fri, 28 Apr 2023 18:51:28 +0200 Subject: [PATCH 27/49] Major modifications to account for introducing in the calibration paramters the panel center offset: This include as most important changes: - itkImageProcessor UpdateProjectionGeometryMeta - SetOriginLPS now includes that offset - ui_qvtk_handler: change in overlapping of two images. This now use the vtk provided image center which also consider image orientation and allows us to work under no assumption of center at same position between DRT and TOPO This release was tested on Imaging calibration data. Consistency was good. On Phantom data also good consistency on Correction Vector between SHORT and LONG --- .../itkDTRrecon/DRTMetaInformation.cpp | 4 + .../itkDTRrecon/DRTMetaInformation.h | 8 + .../itkDTRrecon/itkImageProcessor.cpp | 163 ++++++++++++++---- .../itkDTRrecon/itkImageProcessor.h | 14 ++ 4 files changed, 156 insertions(+), 33 deletions(-) diff --git a/reg23Topograms/itkDTRrecon/DRTMetaInformation.cpp b/reg23Topograms/itkDTRrecon/DRTMetaInformation.cpp index 748cded..55ada69 100644 --- a/reg23Topograms/itkDTRrecon/DRTMetaInformation.cpp +++ b/reg23Topograms/itkDTRrecon/DRTMetaInformation.cpp @@ -450,6 +450,10 @@ DRTProjectionGeometryImageMetaInformation(){ this->m_SCD2Offset = 0.; + this->m_Panel1Offset = 0.; + + this->m_Panel2Offset = 0.; + this->m_IntensityThreshold=0.; this->m_DRT1Size.Fill(0.); diff --git a/reg23Topograms/itkDTRrecon/DRTMetaInformation.h b/reg23Topograms/itkDTRrecon/DRTMetaInformation.h index d79ffd1..1f77f24 100644 --- a/reg23Topograms/itkDTRrecon/DRTMetaInformation.h +++ b/reg23Topograms/itkDTRrecon/DRTMetaInformation.h @@ -372,6 +372,12 @@ public: itkSetMacro(SCD2Offset, double); itkGetMacro(SCD2Offset, double); + itkSetMacro(Panel1Offset, double); + itkGetMacro(Panel1Offset, double); + + itkSetMacro(Panel2Offset, double); + itkGetMacro(Panel2Offset, double); + itkSetMacro(IntensityThreshold, double); itkGetMacro(IntensityThreshold, double); @@ -413,6 +419,8 @@ protected: m_SCD2, m_SCD1Offset, m_SCD2Offset, + m_Panel1Offset, + m_Panel2Offset, m_IntensityThreshold; diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp index 04b0fca..8dfcc00 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp @@ -261,9 +261,27 @@ double itkImageProcessor::GetSCD1(){ } double itkImageProcessor::GetSCD2(){ return - m_DRTImage1MetaInfo ->GetSCD(); + m_DRTImage2MetaInfo ->GetSCD(); } +void itkImageProcessor::SetPanelOffsets(double dOff1, double dOff2) +{ + m_DRTGeometryMetaInfo->SetPanel1Offset(dOff1); + m_DRTGeometryMetaInfo->SetPanel2Offset(dOff2); +} + +double itkImageProcessor::GetPanelOffset1(){ + return + m_DRTGeometryMetaInfo->GetPanel1Offset(); +} + +double itkImageProcessor::GetPanelOffset2(){ + return + m_DRTGeometryMetaInfo ->GetPanel2Offset(); +} + + + void itkImageProcessor::SetDegreeOfFreedom(tDegreeOfFreedomEnum dof) { m_TransformMetaInfo->SetDegreeOfFreedom(dof); @@ -2020,7 +2038,7 @@ void itkImageProcessor::InitializeProjector() filter2->SetInput( resampleFilter2 ->GetOutput() ); filter2->SetOutputDirection(m_DRTImage2MetaInfo->GetImageDirectionsLPS() ); filter2->ChangeDirectionOn(); - filter2->SetOutputOrigin(m_DRTImage2MetaInfo->GetOriginLPS() ); + filter2->SetOutputOrigin(m_DRTImage2MetaInfo->GetOriginLPS() ); filter2->ChangeOriginOn(); filter2->UpdateOutputInformation(); @@ -2160,11 +2178,11 @@ void itkImageProcessor::UpdateProjectionGeometryMeta(){ IsocenterOffsetLPS = m_CTMetaInfo->ConvertIECPointToLPSPoint( m_DRTGeometryMetaInfo->GetProjectionCenterOffset1()); -// std::cout<< "///////////////// PGEOM META BEG ///////////////" <GetProjectionCenter() <GetProjectionCenter() <SetProjectionAngleLPS( this->CalcProjectionAngleLPS( @@ -2203,27 +2223,33 @@ void itkImageProcessor::UpdateProjectionGeometryMeta(){ m_DRTImage1MetaInfo->SetProjectionOriginLPSZero( CalibratedIsocenterZeroLPS); - // This is based on the calibrated iso to be sure... - std::vector vBounds = m_CTMetaInfo->CalculateRegions( - NominalIsocenter_wZcorrectionLPS -// m_DRTImage1MetaInfo->GetProjectionOriginLPS() - ); +// // This is based on the calibrated iso to be sure... +// std::vector vBounds = m_CTMetaInfo->CalculateRegions( +// NominalIsocenter_wZcorrectionLPS +//// m_DRTImage1MetaInfo->GetProjectionOriginLPS() +// ); -// std::cout<<"Bounds1: " -// <SetSizeWithBounds( - vBounds.data(), + NULL,//vBounds.data(), m_DRTGeometryMetaInfo->GetDRT1Size(), m_DRTGeometryMetaInfo->GetDRT1Spacing() ); + ImageType3D::PointType PanelOffsetIEC1; + + PanelOffsetIEC1[0] = -m_DRTGeometryMetaInfo->GetPanel1Offset(); + PanelOffsetIEC1[1] = 0.0; + PanelOffsetIEC1[2] = 0.0; + // This HAS TO be calculated from the nominal isocenter. m_DRTImage1MetaInfo->SetOriginLPS( CalcDRTImageOrigin( @@ -2235,8 +2261,17 @@ void itkImageProcessor::UpdateProjectionGeometryMeta(){ m_DRTGeometryMetaInfo->GetProjectionAngle1IEC() ), //m_DRTGeometryMetaInfo->GetProjectionAngle1IEC(),// m_DRTImage1MetaInfo->GetProjectionAngleLPS(), Std_DRT2LPS + ) - + CalcDRTImageOffset( + PanelOffsetIEC1, + this->CalcProjectionAngleLPS( + m_CTMetaInfo->GetPatientOrientation(), + m_DRTGeometryMetaInfo->GetProjectionAngle1IEC() ), + Std_DRT2LPS ) + ); + std::cout<<"CALIBRATION GetOriginLPS "<GetOriginLPS()<GetSize()"<< m_DRTImage1MetaInfo->GetSize() <GetSpacing()"<< m_DRTImage1MetaInfo->GetSpacing() <GetOrigin()"<< m_DRTImage1MetaInfo->GetOrigin() <CalcProjectionAngleLPS( + m_CTMetaInfo->GetPatientOrientation(), + m_DRTGeometryMetaInfo->GetProjectionAngle1IEC() ), + Std_DRT2LPS + ) <GetCOV()"<< m_DRTImage1MetaInfo->GetCOV() <GetOriginLPS()"<< m_DRTImage1MetaInfo->GetOriginLPS() <GetOriginLPS()"<< m_DRTImage1MetaInfo->GetOriginLPS() <GetProjectionAngleLPS()"<GetProjectionAngleLPS()<GetImageDirectionsLPS()"<< m_DRTImage1MetaInfo->GetImageDirectionsLPS() <GetProjectionCenter2()) // ); - vBounds.clear(); - vBounds = m_CTMetaInfo->CalculateRegions( - NominalIsocenter_wZcorrectionLPS//m_DRTImage2MetaInfo->GetProjectionOriginLPS() - ); +// vBounds.clear(); +// vBounds = m_CTMetaInfo->CalculateRegions( +// NominalIsocenter_wZcorrectionLPS//m_DRTImage2MetaInfo->GetProjectionOriginLPS() +// ); // std::cout<<"Bounds2: " // <SetSizeWithBounds( - vBounds.data(), + NULL,//vBounds.data(), m_DRTGeometryMetaInfo->GetDRT2Size(), m_DRTGeometryMetaInfo->GetDRT2Spacing() ); + + ImageType3D::PointType PanelOffsetIEC2; + + PanelOffsetIEC2[0] = -m_DRTGeometryMetaInfo->GetPanel2Offset(); + PanelOffsetIEC2[1] = 0.0; + PanelOffsetIEC2[2] = 0.0; + + m_DRTImage2MetaInfo->SetOriginLPS( CalcDRTImageOrigin( m_DRTImage2MetaInfo->GetOrigin(), @@ -2336,7 +2386,30 @@ void itkImageProcessor::UpdateProjectionGeometryMeta(){ m_DRTGeometryMetaInfo->GetProjectionAngle2IEC()) , //m_DRTGeometryMetaInfo->GetProjectionAngle2IEC(),//m_DRTImage2MetaInfo->GetProjectionAngleLPS(), Std_DRT2LPS + )); + + std::cout<<"m_DRTImage2MetaInfo->GetOriginLPS()"<< m_DRTImage2MetaInfo->GetOriginLPS() <SetOriginLPS( + CalcDRTImageOrigin( + m_DRTImage2MetaInfo->GetOrigin(), + m_DRTImage2MetaInfo->GetCOV(), + NominalIsocenter_wZcorrectionLPS,//m_DRTImage2MetaInfo->GetProjectionOriginLPS(), + this->CalcProjectionAngleLPS( + m_CTMetaInfo->GetPatientOrientation(), + m_DRTGeometryMetaInfo->GetProjectionAngle2IEC()) , + //m_DRTGeometryMetaInfo->GetProjectionAngle2IEC(),//m_DRTImage2MetaInfo->GetProjectionAngleLPS(), + Std_DRT2LPS + ) - + CalcDRTImageOffset( + PanelOffsetIEC2, + this->CalcProjectionAngleLPS( + m_CTMetaInfo->GetPatientOrientation(), + m_DRTGeometryMetaInfo->GetProjectionAngle2IEC() ), + Std_DRT2LPS ) + ); m_DRTImage2MetaInfo->SetImageDirectionsLPS( @@ -2354,8 +2427,15 @@ void itkImageProcessor::UpdateProjectionGeometryMeta(){ // std::cout<<"m_DRTImage2MetaInfo->GetSize()"<< m_DRTImage2MetaInfo->GetSize() <GetSpacing()"<< m_DRTImage2MetaInfo->GetSpacing() <GetOrigin()"<< m_DRTImage2MetaInfo->GetOrigin() <CalcProjectionAngleLPS( + m_CTMetaInfo->GetPatientOrientation(), + m_DRTGeometryMetaInfo->GetProjectionAngle2IEC() ), + Std_DRT2LPS + ) <GetCOV()"<< m_DRTImage2MetaInfo->GetCOV() <GetOriginLPS()"<< m_DRTImage2MetaInfo->GetOriginLPS() <GetOriginLPS() - Offset "<< m_DRTImage2MetaInfo->GetOriginLPS() <GetProjectionAngleLPS()"<GetProjectionAngleLPS()<GetImageDirectionsLPS()"<< m_DRTImage2MetaInfo->GetImageDirectionsLPS() <CalcDRTImageDirections(dAngle, stdDRT2LPS); + + ImageType3D::PointType NewOffset = + DRT2LPS * (m_DRTOffset); + + return + NewOffset; +} + void itkImageProcessor::GetProjectionImages(){ @@ -2997,13 +3094,13 @@ vtkImageData* itkImageProcessor::GetProjection2VTK() - // double* dBounds = toVTK2D2->GetOutput()->GetBounds(); + double* dBounds = toVTK2D2->GetOutput()->GetBounds(); - // std::cout<< "-------- Proj 2 --------" <GetOutput(); diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.h b/reg23Topograms/itkDTRrecon/itkImageProcessor.h index 04adb49..3a1045b 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.h +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.h @@ -106,6 +106,13 @@ public: double GetSCD1(); double GetSCD2(); + /** Panel offsets - panel offsets IEC */ + void SetPanelOffsets(double,double); + /** Get projection angles - Gantry angle LPS + * Only meaningful after a 3D Volume is loaded */ + double GetPanelOffset1(); + double GetPanelOffset2(); + /** Sets the degree of freedom for omptimzation*/ void SetDegreeOfFreedom(tDegreeOfFreedomEnum); tDegreeOfFreedomEnum GetDegreeOfFreedom(); @@ -338,6 +345,13 @@ private: ); + ImageType3D::PointType + CalcDRTImageOffset( + ImageType3D::PointType m_DRTOffset, + double dAngle, + InternalImageType::DirectionType stdDRT2LPS + ); + TransformType::Pointer MapTransformToNewOrigin( ImageType3D::PointType m_COR, From b7bf26b0d2822d0023a4ae21b50393dc6b397fd5 Mon Sep 17 00:00:00 2001 From: Proton local user Date: Sun, 30 Apr 2023 23:33:25 +0200 Subject: [PATCH 28/49] Working on modeling panel offset: - panel offset moved to gSiddon, output image w/ offset are available to reg23 - calibration in settings.ini is a mix of fitting and manual review in SRT - calibration images reviewed (all: short long AP PA) - Test with validation dataset is good. However only for IECS2CT2 w/ translations only. Import offset and hidden transform confuse the situation. Unclear if should be used or not when w/o resildual wrt LT is belo 0.3 - registration dialog is modal.' --- .../itkDTRrecon/itkImageProcessor.cpp | 81 +++++++++++-------- .../itkDTRrecon/itkImageProcessor.h | 12 +-- ...donJacobsRayCastInterpolateImageFunction.h | 5 ++ ...nJacobsRayCastInterpolateImageFunction.hxx | 6 +- 4 files changed, 63 insertions(+), 41 deletions(-) diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp index 8dfcc00..3723431 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp @@ -752,7 +752,7 @@ int itkImageProcessor::fill3DVolumeMeta( // std::cout<< "OriginLPS"<< m_CTMetaInfo->GetOriginLPS() <GetCOV() <GetImportOffset() <GetImportOffset() <GetLPS2IECDirections() <GetSize() <GetSpacing() <SetCenter( m_ProjectionTransformCenter); + + std::cout<GetSCD()); interpolator1->SetThreshold( m_DRTGeometryMetaInfo->GetIntensityThreshold() ); + interpolator1->SetPanelOffset( + m_DRTGeometryMetaInfo->GetPanel1Offset()); + std::cout<< + "00000000000000 IP1 m_DRTGeometryMetaInfo->GetPanel2Offset()" + <GetPanel1Offset()<SetTransform(transform1); interpolator1->Initialize(); @@ -1962,6 +1971,12 @@ void itkImageProcessor::InitializeProjector() m_DRTImage2MetaInfo->GetSCD() ); interpolator2->SetThreshold( m_DRTGeometryMetaInfo->GetIntensityThreshold() ); + interpolator2->SetPanelOffset( + m_DRTGeometryMetaInfo->GetPanel2Offset()); + std::cout<< + "00000000000000 IP2 m_DRTGeometryMetaInfo->GetPanel2Offset()" + <GetPanel2Offset()<SetTransform(transform2); interpolator2->Initialize(); @@ -2261,14 +2276,14 @@ void itkImageProcessor::UpdateProjectionGeometryMeta(){ m_DRTGeometryMetaInfo->GetProjectionAngle1IEC() ), //m_DRTGeometryMetaInfo->GetProjectionAngle1IEC(),// m_DRTImage1MetaInfo->GetProjectionAngleLPS(), Std_DRT2LPS - ) - + ) /*- CalcDRTImageOffset( PanelOffsetIEC1, this->CalcProjectionAngleLPS( m_CTMetaInfo->GetPatientOrientation(), m_DRTGeometryMetaInfo->GetProjectionAngle1IEC() ), Std_DRT2LPS - ) + )*/ ); std::cout<<"CALIBRATION GetOriginLPS "<GetOriginLPS()<GetSize()"<< m_DRTImage1MetaInfo->GetSize() <GetSpacing()"<< m_DRTImage1MetaInfo->GetSpacing() <GetOrigin()"<< m_DRTImage1MetaInfo->GetOrigin() <CalcProjectionAngleLPS( - m_CTMetaInfo->GetPatientOrientation(), - m_DRTGeometryMetaInfo->GetProjectionAngle1IEC() ), - Std_DRT2LPS - ) <CalcProjectionAngleLPS( +// m_CTMetaInfo->GetPatientOrientation(), +// m_DRTGeometryMetaInfo->GetProjectionAngle1IEC() ), +// Std_DRT2LPS +// ) <GetCOV()"<< m_DRTImage1MetaInfo->GetCOV() <GetOriginLPS()"<< m_DRTImage1MetaInfo->GetOriginLPS() <GetOriginLPS()"<< m_DRTImage1MetaInfo->GetOriginLPS() <GetProjectionAngleLPS()"<GetProjectionAngleLPS()<GetImageDirectionsLPS()"<< m_DRTImage1MetaInfo->GetImageDirectionsLPS() <GetProjectionAngle2IEC()) , //m_DRTGeometryMetaInfo->GetProjectionAngle2IEC(),//m_DRTImage2MetaInfo->GetProjectionAngleLPS(), Std_DRT2LPS - ) - + ) /*- CalcDRTImageOffset( PanelOffsetIEC2, this->CalcProjectionAngleLPS( m_CTMetaInfo->GetPatientOrientation(), m_DRTGeometryMetaInfo->GetProjectionAngle2IEC() ), Std_DRT2LPS - ) + )*/ ); @@ -2427,13 +2442,13 @@ void itkImageProcessor::UpdateProjectionGeometryMeta(){ // std::cout<<"m_DRTImage2MetaInfo->GetSize()"<< m_DRTImage2MetaInfo->GetSize() <GetSpacing()"<< m_DRTImage2MetaInfo->GetSpacing() <GetOrigin()"<< m_DRTImage2MetaInfo->GetOrigin() <CalcProjectionAngleLPS( - m_CTMetaInfo->GetPatientOrientation(), - m_DRTGeometryMetaInfo->GetProjectionAngle2IEC() ), - Std_DRT2LPS - ) <CalcProjectionAngleLPS( +// m_CTMetaInfo->GetPatientOrientation(), +// m_DRTGeometryMetaInfo->GetProjectionAngle2IEC() ), +// Std_DRT2LPS +// ) <GetCOV()"<< m_DRTImage2MetaInfo->GetCOV() <GetOriginLPS() - Offset "<< m_DRTImage2MetaInfo->GetOriginLPS() <GetProjectionAngleLPS()"<GetProjectionAngleLPS()<CalcDRTImageDirections(dAngle, stdDRT2LPS); +// itkImageProcessor::InternalImageType::DirectionType DRT2LPS +// = this->CalcDRTImageDirections(dAngle, stdDRT2LPS); - ImageType3D::PointType NewOffset = - DRT2LPS * (m_DRTOffset); +// ImageType3D::PointType NewOffset = +// DRT2LPS * (m_DRTOffset); - return - NewOffset; -} +// return +// NewOffset; +//} void itkImageProcessor::GetProjectionImages(){ diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.h b/reg23Topograms/itkDTRrecon/itkImageProcessor.h index 3a1045b..401aa7e 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.h +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.h @@ -345,12 +345,12 @@ private: ); - ImageType3D::PointType - CalcDRTImageOffset( - ImageType3D::PointType m_DRTOffset, - double dAngle, - InternalImageType::DirectionType stdDRT2LPS - ); +// ImageType3D::PointType +// CalcDRTImageOffset( +// ImageType3D::PointType m_DRTOffset, +// double dAngle, +// InternalImageType::DirectionType stdDRT2LPS +// ); TransformType::Pointer MapTransformToNewOrigin( diff --git a/reg23Topograms/itkDTRrecon/itkgSiddonJacobsRayCastInterpolateImageFunction.h b/reg23Topograms/itkDTRrecon/itkgSiddonJacobsRayCastInterpolateImageFunction.h index 86579e3..6c48c3b 100644 --- a/reg23Topograms/itkDTRrecon/itkgSiddonJacobsRayCastInterpolateImageFunction.h +++ b/reg23Topograms/itkDTRrecon/itkgSiddonJacobsRayCastInterpolateImageFunction.h @@ -182,6 +182,10 @@ public: itkSetMacro(Threshold, double); itkGetMacro(Threshold, double); + /** Set and get the Panel Offset */ + itkSetMacro(PanelOffset, double); + itkGetMacro(PanelOffset, double); + /** Check if a point is inside the image buffer. * \warning For efficiency, no validity checking of * the input image pointer is done. */ @@ -232,6 +236,7 @@ protected: double m_Threshold; double m_FocalPointToIsocenterDistance; // Focal point to isocenter distance double m_ProjectionAngle; // Linac gantry rotation angle in radians + double m_PanelOffset; private: void diff --git a/reg23Topograms/itkDTRrecon/itkgSiddonJacobsRayCastInterpolateImageFunction.hxx b/reg23Topograms/itkDTRrecon/itkgSiddonJacobsRayCastInterpolateImageFunction.hxx index e574b22..ee26045 100644 --- a/reg23Topograms/itkDTRrecon/itkgSiddonJacobsRayCastInterpolateImageFunction.hxx +++ b/reg23Topograms/itkDTRrecon/itkgSiddonJacobsRayCastInterpolateImageFunction.hxx @@ -62,6 +62,7 @@ gSiddonJacobsRayCastInterpolateImageFunction::gSiddonJac m_FocalPointToIsocenterDistance = 1000.; // Focal point to isocenter distance in mm. m_ProjectionAngle = 0.; // Angle in radians betweeen projection central axis and reference axis m_Threshold = 0.; // Intensity threshold, below which is ignored. + m_PanelOffset = 0.; m_SourcePoint[0] = 0.; m_SourcePoint[1] = 0.; @@ -148,14 +149,15 @@ gSiddonJacobsRayCastInterpolateImageFunction::Evaluate(c // m_SourceWorld = m_InverseTransform->TransformPoint(m_SourcePoint); } + PointType PointReq = point; + PointReq[0] += m_PanelOffset; - drrPixelWorld = m_InverseTransform->TransformPoint(point); + drrPixelWorld = m_InverseTransform->TransformPoint(PointReq); PointType SlidingSourcePoint = m_SourcePoint; SlidingSourcePoint[0] = 0.; SlidingSourcePoint[1] = point[1]; SlidingSourcePoint[2] = 0.; - //PointType SourceWorld = m_InverseTransform->TransformPoint(m_SourcePoint); PointType SourceWorld = m_InverseTransform->TransformPoint(SlidingSourcePoint); //std::cout<<"SourceWorld: "< Date: Tue, 2 May 2023 23:46:48 +0200 Subject: [PATCH 29/49] review of projection geometry definition - introduction of CalculateInternalTransformV2 - Each projection maps the isocentric transform (RTIso COR) to its own projection center, including calibration offset. - Direct comparison with previous implementation of CalculateInternalTransform not done... yet. - Results on validation dataset are good. - This change was triggered by rather large errors (ca. 0.8mm) on validation dataset. - Both fakeIso and DCM RTPlan iso have been updated to V2. --- .../itkDTRrecon/itkImageProcessor.cpp | 438 +++++++++++++----- .../itkDTRrecon/itkImageProcessor.h | 11 + 2 files changed, 322 insertions(+), 127 deletions(-) diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp index 3723431..15a3000 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp @@ -1362,6 +1362,82 @@ void itkImageProcessor::CalculateExternalUserTransform(TransformType::Pointer tr m_TransformMetaInfo->SetUserRotations(LPStoIEC_Directions * rotationUser); } +itkImageProcessor::TransformType::Pointer +itkImageProcessor::CalculateInternalTransformV2( + ImageType3D::PointType m_TranslationOffset, //IEC + ImageType3D::PointType m_RotationOffset, //IEC + ImageType3D::PointType m_TranslationUser, //IEC + ImageType3D::PointType m_RotationUser, //IEC + ImageType3D::PointType m_CalibratedProjectionCenter, //LPS + ImageType3D::PointType m_RTIsocenter, //LPS + InternalImageType::DirectionType m_IECtoLPSDirections + ) +{ + + //Convert all inputs into LPS + + ImageType3D::PointType m_TOffsetLPS = + m_IECtoLPSDirections * m_TranslationOffset; + + ImageType3D::PointType m_ROffsetLPS = + m_IECtoLPSDirections * m_RotationOffset; + + ImageType3D::PointType m_TUserLPS = + m_IECtoLPSDirections * m_TranslationUser; + + ImageType3D::PointType m_RUserLPS = + m_IECtoLPSDirections * m_RotationUser; + + +// TransformType::Pointer IsocetricTransform = TransformType::New(); +// IsocetricTransform->SetComputeZYX(true); +// IsocetricTransform->SetIdentity(); + + TransformType::OutputVectorType translation; + translation[0] = m_TOffsetLPS[0] + m_TUserLPS[0]; + translation[1] = m_TOffsetLPS[1] + m_TUserLPS[1]; + translation[2] = m_TOffsetLPS[2] + m_TUserLPS[2]; + +// IsocetricTransform->SetTranslation(translation); + + const double dtr = (atan(1.0) * 4.0) / 180.0; +// IsocetricTransform->SetRotation( +// dtr * m_ROffsetLPS[0] + dtr * m_RUserLPS[0], +// dtr * m_ROffsetLPS[1] + dtr * m_RUserLPS[1], +// dtr * m_ROffsetLPS[2] + dtr * m_RUserLPS[2]); + + TransformType::OutputVectorType rotations; + rotations[0] = m_ROffsetLPS[0] + m_RUserLPS[0]; + rotations[1] = m_ROffsetLPS[1] + m_RUserLPS[1]; + rotations[2] = m_ROffsetLPS[2] + m_RUserLPS[2]; + + +// ImageType3D::PointType m_TransformOrigin; +// m_TransformOrigin.Fill(0.); +// IsocetricTransform->SetCenter( +// m_TransformOrigin ); + +// IsocetricTransform->Print(std::cout); + + // Map offset to the projection center + TransformType::Pointer m_outputTransform = + MapTransformToNewOrigin ( + m_CalibratedProjectionCenter - m_RTIsocenter, + translation, + rotations + ); + + std::cout<GetTranslation()<GetCenter()<SetCenter(m_CalibratedProjectionCenter); + std::cout<GetTranslation()<GetCenter()<GetImportOffset(), IECtoLPS_Directions ); +// CurrTransform = +// CalculateInternalTransform( +// ZeroPoint , +// m_DRTGeometryMetaInfo->GetIECS2IECScannerR(), +// m_TransformMetaInfo->GetTranslations(), +// m_TransformMetaInfo->GetRotations(), +// m_CTMetaInfo->GetProjectionOriginLPS( +// m_DRTGeometryMetaInfo->GetProjectionCenter() +// ), +// m_RTMetaInfo->GetIsocenterLPS() - m_CTMetaInfo->GetImportOffset(), +// m_CTMetaInfo->GetImportOffset(), +// IECtoLPS_Directions +// ); } @@ -1562,6 +1651,9 @@ void itkImageProcessor::InitializeRegistration( ); transform1->SetCenter( m_DRTImage1MetaInfo->GetProjectionOriginLPSZero() ); +// transform1 ->SetCenter( +// m_CTMetaInfo->GetProjectionOriginLPSZero( +// m_DRTGeometryMetaInfo->GetProjectionCenter())); /********* END OF CALCULATE INTERNAL TRANSFORM FOR PROJ1 *********/ @@ -1602,6 +1694,19 @@ void itkImageProcessor::InitializeRegistration( m_CTMetaInfo->GetImportOffset(), IECtoLPS_Directions ); +// CurrTransform = +// CalculateInternalTransform( +// ZeroPoint , +// m_DRTGeometryMetaInfo->GetIECS2IECScannerR(), +// m_TransformMetaInfo->GetTranslations(), +// m_TransformMetaInfo->GetRotations(), +// m_CTMetaInfo->GetProjectionOriginLPS( +// m_DRTGeometryMetaInfo->GetProjectionCenter() +// ), +// m_RTMetaInfo->GetIsocenterLPS() - m_CTMetaInfo->GetImportOffset(), +// m_CTMetaInfo->GetImportOffset(), +// IECtoLPS_Directions +// ); } transform2->SetComputeZYX(true); @@ -1615,6 +1720,9 @@ void itkImageProcessor::InitializeRegistration( ); transform2->SetCenter( m_DRTImage2MetaInfo->GetProjectionOriginLPSZero() ); +// transform2 ->SetCenter( +// m_CTMetaInfo->GetProjectionOriginLPSZero( +// m_DRTGeometryMetaInfo->GetProjectionCenter())); /********* END OF CALCULATE INTERNAL TRANSFORM FOR PROJ1 *********/ @@ -1844,49 +1952,72 @@ void itkImageProcessor::InitializeProjector() // m_DRTGeometryMetaInfo->GetProjectionCenter1()); - CurrTransform = - CalculateInternalTransform( - ZeroPoint, - ZeroPoint, - m_TransformMetaInfo->GetTranslations(), - m_TransformMetaInfo->GetRotations(), - m_DRTImage1MetaInfo->GetProjectionOriginLPS(), - pFakeIsoLPS, - ZeroPoint, - IECtoLPS_Directions - ); +// CurrTransform = +// CalculateInternalTransform( +// ZeroPoint, +// ZeroPoint, +// m_TransformMetaInfo->GetTranslations(), +// m_TransformMetaInfo->GetRotations(), +// m_DRTImage1MetaInfo->GetProjectionOriginLPS(), +// pFakeIsoLPS, +// ZeroPoint, +// IECtoLPS_Directions +// ); + + CurrTransform = CalculateInternalTransformV2( + ZeroPoint , + ZeroPoint , + m_TransformMetaInfo->GetTranslations(), + m_TransformMetaInfo->GetRotations(), + m_DRTImage2MetaInfo->GetProjectionOriginLPSZero(), + m_DRTImage2MetaInfo->GetProjectionOriginLPS(), + IECtoLPS_Directions + ); } else { - CurrTransform = - CalculateInternalTransform( +// CurrTransform = +// CalculateInternalTransform( +// ZeroPoint , +// m_DRTGeometryMetaInfo->GetIECS2IECScannerR(), +// m_TransformMetaInfo->GetTranslations(), +// m_TransformMetaInfo->GetRotations(), +// m_DRTImage1MetaInfo->GetProjectionOriginLPS(), +// m_RTMetaInfo->GetIsocenterLPS() - m_CTMetaInfo->GetImportOffset(), +// m_CTMetaInfo->GetImportOffset(), +// IECtoLPS_Directions +// ); + + CurrTransform = CalculateInternalTransformV2( ZeroPoint , m_DRTGeometryMetaInfo->GetIECS2IECScannerR(), m_TransformMetaInfo->GetTranslations(), m_TransformMetaInfo->GetRotations(), - m_DRTImage1MetaInfo->GetProjectionOriginLPS(), - m_RTMetaInfo->GetIsocenterLPS() - m_CTMetaInfo->GetImportOffset(), - m_CTMetaInfo->GetImportOffset(), + m_DRTImage1MetaInfo->GetProjectionOriginLPSZero(), + m_RTMetaInfo->GetIsocenterLPS() - m_CTMetaInfo->GetOriginLPS(), IECtoLPS_Directions ); } - transform1->SetComputeZYX(true); - transform1->SetIdentity(); +// transform1->SetComputeZYX(true); +// transform1->SetIdentity(); - transform1->SetTranslation( - CurrTransform->GetTranslation()); - transform1->SetRotation( - CurrTransform->GetAngleX(), - CurrTransform->GetAngleY(), - CurrTransform->GetAngleZ() - ); +// transform1->SetTranslation( +// CurrTransform->GetTranslation()); +// transform1->SetRotation( +// CurrTransform->GetAngleX(), +// CurrTransform->GetAngleY(), +// CurrTransform->GetAngleZ() +// ); - transform1->SetCenter( - m_DRTImage1MetaInfo->GetProjectionOriginLPSZero() ); -// transform1->Print(std::cout); +// transform1->SetCenter( +// m_DRTImage1MetaInfo->GetProjectionOriginLPSZero() ); + + + transform1 = CurrTransform; + // 2D Image 1 interpolator1->SetProjectionAngle( @@ -1920,48 +2051,70 @@ void itkImageProcessor::InitializeProjector() - CurrTransform = - CalculateInternalTransform( - ZeroPoint, - ZeroPoint, - m_TransformMetaInfo->GetTranslations(), - m_TransformMetaInfo->GetRotations(), - m_DRTImage2MetaInfo->GetProjectionOriginLPS(), - pFakeIsoLPS, - ZeroPoint, - IECtoLPS_Directions - ); +// CurrTransform = +// CalculateInternalTransform( +// ZeroPoint, +// ZeroPoint, +// m_TransformMetaInfo->GetTranslations(), +// m_TransformMetaInfo->GetRotations(), +// m_DRTImage2MetaInfo->GetProjectionOriginLPS(), +// pFakeIsoLPS, +// ZeroPoint, +// IECtoLPS_Directions +// ); + CurrTransform = CalculateInternalTransformV2( + ZeroPoint , + ZeroPoint , + m_TransformMetaInfo->GetTranslations(), + m_TransformMetaInfo->GetRotations(), + m_DRTImage2MetaInfo->GetProjectionOriginLPSZero(), + m_DRTImage2MetaInfo->GetProjectionOriginLPS(), + IECtoLPS_Directions + ); } else { - CurrTransform = - CalculateInternalTransform( +// CurrTransform = +// CalculateInternalTransform( +// ZeroPoint , +// m_DRTGeometryMetaInfo->GetIECS2IECScannerR(), +// m_TransformMetaInfo->GetTranslations(), +// m_TransformMetaInfo->GetRotations(), +// m_DRTImage2MetaInfo->GetProjectionOriginLPS(), +// m_RTMetaInfo->GetIsocenterLPS() - m_CTMetaInfo->GetImportOffset(), +// m_CTMetaInfo->GetImportOffset(), +// IECtoLPS_Directions +// ); + + CurrTransform = CalculateInternalTransformV2( ZeroPoint , m_DRTGeometryMetaInfo->GetIECS2IECScannerR(), m_TransformMetaInfo->GetTranslations(), m_TransformMetaInfo->GetRotations(), - m_DRTImage2MetaInfo->GetProjectionOriginLPS(), - m_RTMetaInfo->GetIsocenterLPS() - m_CTMetaInfo->GetImportOffset(), - m_CTMetaInfo->GetImportOffset(), + m_DRTImage2MetaInfo->GetProjectionOriginLPSZero(), + m_RTMetaInfo->GetIsocenterLPS() - m_CTMetaInfo->GetOriginLPS(), IECtoLPS_Directions ); - } +transform2 = CurrTransform; + +// transform2->SetComputeZYX(true); +// transform2->SetIdentity(); + +// transform2->SetTranslation( +// CurrTransform->GetTranslation()); +// transform2->SetRotation( +// CurrTransform->GetAngleX(), +// CurrTransform->GetAngleY(), +// CurrTransform->GetAngleZ() +// ); - transform2->SetComputeZYX(true); - transform2->SetIdentity(); +// transform2->SetCenter( +// m_DRTImage2MetaInfo->GetProjectionOriginLPSZero() ); +// transform2 ->SetCenter( +// m_CTMetaInfo->GetProjectionOriginLPSZero( +// m_DRTGeometryMetaInfo->GetProjectionCenter())); - transform2->SetTranslation( - CurrTransform->GetTranslation()); - transform2->SetRotation( - CurrTransform->GetAngleX(), - CurrTransform->GetAngleY(), - CurrTransform->GetAngleZ() - ); - - - transform2->SetCenter( - m_DRTImage2MetaInfo->GetProjectionOriginLPSZero() ); //transform2->Print(std::cout); // 2D Image 2 @@ -2193,11 +2346,11 @@ void itkImageProcessor::UpdateProjectionGeometryMeta(){ IsocenterOffsetLPS = m_CTMetaInfo->ConvertIECPointToLPSPoint( m_DRTGeometryMetaInfo->GetProjectionCenterOffset1()); - std::cout<< "///////////////// PGEOM META BEG ///////////////" <GetProjectionCenter() <GetProjectionCenter() <SetProjectionAngleLPS( this->CalcProjectionAngleLPS( @@ -2276,15 +2429,7 @@ void itkImageProcessor::UpdateProjectionGeometryMeta(){ m_DRTGeometryMetaInfo->GetProjectionAngle1IEC() ), //m_DRTGeometryMetaInfo->GetProjectionAngle1IEC(),// m_DRTImage1MetaInfo->GetProjectionAngleLPS(), Std_DRT2LPS - ) /*- - CalcDRTImageOffset( - PanelOffsetIEC1, - this->CalcProjectionAngleLPS( - m_CTMetaInfo->GetPatientOrientation(), - m_DRTGeometryMetaInfo->GetProjectionAngle1IEC() ), - Std_DRT2LPS - )*/ - + ) ); std::cout<<"CALIBRATION GetOriginLPS "<GetOriginLPS()<GetTranslations(), m_TransformMetaInfo->GetRotations(), + m_DRTImage1MetaInfo->GetProjectionOriginLPSZero(), m_DRTImage1MetaInfo->GetProjectionOriginLPS(), - pFakeIsoLPS, - ZeroPoint, IECtoLPS_Directions ); } else { - CurrTransform = - CalculateInternalTransform( - ZeroPoint , - m_DRTGeometryMetaInfo->GetIECS2IECScannerR(), - m_TransformMetaInfo->GetTranslations(), - m_TransformMetaInfo->GetRotations(), - m_DRTImage1MetaInfo->GetProjectionOriginLPS(), - m_RTMetaInfo->GetIsocenterLPS() - m_CTMetaInfo->GetImportOffset(), - m_CTMetaInfo->GetImportOffset(), - IECtoLPS_Directions - ); - } + // CurrTransform = + // CalculateInternalTransform( + // ZeroPoint , + // m_DRTGeometryMetaInfo->GetIECS2IECScannerR(), + // m_TransformMetaInfo->GetTranslations(), + // m_TransformMetaInfo->GetRotations(), + // m_DRTImage1MetaInfo->GetProjectionOriginLPS(), + // m_RTMetaInfo->GetIsocenterLPS() - m_CTMetaInfo->GetImportOffset(), + // m_CTMetaInfo->GetImportOffset(), + // IECtoLPS_Directions + // ); - std::cout<<"Curr GetCenter"<GetCenter()<GetIsocenterLPS()<GetIECS2IECScannerR(), + m_TransformMetaInfo->GetTranslations(), + m_TransformMetaInfo->GetRotations(), + m_DRTImage1MetaInfo->GetProjectionOriginLPSZero(), + m_RTMetaInfo->GetIsocenterLPS() - m_CTMetaInfo->GetOriginLPS(), + IECtoLPS_Directions + ); - transform1->SetComputeZYX(true); - transform1->SetIdentity(); + std::cout<GetProjectionOriginLPSZero()<GetIsocenterLPS() <GetOriginLPS() <GetIsocenterLPS() - m_CTMetaInfo->GetOriginLPS() <SetTranslation( - CurrTransform->GetTranslation()); - transform1->SetRotation( - CurrTransform->GetAngleX(), - CurrTransform->GetAngleY(), - CurrTransform->GetAngleZ() - ); + } + + + + + // transform1->SetComputeZYX(true); + // transform1->SetIdentity(); + + // transform1->SetTranslation( + // CurrTransform->GetTranslation()); + // transform1->SetRotation( + // CurrTransform->GetAngleX(), + // CurrTransform->GetAngleY(), + // CurrTransform->GetAngleZ() + // ); + + + // transform1->SetCenter( + // m_DRTImage1MetaInfo->GetProjectionOriginLPSZero() ); + + + transform1 = CurrTransform; // std::cout<< "itkImageProcessor::GetProjectionImages" <SetCenter( - m_DRTImage1MetaInfo->GetProjectionOriginLPSZero()); +// transform1 ->SetCenter( +// m_DRTImage1MetaInfo->GetProjectionOriginLPSZero()); +// transform1 ->SetCenter( +// m_CTMetaInfo->GetProjectionOriginLPSZero( +// m_DRTGeometryMetaInfo->GetProjectionCenter())); + + + std::cout<<"----> transform1 GetCenter"<GetCenter()<GetProjectionAngleLPS() <GetTranslations(), m_TransformMetaInfo->GetRotations(), + m_DRTImage2MetaInfo->GetProjectionOriginLPSZero(), m_DRTImage2MetaInfo->GetProjectionOriginLPS(), - pFakeIsoLPS, - ZeroPoint, + IECtoLPS_Directions ); @@ -2639,37 +2812,48 @@ void itkImageProcessor::GetProjectionImages(){ } else { - CurrTransform = - CalculateInternalTransform( +// CurrTransform = +// CalculateInternalTransform( +// ZeroPoint , +// m_DRTGeometryMetaInfo->GetIECS2IECScannerR(), +// m_TransformMetaInfo->GetTranslations(), +// m_TransformMetaInfo->GetRotations(), +// m_DRTImage2MetaInfo->GetProjectionOriginLPS(), +// m_RTMetaInfo->GetIsocenterLPS() - m_CTMetaInfo->GetImportOffset(), +// m_CTMetaInfo->GetImportOffset(), +// IECtoLPS_Directions +// ); + + CurrTransform = CalculateInternalTransformV2( ZeroPoint , m_DRTGeometryMetaInfo->GetIECS2IECScannerR(), m_TransformMetaInfo->GetTranslations(), m_TransformMetaInfo->GetRotations(), - m_DRTImage2MetaInfo->GetProjectionOriginLPS(), - m_RTMetaInfo->GetIsocenterLPS() - m_CTMetaInfo->GetImportOffset(), - m_CTMetaInfo->GetImportOffset(), + m_DRTImage2MetaInfo->GetProjectionOriginLPSZero(), + m_RTMetaInfo->GetIsocenterLPS() - m_CTMetaInfo->GetOriginLPS(), IECtoLPS_Directions ); - } +transform2 = CurrTransform; + +// transform2->SetComputeZYX(true); +// transform2->SetIdentity(); + +// transform2->SetTranslation( +// CurrTransform->GetTranslation()); +// transform2->SetRotation( +// CurrTransform->GetAngleX(), +// CurrTransform->GetAngleY(), +// CurrTransform->GetAngleZ() +// ); - transform2->SetComputeZYX(true); - transform2->SetIdentity(); - - transform2->SetTranslation( - CurrTransform->GetTranslation()); - transform2->SetRotation( - CurrTransform->GetAngleX(), - CurrTransform->GetAngleY(), - CurrTransform->GetAngleZ() - ); - - - transform2 ->SetCenter( - m_DRTImage2MetaInfo->GetProjectionOriginLPSZero()); - +// transform2 ->SetCenter( +// m_DRTImage2MetaInfo->GetProjectionOriginLPSZero()); +// transform2 ->SetCenter( +// m_CTMetaInfo->GetProjectionOriginLPSZero( +// m_DRTGeometryMetaInfo->GetProjectionCenter())); //transform2 ->Print(std::cout); diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.h b/reg23Topograms/itkDTRrecon/itkImageProcessor.h index 401aa7e..ec96d35 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.h +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.h @@ -280,6 +280,17 @@ private: InternalImageType::DirectionType m_IECtoLPSDirections ); + TransformType::Pointer + CalculateInternalTransformV2( + ImageType3D::PointType m_TranslationOffset, + ImageType3D::PointType m_RotationOffset, + ImageType3D::PointType m_TranslationUser, + ImageType3D::PointType m_RotationUser, + ImageType3D::PointType m_CalibratedProjectionCenter, + ImageType3D::PointType m_RTIsocenter, + InternalImageType::DirectionType m_IECtoLPSDirections + ); + TransformType::Pointer transform1, From 9b5921dd60eb3cae09378bae7eee66856789b3ce Mon Sep 17 00:00:00 2001 From: Proton local user Date: Wed, 3 May 2023 14:41:52 +0200 Subject: [PATCH 30/49] autoReg working --- .../itkDTRrecon/itkImageProcessor.cpp | 537 +++++++++--------- .../itkDTRrecon/itkImageProcessor.h | 44 +- 2 files changed, 290 insertions(+), 291 deletions(-) diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp index 15a3000..6ce2871 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp @@ -1362,6 +1362,7 @@ void itkImageProcessor::CalculateExternalUserTransform(TransformType::Pointer tr m_TransformMetaInfo->SetUserRotations(LPStoIEC_Directions * rotationUser); } + itkImageProcessor::TransformType::Pointer itkImageProcessor::CalculateInternalTransformV2( ImageType3D::PointType m_TranslationOffset, //IEC @@ -1388,37 +1389,16 @@ itkImageProcessor::CalculateInternalTransformV2( ImageType3D::PointType m_RUserLPS = m_IECtoLPSDirections * m_RotationUser; - -// TransformType::Pointer IsocetricTransform = TransformType::New(); -// IsocetricTransform->SetComputeZYX(true); -// IsocetricTransform->SetIdentity(); - TransformType::OutputVectorType translation; translation[0] = m_TOffsetLPS[0] + m_TUserLPS[0]; translation[1] = m_TOffsetLPS[1] + m_TUserLPS[1]; translation[2] = m_TOffsetLPS[2] + m_TUserLPS[2]; -// IsocetricTransform->SetTranslation(translation); - - const double dtr = (atan(1.0) * 4.0) / 180.0; -// IsocetricTransform->SetRotation( -// dtr * m_ROffsetLPS[0] + dtr * m_RUserLPS[0], -// dtr * m_ROffsetLPS[1] + dtr * m_RUserLPS[1], -// dtr * m_ROffsetLPS[2] + dtr * m_RUserLPS[2]); - TransformType::OutputVectorType rotations; rotations[0] = m_ROffsetLPS[0] + m_RUserLPS[0]; rotations[1] = m_ROffsetLPS[1] + m_RUserLPS[1]; rotations[2] = m_ROffsetLPS[2] + m_RUserLPS[2]; - -// ImageType3D::PointType m_TransformOrigin; -// m_TransformOrigin.Fill(0.); -// IsocetricTransform->SetCenter( -// m_TransformOrigin ); - -// IsocetricTransform->Print(std::cout); - // Map offset to the projection center TransformType::Pointer m_outputTransform = MapTransformToNewOrigin ( @@ -1427,11 +1407,7 @@ itkImageProcessor::CalculateInternalTransformV2( rotations ); - std::cout<GetTranslation()<GetCenter()<SetCenter(m_CalibratedProjectionCenter); - std::cout<GetTranslation()<GetCenter()<SetComputeZYX(true); - m_OutputTransform ->SetIdentity(); +// TransformType::Pointer m_OutputTransform = +// TransformType::New(); +// m_OutputTransform ->SetComputeZYX(true); +// m_OutputTransform ->SetIdentity(); - m_OutputTransform->SetTranslation( - m_OffsetTransform->GetTranslation() + - m_UserTransform->GetTranslation() - ); +// m_OutputTransform->SetTranslation( +// m_OffsetTransform->GetTranslation() + +// m_UserTransform->GetTranslation() +// ); - m_OutputTransform->SetRotation( - m_OffsetTransform->GetAngleX() + - m_UserTransform->GetAngleX(), - m_OffsetTransform->GetAngleY() + - m_UserTransform->GetAngleY(), - m_OffsetTransform->GetAngleZ() + - m_UserTransform->GetAngleZ() - ); +// m_OutputTransform->SetRotation( +// m_OffsetTransform->GetAngleX() + +// m_UserTransform->GetAngleX(), +// m_OffsetTransform->GetAngleY() + +// m_UserTransform->GetAngleY(), +// m_OffsetTransform->GetAngleZ() + +// m_UserTransform->GetAngleZ() +// ); - m_OutputTransform->SetCenter( - m_ProjectionTransformCenter); +// m_OutputTransform->SetCenter( +// m_ProjectionTransformCenter); - //std::cout<GetProjectionOriginLPS( // m_DRTGeometryMetaInfo->GetProjectionCenter1()); +// CurrTransform = +// CalculateInternalTransform( +// ZeroPoint, +// ZeroPoint, +// m_TransformMetaInfo->GetTranslations(), +// m_TransformMetaInfo->GetRotations(), +// m_DRTImage1MetaInfo->GetProjectionOriginLPS(), +// pFakeIsoLPS, +// ZeroPoint, +// IECtoLPS_Directions +// ); CurrTransform = - CalculateInternalTransform( + CalculateInternalTransformV2( ZeroPoint, ZeroPoint, m_TransformMetaInfo->GetTranslations(), m_TransformMetaInfo->GetRotations(), + m_DRTImage1MetaInfo->GetProjectionOriginLPSZero(), m_DRTImage1MetaInfo->GetProjectionOriginLPS(), - pFakeIsoLPS, - ZeroPoint, IECtoLPS_Directions ); + } else { - CurrTransform = - CalculateInternalTransform( - ZeroPoint , - m_DRTGeometryMetaInfo->GetIECS2IECScannerR(), - m_TransformMetaInfo->GetTranslations(), - m_TransformMetaInfo->GetRotations(), - m_DRTImage1MetaInfo->GetProjectionOriginLPS(), - m_RTMetaInfo->GetIsocenterLPS() - m_CTMetaInfo->GetImportOffset(), - m_CTMetaInfo->GetImportOffset(), - IECtoLPS_Directions - ); // CurrTransform = // CalculateInternalTransform( // ZeroPoint , // m_DRTGeometryMetaInfo->GetIECS2IECScannerR(), // m_TransformMetaInfo->GetTranslations(), // m_TransformMetaInfo->GetRotations(), -// m_CTMetaInfo->GetProjectionOriginLPS( -// m_DRTGeometryMetaInfo->GetProjectionCenter() -// ), +// m_DRTImage1MetaInfo->GetProjectionOriginLPS(), // m_RTMetaInfo->GetIsocenterLPS() - m_CTMetaInfo->GetImportOffset(), // m_CTMetaInfo->GetImportOffset(), // IECtoLPS_Directions // ); + CurrTransform = CalculateInternalTransformV2( + ZeroPoint , + m_DRTGeometryMetaInfo->GetIECS2IECScannerR(), + m_TransformMetaInfo->GetTranslations(), + m_TransformMetaInfo->GetRotations(), + m_DRTImage1MetaInfo->GetProjectionOriginLPSZero(), + m_RTMetaInfo->GetIsocenterLPS() - m_CTMetaInfo->GetOriginLPS(), + IECtoLPS_Directions + ); + } @@ -1651,9 +1635,6 @@ void itkImageProcessor::InitializeRegistration( ); transform1->SetCenter( m_DRTImage1MetaInfo->GetProjectionOriginLPSZero() ); -// transform1 ->SetCenter( -// m_CTMetaInfo->GetProjectionOriginLPSZero( -// m_DRTGeometryMetaInfo->GetProjectionCenter())); /********* END OF CALCULATE INTERNAL TRANSFORM FOR PROJ1 *********/ @@ -1670,43 +1651,51 @@ void itkImageProcessor::InitializeRegistration( +// CurrTransform = +// CalculateInternalTransform( +// ZeroPoint, +// ZeroPoint, +// m_TransformMetaInfo->GetTranslations(), +// m_TransformMetaInfo->GetRotations(), +// m_DRTImage2MetaInfo->GetProjectionOriginLPS(), +// pFakeIsoLPS, +// ZeroPoint, +// IECtoLPS_Directions +// ); CurrTransform = - CalculateInternalTransform( - ZeroPoint, - ZeroPoint, - m_TransformMetaInfo->GetTranslations(), - m_TransformMetaInfo->GetRotations(), - m_DRTImage2MetaInfo->GetProjectionOriginLPS(), - pFakeIsoLPS, - ZeroPoint, - IECtoLPS_Directions - ); + CalculateInternalTransformV2( + ZeroPoint, + ZeroPoint, + m_TransformMetaInfo->GetTranslations(), + m_TransformMetaInfo->GetRotations(), + m_DRTImage2MetaInfo->GetProjectionOriginLPSZero(), + m_DRTImage2MetaInfo->GetProjectionOriginLPS(), + IECtoLPS_Directions + ); + } else { - CurrTransform = - CalculateInternalTransform( - ZeroPoint , - m_DRTGeometryMetaInfo->GetIECS2IECScannerR(), - m_TransformMetaInfo->GetTranslations(), - m_TransformMetaInfo->GetRotations(), - m_DRTImage2MetaInfo->GetProjectionOriginLPS(), - m_RTMetaInfo->GetIsocenterLPS() - m_CTMetaInfo->GetImportOffset(), - m_CTMetaInfo->GetImportOffset(), - IECtoLPS_Directions - ); // CurrTransform = // CalculateInternalTransform( // ZeroPoint , // m_DRTGeometryMetaInfo->GetIECS2IECScannerR(), // m_TransformMetaInfo->GetTranslations(), // m_TransformMetaInfo->GetRotations(), -// m_CTMetaInfo->GetProjectionOriginLPS( -// m_DRTGeometryMetaInfo->GetProjectionCenter() -// ), +// m_DRTImage2MetaInfo->GetProjectionOriginLPS(), // m_RTMetaInfo->GetIsocenterLPS() - m_CTMetaInfo->GetImportOffset(), // m_CTMetaInfo->GetImportOffset(), // IECtoLPS_Directions // ); + CurrTransform = CalculateInternalTransformV2( + ZeroPoint, + m_DRTGeometryMetaInfo->GetIECS2IECScannerR(), + m_TransformMetaInfo->GetTranslations(), + m_TransformMetaInfo->GetRotations(), + m_DRTImage2MetaInfo->GetProjectionOriginLPSZero(), + m_RTMetaInfo->GetIsocenterLPS() - m_CTMetaInfo->GetOriginLPS(), + IECtoLPS_Directions + ); + } transform2->SetComputeZYX(true); @@ -1720,9 +1709,6 @@ void itkImageProcessor::InitializeRegistration( ); transform2->SetCenter( m_DRTImage2MetaInfo->GetProjectionOriginLPSZero() ); -// transform2 ->SetCenter( -// m_CTMetaInfo->GetProjectionOriginLPSZero( -// m_DRTGeometryMetaInfo->GetProjectionCenter())); /********* END OF CALCULATE INTERNAL TRANSFORM FOR PROJ1 *********/ @@ -1963,16 +1949,17 @@ void itkImageProcessor::InitializeProjector() // ZeroPoint, // IECtoLPS_Directions // ); - CurrTransform = CalculateInternalTransformV2( - ZeroPoint , - ZeroPoint , - m_TransformMetaInfo->GetTranslations(), - m_TransformMetaInfo->GetRotations(), - m_DRTImage2MetaInfo->GetProjectionOriginLPSZero(), - m_DRTImage2MetaInfo->GetProjectionOriginLPS(), - IECtoLPS_Directions - ); + ZeroPoint , + ZeroPoint , + m_TransformMetaInfo->GetTranslations(), + m_TransformMetaInfo->GetRotations(), + m_DRTImage1MetaInfo->GetProjectionOriginLPSZero(), + m_DRTImage1MetaInfo->GetProjectionOriginLPS(), + IECtoLPS_Directions + ); + + } else { // CurrTransform = @@ -1997,27 +1984,25 @@ void itkImageProcessor::InitializeProjector() IECtoLPS_Directions ); + } -// transform1->SetComputeZYX(true); -// transform1->SetIdentity(); + transform1->SetComputeZYX(true); + transform1->SetIdentity(); -// transform1->SetTranslation( -// CurrTransform->GetTranslation()); -// transform1->SetRotation( -// CurrTransform->GetAngleX(), -// CurrTransform->GetAngleY(), -// CurrTransform->GetAngleZ() -// ); + transform1->SetTranslation( + CurrTransform->GetTranslation()); + transform1->SetRotation( + CurrTransform->GetAngleX(), + CurrTransform->GetAngleY(), + CurrTransform->GetAngleZ() + ); -// transform1->SetCenter( -// m_DRTImage1MetaInfo->GetProjectionOriginLPSZero() ); - - - transform1 = CurrTransform; - + transform1->SetCenter( + m_DRTImage1MetaInfo->GetProjectionOriginLPSZero() ); +// transform1->Print(std::cout); // 2D Image 1 interpolator1->SetProjectionAngle( @@ -2062,15 +2047,18 @@ void itkImageProcessor::InitializeProjector() // ZeroPoint, // IECtoLPS_Directions // ); - CurrTransform = CalculateInternalTransformV2( - ZeroPoint , - ZeroPoint , - m_TransformMetaInfo->GetTranslations(), - m_TransformMetaInfo->GetRotations(), - m_DRTImage2MetaInfo->GetProjectionOriginLPSZero(), - m_DRTImage2MetaInfo->GetProjectionOriginLPS(), - IECtoLPS_Directions - ); + CurrTransform = + CalculateInternalTransformV2( + ZeroPoint, + ZeroPoint, + m_TransformMetaInfo->GetTranslations(), + m_TransformMetaInfo->GetRotations(), + m_DRTImage2MetaInfo->GetProjectionOriginLPSZero(), + m_DRTImage2MetaInfo->GetProjectionOriginLPS(), + IECtoLPS_Directions + ); + + } else { // CurrTransform = @@ -2084,9 +2072,8 @@ void itkImageProcessor::InitializeProjector() // m_CTMetaInfo->GetImportOffset(), // IECtoLPS_Directions // ); - CurrTransform = CalculateInternalTransformV2( - ZeroPoint , + ZeroPoint, m_DRTGeometryMetaInfo->GetIECS2IECScannerR(), m_TransformMetaInfo->GetTranslations(), m_TransformMetaInfo->GetRotations(), @@ -2094,27 +2081,25 @@ void itkImageProcessor::InitializeProjector() m_RTMetaInfo->GetIsocenterLPS() - m_CTMetaInfo->GetOriginLPS(), IECtoLPS_Directions ); + + } -transform2 = CurrTransform; - -// transform2->SetComputeZYX(true); -// transform2->SetIdentity(); - -// transform2->SetTranslation( -// CurrTransform->GetTranslation()); -// transform2->SetRotation( -// CurrTransform->GetAngleX(), -// CurrTransform->GetAngleY(), -// CurrTransform->GetAngleZ() -// ); -// transform2->SetCenter( -// m_DRTImage2MetaInfo->GetProjectionOriginLPSZero() ); -// transform2 ->SetCenter( -// m_CTMetaInfo->GetProjectionOriginLPSZero( -// m_DRTGeometryMetaInfo->GetProjectionCenter())); + transform2->SetComputeZYX(true); + transform2->SetIdentity(); + transform2->SetTranslation( + CurrTransform->GetTranslation()); + transform2->SetRotation( + CurrTransform->GetAngleX(), + CurrTransform->GetAngleY(), + CurrTransform->GetAngleZ() + ); + + + transform2->SetCenter( + m_DRTImage2MetaInfo->GetProjectionOriginLPSZero() ); //transform2->Print(std::cout); // 2D Image 2 @@ -2346,11 +2331,11 @@ void itkImageProcessor::UpdateProjectionGeometryMeta(){ IsocenterOffsetLPS = m_CTMetaInfo->ConvertIECPointToLPSPoint( m_DRTGeometryMetaInfo->GetProjectionCenterOffset1()); -// std::cout<< "///////////////// PGEOM META BEG ///////////////" <GetProjectionCenter() <GetProjectionCenter() <SetProjectionAngleLPS( this->CalcProjectionAngleLPS( @@ -2429,7 +2414,15 @@ void itkImageProcessor::UpdateProjectionGeometryMeta(){ m_DRTGeometryMetaInfo->GetProjectionAngle1IEC() ), //m_DRTGeometryMetaInfo->GetProjectionAngle1IEC(),// m_DRTImage1MetaInfo->GetProjectionAngleLPS(), Std_DRT2LPS - ) + ) /*- + CalcDRTImageOffset( + PanelOffsetIEC1, + this->CalcProjectionAngleLPS( + m_CTMetaInfo->GetPatientOrientation(), + m_DRTGeometryMetaInfo->GetProjectionAngle1IEC() ), + Std_DRT2LPS + )*/ + ); std::cout<<"CALIBRATION GetOriginLPS "<GetOriginLPS()<GetTranslations(), +// m_TransformMetaInfo->GetRotations(), +// m_DRTImage1MetaInfo->GetProjectionOriginLPS(), +// pFakeIsoLPS, +// ZeroPoint, +// IECtoLPS_Directions +// ); + CurrTransform = CalculateInternalTransformV2( ZeroPoint, @@ -2694,70 +2699,52 @@ void itkImageProcessor::GetProjectionImages(){ m_DRTImage1MetaInfo->GetProjectionOriginLPS(), IECtoLPS_Directions ); + } else { +// CurrTransform = +// CalculateInternalTransform( +// ZeroPoint , +// m_DRTGeometryMetaInfo->GetIECS2IECScannerR(), +// m_TransformMetaInfo->GetTranslations(), +// m_TransformMetaInfo->GetRotations(), +// m_DRTImage1MetaInfo->GetProjectionOriginLPS(), +// m_RTMetaInfo->GetIsocenterLPS() - m_CTMetaInfo->GetImportOffset(), +// m_CTMetaInfo->GetImportOffset(), +// IECtoLPS_Directions +// ); - // CurrTransform = - // CalculateInternalTransform( - // ZeroPoint , - // m_DRTGeometryMetaInfo->GetIECS2IECScannerR(), - // m_TransformMetaInfo->GetTranslations(), - // m_TransformMetaInfo->GetRotations(), - // m_DRTImage1MetaInfo->GetProjectionOriginLPS(), - // m_RTMetaInfo->GetIsocenterLPS() - m_CTMetaInfo->GetImportOffset(), - // m_CTMetaInfo->GetImportOffset(), - // IECtoLPS_Directions - // ); + CurrTransform = CalculateInternalTransformV2( + ZeroPoint , + m_DRTGeometryMetaInfo->GetIECS2IECScannerR(), + m_TransformMetaInfo->GetTranslations(), + m_TransformMetaInfo->GetRotations(), + m_DRTImage1MetaInfo->GetProjectionOriginLPSZero(), + m_RTMetaInfo->GetIsocenterLPS() - m_CTMetaInfo->GetOriginLPS(), + IECtoLPS_Directions + ); - CurrTransform = CalculateInternalTransformV2( - ZeroPoint , - m_DRTGeometryMetaInfo->GetIECS2IECScannerR(), - m_TransformMetaInfo->GetTranslations(), - m_TransformMetaInfo->GetRotations(), - m_DRTImage1MetaInfo->GetProjectionOriginLPSZero(), - m_RTMetaInfo->GetIsocenterLPS() - m_CTMetaInfo->GetOriginLPS(), - IECtoLPS_Directions - ); + } - std::cout<GetProjectionOriginLPSZero()<GetIsocenterLPS() <GetOriginLPS() <GetIsocenterLPS() - m_CTMetaInfo->GetOriginLPS() <GetCenter()<GetIsocenterLPS()<SetComputeZYX(true); + transform1->SetIdentity(); - - - - // transform1->SetComputeZYX(true); - // transform1->SetIdentity(); - - // transform1->SetTranslation( - // CurrTransform->GetTranslation()); - // transform1->SetRotation( - // CurrTransform->GetAngleX(), - // CurrTransform->GetAngleY(), - // CurrTransform->GetAngleZ() - // ); - - - // transform1->SetCenter( - // m_DRTImage1MetaInfo->GetProjectionOriginLPSZero() ); - - - transform1 = CurrTransform; + transform1->SetTranslation( + CurrTransform->GetTranslation()); + transform1->SetRotation( + CurrTransform->GetAngleX(), + CurrTransform->GetAngleY(), + CurrTransform->GetAngleZ() + ); // std::cout<< "itkImageProcessor::GetProjectionImages" <SetCenter( -// m_DRTImage1MetaInfo->GetProjectionOriginLPSZero()); -// transform1 ->SetCenter( -// m_CTMetaInfo->GetProjectionOriginLPSZero( -// m_DRTGeometryMetaInfo->GetProjectionCenter())); - - - std::cout<<"----> transform1 GetCenter"<GetCenter()<SetCenter( + m_DRTImage1MetaInfo->GetProjectionOriginLPSZero()); // std::cout<<"Angle1 "<GetProjectionAngleLPS() <GetTranslations(), +// m_TransformMetaInfo->GetRotations(), +// m_DRTImage2MetaInfo->GetProjectionOriginLPS(), +// pFakeIsoLPS, +// ZeroPoint, +// IECtoLPS_Directions +// ); CurrTransform = - CalculateInternalTransformV2( - ZeroPoint, - ZeroPoint, - m_TransformMetaInfo->GetTranslations(), - m_TransformMetaInfo->GetRotations(), - m_DRTImage2MetaInfo->GetProjectionOriginLPSZero(), - m_DRTImage2MetaInfo->GetProjectionOriginLPS(), - - IECtoLPS_Directions - ); + CalculateInternalTransformV2( + ZeroPoint, + ZeroPoint, + m_TransformMetaInfo->GetTranslations(), + m_TransformMetaInfo->GetRotations(), + m_DRTImage2MetaInfo->GetProjectionOriginLPSZero(), + m_DRTImage2MetaInfo->GetProjectionOriginLPS(), + IECtoLPS_Directions + ); // std::cout<<"pFakeIsoLPS: "<GetIECS2IECScannerR(), m_TransformMetaInfo->GetTranslations(), m_TransformMetaInfo->GetRotations(), @@ -2833,27 +2830,27 @@ void itkImageProcessor::GetProjectionImages(){ m_RTMetaInfo->GetIsocenterLPS() - m_CTMetaInfo->GetOriginLPS(), IECtoLPS_Directions ); + + } -transform2 = CurrTransform; - -// transform2->SetComputeZYX(true); -// transform2->SetIdentity(); - -// transform2->SetTranslation( -// CurrTransform->GetTranslation()); -// transform2->SetRotation( -// CurrTransform->GetAngleX(), -// CurrTransform->GetAngleY(), -// CurrTransform->GetAngleZ() -// ); -// transform2 ->SetCenter( -// m_DRTImage2MetaInfo->GetProjectionOriginLPSZero()); -// transform2 ->SetCenter( -// m_CTMetaInfo->GetProjectionOriginLPSZero( -// m_DRTGeometryMetaInfo->GetProjectionCenter())); + transform2->SetComputeZYX(true); + transform2->SetIdentity(); + + transform2->SetTranslation( + CurrTransform->GetTranslation()); + transform2->SetRotation( + CurrTransform->GetAngleX(), + CurrTransform->GetAngleY(), + CurrTransform->GetAngleZ() + ); + + + transform2 ->SetCenter( + m_DRTImage2MetaInfo->GetProjectionOriginLPSZero()); + //transform2 ->Print(std::cout); diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.h b/reg23Topograms/itkDTRrecon/itkImageProcessor.h index ec96d35..c91f4b4 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.h +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.h @@ -268,28 +268,30 @@ private: void CalculateExternalUserTransform(TransformType::Pointer transform, DRTImageMetaInformation::Pointer imageMetaInfo); - TransformType::Pointer - CalculateInternalTransform( - ImageType3D::PointType m_TranslationOffset, - ImageType3D::PointType m_RotationOffset, - ImageType3D::PointType m_TranslationUser, - ImageType3D::PointType m_RotationUser, - ImageType3D::PointType m_ProjectionTransformCenter, - ImageType3D::PointType m_UserTransformCenter, - ImageType3D::PointType m_OffsetTransformCenter, - InternalImageType::DirectionType m_IECtoLPSDirections - ); +// TransformType::Pointer +// CalculateInternalTransform( +// ImageType3D::PointType m_TranslationOffset, +// ImageType3D::PointType m_RotationOffset, +// ImageType3D::PointType m_TranslationUser, +// ImageType3D::PointType m_RotationUser, +// ImageType3D::PointType m_ProjectionTransformCenter, +// ImageType3D::PointType m_UserTransformCenter, +// ImageType3D::PointType m_OffsetTransformCenter, +// InternalImageType::DirectionType m_IECtoLPSDirections +// ); - TransformType::Pointer - CalculateInternalTransformV2( - ImageType3D::PointType m_TranslationOffset, - ImageType3D::PointType m_RotationOffset, - ImageType3D::PointType m_TranslationUser, - ImageType3D::PointType m_RotationUser, - ImageType3D::PointType m_CalibratedProjectionCenter, - ImageType3D::PointType m_RTIsocenter, - InternalImageType::DirectionType m_IECtoLPSDirections - ); + /* Calculate the transform used in siddon. + * The isocentric transform is mapped to the calibrated center of projection */ + TransformType::Pointer + CalculateInternalTransformV2( + ImageType3D::PointType m_TranslationOffset, + ImageType3D::PointType m_RotationOffset, + ImageType3D::PointType m_TranslationUser, + ImageType3D::PointType m_RotationUser, + ImageType3D::PointType m_CalibratedProjectionCenter, + ImageType3D::PointType m_RTIsocenter, + InternalImageType::DirectionType m_IECtoLPSDirections + ); TransformType::Pointer From 97674c6b4b8337d1199298a7d4f0cbac22bdc094 Mon Sep 17 00:00:00 2001 From: Proton local user Date: Wed, 3 May 2023 15:19:50 +0200 Subject: [PATCH 31/49] Cleanup debug print --- .../itkDTRrecon/itkImageProcessor.cpp | 463 +----------------- .../itkDTRrecon/itkQtIterationUpdate.h | 2 +- 2 files changed, 22 insertions(+), 443 deletions(-) diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp index 6ce2871..8af1bf8 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp @@ -1414,79 +1414,6 @@ itkImageProcessor::CalculateInternalTransformV2( } - -//itkImageProcessor::TransformType::Pointer -//itkImageProcessor::CalculateInternalTransform( -// ImageType3D::PointType m_TranslationOffset, //IEC -// ImageType3D::PointType m_RotationOffset, //IEC -// ImageType3D::PointType m_TranslationUser, //IEC -// ImageType3D::PointType m_RotationUser, //IEC -// ImageType3D::PointType m_ProjectionTransformCenter, //LPS -// ImageType3D::PointType m_UserTransformCenter, //LPS -// ImageType3D::PointType m_OffsetTransformCenter, //LPS -// InternalImageType::DirectionType m_IECtoLPSDirections -// ) -//{ - -// //Convert all inputs into LPS - -// ImageType3D::PointType m_TOffsetLPS = -// m_IECtoLPSDirections * m_TranslationOffset; - -// ImageType3D::PointType m_ROffsetLPS = -// m_IECtoLPSDirections * m_RotationOffset; - -// ImageType3D::PointType m_TUserLPS = -// m_IECtoLPSDirections * m_TranslationUser; - -// ImageType3D::PointType m_RUserLPS = -// m_IECtoLPSDirections * m_RotationUser; - -// // Map user to the projection center -// TransformType::Pointer m_UserTransform = -// MapTransformToNewOrigin ( -// m_ProjectionTransformCenter - m_UserTransformCenter, -// m_TUserLPS, -// m_RUserLPS -// ); - -// // Map offset to the projection center -// TransformType::Pointer m_OffsetTransform = -// MapTransformToNewOrigin ( -// m_ProjectionTransformCenter - m_UserTransformCenter,//m_OffsetTransformCenter, -// m_TOffsetLPS, -// m_ROffsetLPS -// ); - -// TransformType::Pointer m_OutputTransform = -// TransformType::New(); -// m_OutputTransform ->SetComputeZYX(true); -// m_OutputTransform ->SetIdentity(); - -// m_OutputTransform->SetTranslation( -// m_OffsetTransform->GetTranslation() + -// m_UserTransform->GetTranslation() -// ); - -// m_OutputTransform->SetRotation( -// m_OffsetTransform->GetAngleX() + -// m_UserTransform->GetAngleX(), -// m_OffsetTransform->GetAngleY() + -// m_UserTransform->GetAngleY(), -// m_OffsetTransform->GetAngleZ() + -// m_UserTransform->GetAngleZ() -// ); - -// m_OutputTransform->SetCenter( -// m_ProjectionTransformCenter); - - -// std::cout<GetProjectionOriginLPS(); - //ImageType3D::PointType pFakeIsoLPS = - // m_CTMetaInfo->GetProjectionOriginLPS( - // m_DRTGeometryMetaInfo->GetProjectionCenter1()); -// CurrTransform = -// CalculateInternalTransform( -// ZeroPoint, -// ZeroPoint, -// m_TransformMetaInfo->GetTranslations(), -// m_TransformMetaInfo->GetRotations(), -// m_DRTImage1MetaInfo->GetProjectionOriginLPS(), -// pFakeIsoLPS, -// ZeroPoint, -// IECtoLPS_Directions -// ); + CurrTransform = CalculateInternalTransformV2( ZeroPoint, @@ -1599,17 +1513,6 @@ void itkImageProcessor::InitializeRegistration( } else { -// CurrTransform = -// CalculateInternalTransform( -// ZeroPoint , -// m_DRTGeometryMetaInfo->GetIECS2IECScannerR(), -// m_TransformMetaInfo->GetTranslations(), -// m_TransformMetaInfo->GetRotations(), -// m_DRTImage1MetaInfo->GetProjectionOriginLPS(), -// m_RTMetaInfo->GetIsocenterLPS() - m_CTMetaInfo->GetImportOffset(), -// m_CTMetaInfo->GetImportOffset(), -// IECtoLPS_Directions -// ); CurrTransform = CalculateInternalTransformV2( ZeroPoint , m_DRTGeometryMetaInfo->GetIECS2IECScannerR(), @@ -1620,7 +1523,6 @@ void itkImageProcessor::InitializeRegistration( IECtoLPS_Directions ); - } @@ -1635,6 +1537,7 @@ void itkImageProcessor::InitializeRegistration( ); transform1->SetCenter( m_DRTImage1MetaInfo->GetProjectionOriginLPSZero() ); + /********* END OF CALCULATE INTERNAL TRANSFORM FOR PROJ1 *********/ @@ -1645,24 +1548,7 @@ void itkImageProcessor::InitializeRegistration( ImageType3D::PointType pFakeIsoLPS = m_DRTImage2MetaInfo->GetProjectionOriginLPS(); - //ImageType3D::PointType pFakeIsoLPS = - // m_CTMetaInfo->GetProjectionOriginLPS( - // m_DRTGeometryMetaInfo->GetProjectionCenter2()); - - - -// CurrTransform = -// CalculateInternalTransform( -// ZeroPoint, -// ZeroPoint, -// m_TransformMetaInfo->GetTranslations(), -// m_TransformMetaInfo->GetRotations(), -// m_DRTImage2MetaInfo->GetProjectionOriginLPS(), -// pFakeIsoLPS, -// ZeroPoint, -// IECtoLPS_Directions -// ); - CurrTransform = + CurrTransform = CalculateInternalTransformV2( ZeroPoint, ZeroPoint, @@ -1675,17 +1561,7 @@ void itkImageProcessor::InitializeRegistration( } else { -// CurrTransform = -// CalculateInternalTransform( -// ZeroPoint , -// m_DRTGeometryMetaInfo->GetIECS2IECScannerR(), -// m_TransformMetaInfo->GetTranslations(), -// m_TransformMetaInfo->GetRotations(), -// m_DRTImage2MetaInfo->GetProjectionOriginLPS(), -// m_RTMetaInfo->GetIsocenterLPS() - m_CTMetaInfo->GetImportOffset(), -// m_CTMetaInfo->GetImportOffset(), -// IECtoLPS_Directions -// ); + CurrTransform = CalculateInternalTransformV2( ZeroPoint, m_DRTGeometryMetaInfo->GetIECS2IECScannerR(), @@ -1923,32 +1799,10 @@ void itkImageProcessor::InitializeProjector() m_CTMetaInfo->GetLPS2IECDirections().GetTranspose(); TransformType::Pointer CurrTransform; - //CurrTransform->SetComputeZYX(true); - //CurrTransform->SetIdentity(); if(m_RTMetaInfo == NULL) { - //AAAAAA TODOOOOO CERCA - ImageType3D::PointType pFakeIsoLPS = - m_DRTImage1MetaInfo->GetProjectionOriginLPS(); - - //ImageType3D::PointType pFakeIsoLPS = - // m_CTMetaInfo->GetProjectionOriginLPS( - // m_DRTGeometryMetaInfo->GetProjectionCenter1()); - - -// CurrTransform = -// CalculateInternalTransform( -// ZeroPoint, -// ZeroPoint, -// m_TransformMetaInfo->GetTranslations(), -// m_TransformMetaInfo->GetRotations(), -// m_DRTImage1MetaInfo->GetProjectionOriginLPS(), -// pFakeIsoLPS, -// ZeroPoint, -// IECtoLPS_Directions -// ); CurrTransform = CalculateInternalTransformV2( ZeroPoint , ZeroPoint , @@ -1959,20 +1813,8 @@ void itkImageProcessor::InitializeProjector() IECtoLPS_Directions ); - } else { -// CurrTransform = -// CalculateInternalTransform( -// ZeroPoint , -// m_DRTGeometryMetaInfo->GetIECS2IECScannerR(), -// m_TransformMetaInfo->GetTranslations(), -// m_TransformMetaInfo->GetRotations(), -// m_DRTImage1MetaInfo->GetProjectionOriginLPS(), -// m_RTMetaInfo->GetIsocenterLPS() - m_CTMetaInfo->GetImportOffset(), -// m_CTMetaInfo->GetImportOffset(), -// IECtoLPS_Directions -// ); CurrTransform = CalculateInternalTransformV2( ZeroPoint , @@ -1999,10 +1841,9 @@ void itkImageProcessor::InitializeProjector() CurrTransform->GetAngleZ() ); - transform1->SetCenter( m_DRTImage1MetaInfo->GetProjectionOriginLPSZero() ); -// transform1->Print(std::cout); + // 2D Image 1 interpolator1->SetProjectionAngle( @@ -2013,40 +1854,13 @@ void itkImageProcessor::InitializeProjector() m_DRTGeometryMetaInfo->GetIntensityThreshold() ); interpolator1->SetPanelOffset( m_DRTGeometryMetaInfo->GetPanel1Offset()); - std::cout<< - "00000000000000 IP1 m_DRTGeometryMetaInfo->GetPanel2Offset()" - <GetPanel1Offset()<SetTransform(transform1); interpolator1->Initialize(); - - - //CurrTransform->SetComputeZYX(true); - //CurrTransform->SetIdentity(); - if(m_RTMetaInfo == NULL) { - ImageType3D::PointType pFakeIsoLPS = - m_DRTImage2MetaInfo->GetProjectionOriginLPS(); - //ImageType3D::PointType pFakeIsoLPS = - // m_CTMetaInfo->GetProjectionOriginLPS( - // m_DRTGeometryMetaInfo->GetProjectionCenter2()); - - - -// CurrTransform = -// CalculateInternalTransform( -// ZeroPoint, -// ZeroPoint, -// m_TransformMetaInfo->GetTranslations(), -// m_TransformMetaInfo->GetRotations(), -// m_DRTImage2MetaInfo->GetProjectionOriginLPS(), -// pFakeIsoLPS, -// ZeroPoint, -// IECtoLPS_Directions -// ); CurrTransform = CalculateInternalTransformV2( ZeroPoint, @@ -2061,17 +1875,6 @@ void itkImageProcessor::InitializeProjector() } else { -// CurrTransform = -// CalculateInternalTransform( -// ZeroPoint , -// m_DRTGeometryMetaInfo->GetIECS2IECScannerR(), -// m_TransformMetaInfo->GetTranslations(), -// m_TransformMetaInfo->GetRotations(), -// m_DRTImage2MetaInfo->GetProjectionOriginLPS(), -// m_RTMetaInfo->GetIsocenterLPS() - m_CTMetaInfo->GetImportOffset(), -// m_CTMetaInfo->GetImportOffset(), -// IECtoLPS_Directions -// ); CurrTransform = CalculateInternalTransformV2( ZeroPoint, m_DRTGeometryMetaInfo->GetIECS2IECScannerR(), @@ -2081,8 +1884,6 @@ void itkImageProcessor::InitializeProjector() m_RTMetaInfo->GetIsocenterLPS() - m_CTMetaInfo->GetOriginLPS(), IECtoLPS_Directions ); - - } @@ -2111,25 +1912,10 @@ void itkImageProcessor::InitializeProjector() m_DRTGeometryMetaInfo->GetIntensityThreshold() ); interpolator2->SetPanelOffset( m_DRTGeometryMetaInfo->GetPanel2Offset()); - std::cout<< - "00000000000000 IP2 m_DRTGeometryMetaInfo->GetPanel2Offset()" - <GetPanel2Offset()<SetTransform(transform2); interpolator2->Initialize(); - // // 2D Image 2 - // interpolator2->SetProjectionAngle( - // dtr * - // m_DRTImage2MetaInfo->GetProjectionAngleLPS() ); - // interpolator2->SetFocalPointToIsocenterDistance( - // m_DRTImage2MetaInfo->GetSCD()); - // interpolator2->SetThreshold( - // m_DRTGeometryMetaInfo->GetIntensityThreshold() - // ); - // interpolator2->SetTransform(transform); - // interpolator2->Initialize(); - resampleFilter1 = ResampleFilterType::New(); resampleFilter1->SetInput( @@ -2282,9 +2068,6 @@ void itkImageProcessor::loadRTPlanInfo( ); -// std::cout<< "m_CTMetaInfo->GetImportOffset() " -// <GetImportOffset() <UpdateProjectionGeometryMeta(); this->InitializeProjector(); @@ -2331,11 +2114,11 @@ void itkImageProcessor::UpdateProjectionGeometryMeta(){ IsocenterOffsetLPS = m_CTMetaInfo->ConvertIECPointToLPSPoint( m_DRTGeometryMetaInfo->GetProjectionCenterOffset1()); - std::cout<< "///////////////// PGEOM META BEG ///////////////" <GetProjectionCenter() <GetProjectionCenter() <SetProjectionAngleLPS( this->CalcProjectionAngleLPS( @@ -2376,20 +2159,6 @@ void itkImageProcessor::UpdateProjectionGeometryMeta(){ m_DRTImage1MetaInfo->SetProjectionOriginLPSZero( CalibratedIsocenterZeroLPS); -// // This is based on the calibrated iso to be sure... -// std::vector vBounds = m_CTMetaInfo->CalculateRegions( -// NominalIsocenter_wZcorrectionLPS -//// m_DRTImage1MetaInfo->GetProjectionOriginLPS() -// ); - -// std::cout<<"Bounds1: " -// <SetSizeWithBounds( NULL,//vBounds.data(), m_DRTGeometryMetaInfo->GetDRT1Size(), @@ -2414,19 +2183,9 @@ void itkImageProcessor::UpdateProjectionGeometryMeta(){ m_DRTGeometryMetaInfo->GetProjectionAngle1IEC() ), //m_DRTGeometryMetaInfo->GetProjectionAngle1IEC(),// m_DRTImage1MetaInfo->GetProjectionAngleLPS(), Std_DRT2LPS - ) /*- - CalcDRTImageOffset( - PanelOffsetIEC1, - this->CalcProjectionAngleLPS( - m_CTMetaInfo->GetPatientOrientation(), - m_DRTGeometryMetaInfo->GetProjectionAngle1IEC() ), - Std_DRT2LPS - )*/ + ) ); - std::cout<<"CALIBRATION GetOriginLPS "<GetOriginLPS()<SetImageDirectionsLPS( CalcDRTImageDirections( @@ -2437,24 +2196,6 @@ void itkImageProcessor::UpdateProjectionGeometryMeta(){ Std_DRT2LPS) ); -// std::cout<<"IsocenterOffsetLPS"<< IsocenterOffsetLPS <GetSize()"<< m_DRTImage1MetaInfo->GetSize() <GetSpacing()"<< m_DRTImage1MetaInfo->GetSpacing() <GetOrigin()"<< m_DRTImage1MetaInfo->GetOrigin() <CalcProjectionAngleLPS( -// m_CTMetaInfo->GetPatientOrientation(), -// m_DRTGeometryMetaInfo->GetProjectionAngle1IEC() ), -// Std_DRT2LPS -// ) <GetCOV()"<< m_DRTImage1MetaInfo->GetCOV() <GetOriginLPS()"<< m_DRTImage1MetaInfo->GetOriginLPS() <GetProjectionAngleLPS()"<GetProjectionAngleLPS()<GetImageDirectionsLPS()"<< m_DRTImage1MetaInfo->GetImageDirectionsLPS() <SetProjectionOriginLPS( CalibratedIsocenterLPS); - // m_CTMetaInfo->GetProjectionOriginLPS( - // m_DRTGeometryMetaInfo->GetProjectionCenter2()) - // ); m_DRTImage2MetaInfo->SetProjectionOriginLPSZero( CalibratedIsocenterZeroLPS); - // m_CTMetaInfo->GetProjectionOriginLPSZero( - // m_DRTGeometryMetaInfo->GetProjectionCenter2()) - // ); -// vBounds.clear(); -// vBounds = m_CTMetaInfo->CalculateRegions( -// NominalIsocenter_wZcorrectionLPS//m_DRTImage2MetaInfo->GetProjectionOriginLPS() -// ); - -// std::cout<<"Bounds2: " -// <SetSizeWithBounds( NULL,//vBounds.data(), @@ -2541,8 +2264,6 @@ void itkImageProcessor::UpdateProjectionGeometryMeta(){ Std_DRT2LPS )); - std::cout<<"m_DRTImage2MetaInfo->GetOriginLPS()"<< m_DRTImage2MetaInfo->GetOriginLPS() <SetOriginLPS( CalcDRTImageOrigin( @@ -2554,14 +2275,7 @@ void itkImageProcessor::UpdateProjectionGeometryMeta(){ m_DRTGeometryMetaInfo->GetProjectionAngle2IEC()) , //m_DRTGeometryMetaInfo->GetProjectionAngle2IEC(),//m_DRTImage2MetaInfo->GetProjectionAngleLPS(), Std_DRT2LPS - ) /*- - CalcDRTImageOffset( - PanelOffsetIEC2, - this->CalcProjectionAngleLPS( - m_CTMetaInfo->GetPatientOrientation(), - m_DRTGeometryMetaInfo->GetProjectionAngle2IEC() ), - Std_DRT2LPS - )*/ + ) ); @@ -2574,26 +2288,6 @@ void itkImageProcessor::UpdateProjectionGeometryMeta(){ Std_DRT2LPS) ); -// std::cout<<"IsocenterOffsetLPS"<< IsocenterOffsetLPS <GetSize()"<< m_DRTImage2MetaInfo->GetSize() <GetSpacing()"<< m_DRTImage2MetaInfo->GetSpacing() <GetOrigin()"<< m_DRTImage2MetaInfo->GetOrigin() <CalcProjectionAngleLPS( -// m_CTMetaInfo->GetPatientOrientation(), -// m_DRTGeometryMetaInfo->GetProjectionAngle2IEC() ), -// Std_DRT2LPS -// ) <GetCOV()"<< m_DRTImage2MetaInfo->GetCOV() <GetOriginLPS() - Offset "<< m_DRTImage2MetaInfo->GetOriginLPS() <GetProjectionAngleLPS()"<GetProjectionAngleLPS()<GetImageDirectionsLPS()"<< m_DRTImage2MetaInfo->GetImageDirectionsLPS() <CalcDRTImageDirections(dAngle, stdDRT2LPS); - -// ImageType3D::PointType NewOffset = -// DRT2LPS * (m_DRTOffset); - -// return -// NewOffset; -//} void itkImageProcessor::GetProjectionImages(){ @@ -2664,31 +2342,10 @@ void itkImageProcessor::GetProjectionImages(){ IECtoLPS_Directions = m_CTMetaInfo->GetLPS2IECDirections().GetTranspose(); TransformType::Pointer CurrTransform; - //CurrTransform->SetComputeZYX(true); - //CurrTransform->SetIdentity(); + if(m_RTMetaInfo == NULL) { - - ImageType3D::PointType pFakeIsoLPS = - m_DRTImage1MetaInfo->GetProjectionOriginLPS(); - //m_CTMetaInfo->GetProjectionOriginLPS( - // m_DRTGeometryMetaInfo->GetProjectionCenter()); - -// std::cout<<"pFakeIsoLPS: "<GetTranslations(), -// m_TransformMetaInfo->GetRotations(), -// m_DRTImage1MetaInfo->GetProjectionOriginLPS(), -// pFakeIsoLPS, -// ZeroPoint, -// IECtoLPS_Directions -// ); - CurrTransform = CalculateInternalTransformV2( ZeroPoint, @@ -2702,18 +2359,6 @@ void itkImageProcessor::GetProjectionImages(){ } else { -// CurrTransform = -// CalculateInternalTransform( -// ZeroPoint , -// m_DRTGeometryMetaInfo->GetIECS2IECScannerR(), -// m_TransformMetaInfo->GetTranslations(), -// m_TransformMetaInfo->GetRotations(), -// m_DRTImage1MetaInfo->GetProjectionOriginLPS(), -// m_RTMetaInfo->GetIsocenterLPS() - m_CTMetaInfo->GetImportOffset(), -// m_CTMetaInfo->GetImportOffset(), -// IECtoLPS_Directions -// ); - CurrTransform = CalculateInternalTransformV2( ZeroPoint , m_DRTGeometryMetaInfo->GetIECS2IECScannerR(), @@ -2726,8 +2371,6 @@ void itkImageProcessor::GetProjectionImages(){ } - std::cout<<"Curr GetCenter"<GetCenter()<GetIsocenterLPS()<SetComputeZYX(true); transform1->SetIdentity(); @@ -2739,22 +2382,9 @@ void itkImageProcessor::GetProjectionImages(){ CurrTransform->GetAngleY(), CurrTransform->GetAngleZ() ); - -// std::cout<< "itkImageProcessor::GetProjectionImages" <SetCenter( m_DRTImage1MetaInfo->GetProjectionOriginLPSZero()); -// std::cout<<"Angle1 "<GetProjectionAngleLPS() <GetProjectionOriginLPSZero() <GetProjectionOriginLPS()<GetProjectionAngleLPS() <GetProjectionOriginLPSZero() <GetProjectionOriginLPS()<Print(std::cout); // The parameters of interpolator1, such as ProjectionAngle and FocalPointToIsocenterDistance @@ -2764,36 +2394,13 @@ void itkImageProcessor::GetProjectionImages(){ interpolator1->Initialize(); - - - transform2->SetComputeZYX(true); transform2->SetIdentity(); - //CurrTransform->SetComputeZYX(true); - //CurrTransform->SetIdentity(); if(m_RTMetaInfo == NULL) { - ImageType3D::PointType pFakeIsoLPS = - m_DRTImage2MetaInfo->GetProjectionOriginLPS(); - //m_CTMetaInfo->GetProjectionOriginLPS( - // m_DRTGeometryMetaInfo->GetProjectionCenter()); - -// std::cout<<"pFakeIsoLPS: "<GetTranslations(), -// m_TransformMetaInfo->GetRotations(), -// m_DRTImage2MetaInfo->GetProjectionOriginLPS(), -// pFakeIsoLPS, -// ZeroPoint, -// IECtoLPS_Directions -// ); CurrTransform = CalculateInternalTransformV2( ZeroPoint, @@ -2805,22 +2412,8 @@ void itkImageProcessor::GetProjectionImages(){ IECtoLPS_Directions ); -// std::cout<<"pFakeIsoLPS: "<GetIECS2IECScannerR(), -// m_TransformMetaInfo->GetTranslations(), -// m_TransformMetaInfo->GetRotations(), -// m_DRTImage2MetaInfo->GetProjectionOriginLPS(), -// m_RTMetaInfo->GetIsocenterLPS() - m_CTMetaInfo->GetImportOffset(), -// m_CTMetaInfo->GetImportOffset(), -// IECtoLPS_Directions -// ); - CurrTransform = CalculateInternalTransformV2( ZeroPoint, m_DRTGeometryMetaInfo->GetIECS2IECScannerR(), @@ -2847,34 +2440,21 @@ void itkImageProcessor::GetProjectionImages(){ CurrTransform->GetAngleZ() ); - transform2 ->SetCenter( m_DRTImage2MetaInfo->GetProjectionOriginLPSZero()); - //transform2 ->Print(std::cout); - - - // // The parameters of interpolator2, such as ProjectionAngle and FocalPointToIsocenterDistance // // have been set before registration. Here we only need to replace the initial // // transform with the final transform. interpolator2->SetTransform(transform2); //finalTransform); interpolator2->Initialize(); -// std::cout<<"pFakeIsoLPS: "<Update(); filter2->Update(); imageDRT1In = filter1->GetOutput(); imageDRT2In = filter2->GetOutput(); -// std::cout<< "itkImageProcessor::GetProjectionImages END" <GetInverseTransform()->GetMatrix()<GetInverseTransform()->GetTranslation()<GetOutput()->GetBounds(); - - std::cout<< "-------- Proj 2 --------" <GetOutput()->GetBounds(); +// std::cout<< "-------- Proj 2 --------" <GetOutput(); diff --git a/reg23Topograms/itkDTRrecon/itkQtIterationUpdate.h b/reg23Topograms/itkDTRrecon/itkQtIterationUpdate.h index 402c4b6..91e982a 100644 --- a/reg23Topograms/itkDTRrecon/itkQtIterationUpdate.h +++ b/reg23Topograms/itkDTRrecon/itkQtIterationUpdate.h @@ -97,7 +97,7 @@ public: Execute(const itk::Object* object, const itk::EventObject& event) override { if(objIterUpdate->getAbortFlag()){ - std::cout << "Abortisci per piacere" << std::endl; + std::cout << "AbortRequest" << std::endl; objIterUpdate->setAbortFlag(false); throw itk::ProcessAborted(); } From 8e6c9e9abafd8c65adeeb0774be455a1abc90de5 Mon Sep 17 00:00:00 2001 From: Proton local user Date: Wed, 3 May 2023 16:08:17 +0200 Subject: [PATCH 32/49] Some work on UI --- .../itkDTRrecon/itkImageProcessor.cpp | 159 +++++++++++------- .../itkDTRrecon/itkImageProcessor.h | 15 +- 2 files changed, 108 insertions(+), 66 deletions(-) diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp index 3723431..867ff03 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp @@ -471,7 +471,7 @@ int itkImageProcessor::load3DSerieFromFiles( std::vector v_fnames){ imageSeriesReader3D->SetImageIO(dicomIO); imageSeriesReader3D->SetFileNames(v_sortedFnames); - //imageSeriesReader3D->SetNumberOfWorkUnits(8); + imageSeriesReader3D->SetNumberOfWorkUnits(8); imageSeriesReader3D->ForceOrthogonalDirectionOff(); // properly read CTs with gantry tilt //imageSeriesReader3D->SetSpacingWarningRelThreshold(); @@ -1362,6 +1362,85 @@ void itkImageProcessor::CalculateExternalUserTransform(TransformType::Pointer tr m_TransformMetaInfo->SetUserRotations(LPStoIEC_Directions * rotationUser); } +itkImageProcessor::TransformType::Pointer +itkImageProcessor::CalculateInternalTransformV2( + ImageType3D::PointType m_ImportOffsetLPS, + ImageType3D::PointType m_RotationOffsetIEC, + ImageType3D::PointType m_TranslationUserIEC, + ImageType3D::PointType m_RotationUserIEC, + ImageType3D::PointType m_ProjectionCenterLPS, + ImageType3D::PointType m_RTIsocenterLPS, + InternalImageType::DirectionType m_IECtoLPSDirections + ){ + + const double dtr = (atan(1.0) * 4.0) / 180.0; + + ImageType3D::PointType m_ROffsetLPS = + m_IECtoLPSDirections * m_RotationOffsetIEC; + + ImageType3D::PointType m_TUserLPS = + m_IECtoLPSDirections * m_TranslationUserIEC; + + ImageType3D::PointType m_RUserLPS = + m_IECtoLPSDirections * m_RotationUserIEC; + + + TransformType::OutputVectorType translation; + translation[0] = m_TUserLPS[0]; + translation[1] = m_TUserLPS[1]; + translation[2] = m_TUserLPS[2]; + + ImageType3D::PointType m_TransformRotations; + m_TransformRotations[0] = m_ROffsetLPS[0] + m_RUserLPS[0] ; + m_TransformRotations[1] = m_ROffsetLPS[1] + m_RUserLPS[1] ; + m_TransformRotations[2] = m_ROffsetLPS[2] + m_RUserLPS[2] ; + + ImageType3D::PointType m_RTIsocenterLPSNEG; + m_RTIsocenterLPSNEG[0] = -m_RTIsocenterLPS[0] + m_ProjectionCenterLPS[0]; + m_RTIsocenterLPSNEG[1] = -m_RTIsocenterLPS[1] + m_ProjectionCenterLPS[0]; + m_RTIsocenterLPSNEG[2] = -m_RTIsocenterLPS[2] + m_ProjectionCenterLPS[0]; + + // Map user to the projection center + TransformType::Pointer m_IsoTransformZeroAtCTOrigin = + MapTransformToNewOrigin ( + m_RTIsocenterLPSNEG, + translation, + m_TransformRotations + ); + + TransformType::Pointer m_OutputTransform = + TransformType::New(); + m_OutputTransform ->SetComputeZYX(true); + m_OutputTransform ->SetIdentity(); + + TransformType::OutputVectorType translation_Out; + translation_Out[0] = + m_IsoTransformZeroAtCTOrigin->GetTranslation()[0] + + m_ImportOffsetLPS[0] + + m_ProjectionCenterLPS[0]; + translation_Out[1] = + m_IsoTransformZeroAtCTOrigin->GetTranslation()[1] + + m_ImportOffsetLPS[1] + + m_ProjectionCenterLPS[1]; + translation_Out[2] = + m_IsoTransformZeroAtCTOrigin->GetTranslation()[2] + + m_ImportOffsetLPS[2] + + m_ProjectionCenterLPS[2]; + + m_OutputTransform->SetTranslation( + translation_Out); + + m_OutputTransform->SetRotation( + m_IsoTransformZeroAtCTOrigin->GetAngleX(), + m_IsoTransformZeroAtCTOrigin->GetAngleY(), + m_IsoTransformZeroAtCTOrigin->GetAngleZ()); + + m_OutputTransform->SetCenter( + m_ProjectionCenterLPS); + + return m_OutputTransform; + +} itkImageProcessor::TransformType::Pointer itkImageProcessor::CalculateInternalTransform( @@ -1401,7 +1480,7 @@ itkImageProcessor::CalculateInternalTransform( // Map offset to the projection center TransformType::Pointer m_OffsetTransform = MapTransformToNewOrigin ( - m_ProjectionTransformCenter - m_UserTransformCenter,//m_OffsetTransformCenter, + m_ProjectionTransformCenter - m_UserTransformCenter, m_TOffsetLPS, m_ROffsetLPS ); @@ -1429,7 +1508,7 @@ itkImageProcessor::CalculateInternalTransform( m_ProjectionTransformCenter); - std::cout<GetLPS2IECDirections().GetTranspose(); TransformType::Pointer CurrTransform; - //CurrTransform->SetComputeZYX(true); - //CurrTransform->SetIdentity(); if(m_RTMetaInfo == NULL) { @@ -1839,11 +1916,6 @@ void itkImageProcessor::InitializeProjector() ImageType3D::PointType pFakeIsoLPS = m_DRTImage1MetaInfo->GetProjectionOriginLPS(); - //ImageType3D::PointType pFakeIsoLPS = - // m_CTMetaInfo->GetProjectionOriginLPS( - // m_DRTGeometryMetaInfo->GetProjectionCenter1()); - - CurrTransform = CalculateInternalTransform( ZeroPoint, @@ -1855,7 +1927,7 @@ void itkImageProcessor::InitializeProjector() ZeroPoint, IECtoLPS_Directions ); - } else { + } else { CurrTransform = CalculateInternalTransform( @@ -2238,20 +2310,6 @@ void itkImageProcessor::UpdateProjectionGeometryMeta(){ m_DRTImage1MetaInfo->SetProjectionOriginLPSZero( CalibratedIsocenterZeroLPS); -// // This is based on the calibrated iso to be sure... -// std::vector vBounds = m_CTMetaInfo->CalculateRegions( -// NominalIsocenter_wZcorrectionLPS -//// m_DRTImage1MetaInfo->GetProjectionOriginLPS() -// ); - -// std::cout<<"Bounds1: " -// <SetSizeWithBounds( NULL,//vBounds.data(), m_DRTGeometryMetaInfo->GetDRT1Size(), @@ -2270,21 +2328,12 @@ void itkImageProcessor::UpdateProjectionGeometryMeta(){ CalcDRTImageOrigin( m_DRTImage1MetaInfo->GetOrigin(), m_DRTImage1MetaInfo->GetCOV(), - NominalIsocenter_wZcorrectionLPS,//m_DRTImage1MetaInfo->GetProjectionOriginLPS(), - this->CalcProjectionAngleLPS( - m_CTMetaInfo->GetPatientOrientation(), - m_DRTGeometryMetaInfo->GetProjectionAngle1IEC() ), - //m_DRTGeometryMetaInfo->GetProjectionAngle1IEC(),// m_DRTImage1MetaInfo->GetProjectionAngleLPS(), - Std_DRT2LPS - ) /*- - CalcDRTImageOffset( - PanelOffsetIEC1, + NominalIsocenter_wZcorrectionLPS, this->CalcProjectionAngleLPS( m_CTMetaInfo->GetPatientOrientation(), m_DRTGeometryMetaInfo->GetProjectionAngle1IEC() ), Std_DRT2LPS - )*/ - + ) ); std::cout<<"CALIBRATION GetOriginLPS "<GetOriginLPS()<SetProjectionOriginLPS( CalibratedIsocenterLPS); - // m_CTMetaInfo->GetProjectionOriginLPS( - // m_DRTGeometryMetaInfo->GetProjectionCenter2()) - // ); m_DRTImage2MetaInfo->SetProjectionOriginLPSZero( CalibratedIsocenterZeroLPS); - // m_CTMetaInfo->GetProjectionOriginLPSZero( - // m_DRTGeometryMetaInfo->GetProjectionCenter2()) - // ); - -// vBounds.clear(); -// vBounds = m_CTMetaInfo->CalculateRegions( -// NominalIsocenter_wZcorrectionLPS//m_DRTImage2MetaInfo->GetProjectionOriginLPS() -// ); - -// std::cout<<"Bounds2: " -// <SetSizeWithBounds( NULL,//vBounds.data(), @@ -2416,14 +2446,7 @@ void itkImageProcessor::UpdateProjectionGeometryMeta(){ m_DRTGeometryMetaInfo->GetProjectionAngle2IEC()) , //m_DRTGeometryMetaInfo->GetProjectionAngle2IEC(),//m_DRTImage2MetaInfo->GetProjectionAngleLPS(), Std_DRT2LPS - ) /*- - CalcDRTImageOffset( - PanelOffsetIEC2, - this->CalcProjectionAngleLPS( - m_CTMetaInfo->GetPatientOrientation(), - m_DRTGeometryMetaInfo->GetProjectionAngle2IEC() ), - Std_DRT2LPS - )*/ + ) ); @@ -2650,7 +2673,15 @@ void itkImageProcessor::GetProjectionImages(){ m_CTMetaInfo->GetImportOffset(), IECtoLPS_Directions ); - + std::cout<<"GGGG CalculateInternalTransform GGG"<GetIECS2IECScannerR()<GetTranslations()<GetRotations()<GetProjectionOriginLPS()<GetIsocenterLPS()<GetImportOffset()<GetIsocenterLPS() - m_CTMetaInfo->GetImportOffset()<GetImportOffset() <; /** Optimizer which tries to find the minimn (Powell Optimizer)*/ - // using OptimizerType = itk::PowellOptimizer; using AmoebaOptimizerType = itk::AmoebaOptimizer; /** Optimizer which samples the whol space */ using ExhaustiveOptimizerType = itk::ExhaustiveOptimizer; @@ -266,7 +265,9 @@ private: using ITKtoVTKFilterType = itk::ImageToVTKImageFilter; void - CalculateExternalUserTransform(TransformType::Pointer transform, DRTImageMetaInformation::Pointer imageMetaInfo); + CalculateExternalUserTransform( + TransformType::Pointer transform, + DRTImageMetaInformation::Pointer imageMetaInfo); TransformType::Pointer CalculateInternalTransform( @@ -280,6 +281,16 @@ private: InternalImageType::DirectionType m_IECtoLPSDirections ); + TransformType::Pointer + CalculateInternalTransformV2( + ImageType3D::PointType m_ImportOffsetLPS, + ImageType3D::PointType m_RotationOffsetIEC, + ImageType3D::PointType m_TranslationUserIEC, + ImageType3D::PointType m_RotationUserIEC, + ImageType3D::PointType m_ProjectionCenterLPS, + ImageType3D::PointType m_RTIsocenterLPS, + InternalImageType::DirectionType m_IECtoLPSDirections + ); TransformType::Pointer transform1, From 2d9d3d97bd546b37a2189b6cd5002b73145e19d0 Mon Sep 17 00:00:00 2001 From: Proton local user Date: Wed, 3 May 2023 16:43:13 +0200 Subject: [PATCH 33/49] RTPlan data widget as TreeWidget --- .../itkDTRrecon/itkImageProcessor.cpp | 79 ------------------- .../itkDTRrecon/itkImageProcessor.h | 11 +-- 2 files changed, 1 insertion(+), 89 deletions(-) diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp index 2916db1..17e53c8 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp @@ -1362,85 +1362,6 @@ void itkImageProcessor::CalculateExternalUserTransform(TransformType::Pointer tr m_TransformMetaInfo->SetUserRotations(LPStoIEC_Directions * rotationUser); } -itkImageProcessor::TransformType::Pointer -itkImageProcessor::CalculateInternalTransformV2( - ImageType3D::PointType m_ImportOffsetLPS, - ImageType3D::PointType m_RotationOffsetIEC, - ImageType3D::PointType m_TranslationUserIEC, - ImageType3D::PointType m_RotationUserIEC, - ImageType3D::PointType m_ProjectionCenterLPS, - ImageType3D::PointType m_RTIsocenterLPS, - InternalImageType::DirectionType m_IECtoLPSDirections - ){ - - const double dtr = (atan(1.0) * 4.0) / 180.0; - - ImageType3D::PointType m_ROffsetLPS = - m_IECtoLPSDirections * m_RotationOffsetIEC; - - ImageType3D::PointType m_TUserLPS = - m_IECtoLPSDirections * m_TranslationUserIEC; - - ImageType3D::PointType m_RUserLPS = - m_IECtoLPSDirections * m_RotationUserIEC; - - - TransformType::OutputVectorType translation; - translation[0] = m_TUserLPS[0]; - translation[1] = m_TUserLPS[1]; - translation[2] = m_TUserLPS[2]; - - ImageType3D::PointType m_TransformRotations; - m_TransformRotations[0] = m_ROffsetLPS[0] + m_RUserLPS[0] ; - m_TransformRotations[1] = m_ROffsetLPS[1] + m_RUserLPS[1] ; - m_TransformRotations[2] = m_ROffsetLPS[2] + m_RUserLPS[2] ; - - ImageType3D::PointType m_RTIsocenterLPSNEG; - m_RTIsocenterLPSNEG[0] = -m_RTIsocenterLPS[0] + m_ProjectionCenterLPS[0]; - m_RTIsocenterLPSNEG[1] = -m_RTIsocenterLPS[1] + m_ProjectionCenterLPS[0]; - m_RTIsocenterLPSNEG[2] = -m_RTIsocenterLPS[2] + m_ProjectionCenterLPS[0]; - - // Map user to the projection center - TransformType::Pointer m_IsoTransformZeroAtCTOrigin = - MapTransformToNewOrigin ( - m_RTIsocenterLPSNEG, - translation, - m_TransformRotations - ); - - TransformType::Pointer m_OutputTransform = - TransformType::New(); - m_OutputTransform ->SetComputeZYX(true); - m_OutputTransform ->SetIdentity(); - - TransformType::OutputVectorType translation_Out; - translation_Out[0] = - m_IsoTransformZeroAtCTOrigin->GetTranslation()[0] + - m_ImportOffsetLPS[0] + - m_ProjectionCenterLPS[0]; - translation_Out[1] = - m_IsoTransformZeroAtCTOrigin->GetTranslation()[1] + - m_ImportOffsetLPS[1] + - m_ProjectionCenterLPS[1]; - translation_Out[2] = - m_IsoTransformZeroAtCTOrigin->GetTranslation()[2] + - m_ImportOffsetLPS[2] + - m_ProjectionCenterLPS[2]; - - m_OutputTransform->SetTranslation( - translation_Out); - - m_OutputTransform->SetRotation( - m_IsoTransformZeroAtCTOrigin->GetAngleX(), - m_IsoTransformZeroAtCTOrigin->GetAngleY(), - m_IsoTransformZeroAtCTOrigin->GetAngleZ()); - - m_OutputTransform->SetCenter( - m_ProjectionCenterLPS); - - return m_OutputTransform; - -} itkImageProcessor::TransformType::Pointer itkImageProcessor::CalculateInternalTransformV2( diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.h b/reg23Topograms/itkDTRrecon/itkImageProcessor.h index aba2660..553212e 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.h +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.h @@ -294,16 +294,7 @@ private: InternalImageType::DirectionType m_IECtoLPSDirections ); - TransformType::Pointer - CalculateInternalTransformV2( - ImageType3D::PointType m_ImportOffsetLPS, - ImageType3D::PointType m_RotationOffsetIEC, - ImageType3D::PointType m_TranslationUserIEC, - ImageType3D::PointType m_RotationUserIEC, - ImageType3D::PointType m_ProjectionCenterLPS, - ImageType3D::PointType m_RTIsocenterLPS, - InternalImageType::DirectionType m_IECtoLPSDirections - ); + TransformType::Pointer transform1, From b0beda81b86f9465215b60c4b15de3942be09de7 Mon Sep 17 00:00:00 2001 From: Proton local user Date: Wed, 3 May 2023 16:43:52 +0200 Subject: [PATCH 34/49] REG working --- .../itkDTRrecon/itkImageProcessor.cpp | 27 +++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp index 8af1bf8..63925cc 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp @@ -1495,11 +1495,6 @@ void itkImageProcessor::InitializeRegistration( TransformType::Pointer CurrTransform; if(m_RTMetaInfo == NULL) { - - //AAAAAA TODOOOOO CERCA - ImageType3D::PointType pFakeIsoLPS = - m_DRTImage1MetaInfo->GetProjectionOriginLPS(); - CurrTransform = CalculateInternalTransformV2( ZeroPoint, @@ -1545,9 +1540,6 @@ void itkImageProcessor::InitializeRegistration( /********* BEGIN CALCULATION OF INTERNAL TRANSFORM FOR PROJ2 *********/ if(m_RTMetaInfo == NULL) { - ImageType3D::PointType pFakeIsoLPS = - m_DRTImage2MetaInfo->GetProjectionOriginLPS(); - CurrTransform = CalculateInternalTransformV2( ZeroPoint, @@ -1743,10 +1735,20 @@ int itkImageProcessor::StartRegistration(std::string extraInfo) m_OptmizerValue = optimizer->GetValue(); + auto finalParameters = transform1->GetParameters(); - optimizer->GetCurrentPosition(); + //optimizer->GetCurrentPosition(); finalParameters = finalParameters - startParameters; + std::cout<<"startParameters "<GetCenter()<GetTranslation()<GetCenter()<GetTranslation()<SetParameters(finalParameters); @@ -1784,6 +1786,7 @@ void itkImageProcessor::InitializeProjector() m_DRTGeometryMetaInfo == NULL || m_TransformMetaInfo == NULL ){ //TODO + return; } const double dtr = (atan(1.0) * 4.0) / 180.0; @@ -2181,7 +2184,6 @@ void itkImageProcessor::UpdateProjectionGeometryMeta(){ this->CalcProjectionAngleLPS( m_CTMetaInfo->GetPatientOrientation(), m_DRTGeometryMetaInfo->GetProjectionAngle1IEC() ), - //m_DRTGeometryMetaInfo->GetProjectionAngle1IEC(),// m_DRTImage1MetaInfo->GetProjectionAngleLPS(), Std_DRT2LPS ) @@ -2192,7 +2194,6 @@ void itkImageProcessor::UpdateProjectionGeometryMeta(){ this->CalcProjectionAngleLPS( m_CTMetaInfo->GetPatientOrientation(), m_DRTGeometryMetaInfo->GetProjectionAngle1IEC()), - //m_DRTGeometryMetaInfo->GetProjectionAngle1IEC(),//m_DRTImage1MetaInfo->GetProjectionAngleLPS(), Std_DRT2LPS) ); @@ -2260,7 +2261,6 @@ void itkImageProcessor::UpdateProjectionGeometryMeta(){ this->CalcProjectionAngleLPS( m_CTMetaInfo->GetPatientOrientation(), m_DRTGeometryMetaInfo->GetProjectionAngle2IEC()) , - //m_DRTGeometryMetaInfo->GetProjectionAngle2IEC(),//m_DRTImage2MetaInfo->GetProjectionAngleLPS(), Std_DRT2LPS )); @@ -2273,7 +2273,6 @@ void itkImageProcessor::UpdateProjectionGeometryMeta(){ this->CalcProjectionAngleLPS( m_CTMetaInfo->GetPatientOrientation(), m_DRTGeometryMetaInfo->GetProjectionAngle2IEC()) , - //m_DRTGeometryMetaInfo->GetProjectionAngle2IEC(),//m_DRTImage2MetaInfo->GetProjectionAngleLPS(), Std_DRT2LPS ) @@ -2284,7 +2283,6 @@ void itkImageProcessor::UpdateProjectionGeometryMeta(){ this->CalcProjectionAngleLPS( m_CTMetaInfo->GetPatientOrientation(), m_DRTGeometryMetaInfo->GetProjectionAngle2IEC()) , - //m_DRTGeometryMetaInfo->GetProjectionAngle2IEC(),//m_DRTImage2MetaInfo->GetProjectionAngleLPS(), Std_DRT2LPS) ); @@ -2326,6 +2324,7 @@ void itkImageProcessor::GetProjectionImages(){ m_DRTGeometryMetaInfo == NULL || m_TransformMetaInfo == NULL ){ //TODO + return; } const double dtr = (atan(1.0) * 4.0) / 180.0; From 2a6a8d49224618d4bc2c132e83c0f4ba0268f17c Mon Sep 17 00:00:00 2001 From: Proton local user Date: Mon, 8 May 2023 17:54:16 +0200 Subject: [PATCH 35/49] Solved bug that would cause crash when trying to change parameters of regEngine with CT not yet loaded (example loading Scout LONG in DataView). Minor changes in UI functionalities to adjust for this new behaviour. Now loading of scouts is automatically followed by visualisation --- .../itkDTRrecon/itkImageProcessor.cpp | 30 +++++++++++++++---- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp index 17e53c8..c1c6b8c 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp @@ -694,13 +694,13 @@ int itkImageProcessor::fill3DVolumeMeta( } if(m_DRTImage2MetaInfo != NULL){ - std::cout << "NEVER HERE m_DRTImage2MetaInfo" << std::endl; - m_DRTImage2MetaInfo = NULL; + std::cout << "NEVER HERE m_DRTImage2MetaInfo" << std::endl; + m_DRTImage2MetaInfo = NULL; } if(m_RTMetaInfo != NULL){ - std::cout << "NEVER HERE m_RTMetaInfo" << std::endl; - m_RTMetaInfo = NULL; + std::cout << "NEVER HERE m_RTMetaInfo" << std::endl; + m_RTMetaInfo = NULL; } @@ -1122,7 +1122,6 @@ int itkImageProcessor::load2D(const char * pcFName){ //double* m_ImageIntensity; DuplicatorType::Pointer m_Duplicator; - bool* m_ImLoaded; TopogramImageMetaInformation::Pointer m_TImageMeta; switch (currProjOrientation) { @@ -1783,6 +1782,7 @@ void itkImageProcessor::InitializeProjector() m_DRTImage2MetaInfo == NULL || m_DRTGeometryMetaInfo == NULL || m_TransformMetaInfo == NULL ){ + return; //TODO } @@ -2076,18 +2076,22 @@ void itkImageProcessor::loadRTPlanInfo( void itkImageProcessor::UpdateProjectionGeometryMeta(){ if(m_CTMetaInfo == NULL){ + return; //TODO. } if(m_DRTGeometryMetaInfo == NULL){ + return; //TODO. } if(m_DRTImage1MetaInfo == NULL){ + return; //TODO. } if(m_DRTImage2MetaInfo == NULL){ + return; //TODO. } @@ -2325,6 +2329,7 @@ void itkImageProcessor::GetProjectionImages(){ m_DRTImage2MetaInfo == NULL || m_DRTGeometryMetaInfo == NULL || m_TransformMetaInfo == NULL ){ + return; //TODO } @@ -2697,6 +2702,14 @@ vtkImageData* itkImageProcessor::GetLocalizer2VTK() vtkImageData* itkImageProcessor::GetProjection1VTK() { + + if(m_DRTImage1MetaInfo == NULL || + m_DRTGeometryMetaInfo == NULL || + m_TransformMetaInfo == NULL ){ + return NULL; + //TODO + } + // Rescale the intensity of the projection images to 0-32768 for output. using RescaleFilterType = itk::RescaleIntensityImageFilter; @@ -2826,6 +2839,13 @@ vtkMatrix4x4 * itkImageProcessor::GetProjection2VTKTransform() vtkImageData* itkImageProcessor::GetProjection2VTK() { + if(m_DRTImage2MetaInfo == NULL || + m_DRTGeometryMetaInfo == NULL || + m_TransformMetaInfo == NULL ){ + return NULL; + //TODO + } + // Rescale the intensity of the projection images to 0-32768 for output. using RescaleFilterType = itk::RescaleIntensityImageFilter; From 9f126e8a34e34dba7b6a2170333e3ef6fd92303b Mon Sep 17 00:00:00 2001 From: Proton local user Date: Thu, 11 May 2023 09:41:10 +0200 Subject: [PATCH 36/49] debug commented --- reg23Topograms/itkDTRrecon/itkImageProcessor.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp index 63925cc..92e9645 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp @@ -2384,6 +2384,13 @@ void itkImageProcessor::GetProjectionImages(){ transform1 ->SetCenter( m_DRTImage1MetaInfo->GetProjectionOriginLPSZero()); + std::cout<< "CurrTransform Rotations: "<< + CurrTransform->GetAngleX() <<" "<< + CurrTransform->GetAngleY() <<" "<< + CurrTransform->GetAngleZ() <<" "<< std::endl; + + std::cout<< "CurrTransform Translations: "<< + CurrTransform->GetTranslation()<Print(std::cout); // The parameters of interpolator1, such as ProjectionAngle and FocalPointToIsocenterDistance From 07db1193150445bf0c1804a07e691576ff606c26 Mon Sep 17 00:00:00 2001 From: Proton local user Date: Fri, 12 May 2023 13:29:02 +0200 Subject: [PATCH 37/49] backup before changing meta reg --- .../itkTwoProjectionImageRegistrationMethod.hxx | 2 +- .../autoreg/itkgTwoImageToOneImageMetric.hxx | 16 ++++++++-------- reg23Topograms/itkDTRrecon/itkImageProcessor.cpp | 5 ++++- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/reg23Topograms/itkDTRrecon/autoreg/itkTwoProjectionImageRegistrationMethod.hxx b/reg23Topograms/itkDTRrecon/autoreg/itkTwoProjectionImageRegistrationMethod.hxx index b6f4b12..81a7e91 100644 --- a/reg23Topograms/itkDTRrecon/autoreg/itkTwoProjectionImageRegistrationMethod.hxx +++ b/reg23Topograms/itkDTRrecon/autoreg/itkTwoProjectionImageRegistrationMethod.hxx @@ -201,7 +201,7 @@ void TwoProjectionImageRegistrationMethod::OnInternal // if (m_CancelRequest) // filter->SetAbortGenerateData(true); // may be handled by filter - std::cout << "Porca Madonna " << std::endl; + std::cout << "OnInternalFilterProgressReceptor :: filter (TURE) " << std::endl; } } diff --git a/reg23Topograms/itkDTRrecon/autoreg/itkgTwoImageToOneImageMetric.hxx b/reg23Topograms/itkDTRrecon/autoreg/itkgTwoImageToOneImageMetric.hxx index 90a9548..0e9c600 100644 --- a/reg23Topograms/itkDTRrecon/autoreg/itkgTwoImageToOneImageMetric.hxx +++ b/reg23Topograms/itkDTRrecon/autoreg/itkgTwoImageToOneImageMetric.hxx @@ -97,14 +97,14 @@ bool gTwoImageToOneImageMetric::SetTransformParameter break; } -// std::cout << "New Transform Parameters = " << std::endl; -// std::cout << " Translation X = " << TranslationAlongX << " mm" << std::endl; -// std::cout << " Translation Y = " << TranslationAlongY << " mm" << std::endl; -// std::cout << " Translation Z = " << TranslationAlongZ << " mm" << std::endl; -// std::cout << " Rotation Along X = " << RotationAlongX / dtr << " deg" << std::endl; -// std::cout << " Rotation Along Y = " << RotationAlongY / dtr << " deg" << std::endl; -// std::cout << " Rotation Along Z = " << RotationAlongZ / dtr << " deg" << std::endl; -// std::cout << "+++++++++++++++++++++++++++++++++++++++++++++++++++++++" << std::endl; + std::cout << "New Transform Parameters = " << std::endl; + std::cout << " Translation X = " << TranslationAlongX << " mm" << std::endl; + std::cout << " Translation Y = " << TranslationAlongY << " mm" << std::endl; + std::cout << " Translation Z = " << TranslationAlongZ << " mm" << std::endl; + std::cout << " Rotation Along X = " << RotationAlongX / dtr << " deg" << std::endl; + std::cout << " Rotation Along Y = " << RotationAlongY / dtr << " deg" << std::endl; + std::cout << " Rotation Along Z = " << RotationAlongZ / dtr << " deg" << std::endl; + std::cout << "+++++++++++++++++++++++++++++++++++++++++++++++++++++++" << std::endl; transformParameters[0] = RotationAlongX; transformParameters[1] = RotationAlongY; diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp index 36699a1..0049101 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp @@ -1734,8 +1734,11 @@ int itkImageProcessor::StartRegistration(std::string extraInfo) m_OptmizerValue = optimizer->GetValue(); - auto finalParameters = transform1->GetParameters(); + std::cout<<"-->startParameters "<finalParameters1 "<GetParameters()<finalParameters2 "<GetParameters()<GetCurrentPosition(); finalParameters = finalParameters - startParameters; From c67281a10a038e0892e8e825fa9692d963cf9c73 Mon Sep 17 00:00:00 2001 From: Proton local user Date: Fri, 12 May 2023 14:00:32 +0200 Subject: [PATCH 38/49] new R23MetaInfo so that R23 does not need TransformMeta anymore --- .../itkDTRrecon/DRTMetaInformation.cpp | 26 +++++++- .../itkDTRrecon/DRTMetaInformation.h | 64 +++++++++++++++---- .../itkTwoProjectionImageRegistrationMethod.h | 9 ++- .../autoreg/itkgTwoImageToOneImageMetric.h | 6 +- .../autoreg/itkgTwoImageToOneImageMetric.hxx | 4 +- .../itkDTRrecon/itkImageProcessor.cpp | 17 +++-- .../itkDTRrecon/itkImageProcessor.h | 23 +------ 7 files changed, 103 insertions(+), 46 deletions(-) diff --git a/reg23Topograms/itkDTRrecon/DRTMetaInformation.cpp b/reg23Topograms/itkDTRrecon/DRTMetaInformation.cpp index 55ada69..9b0c1dc 100644 --- a/reg23Topograms/itkDTRrecon/DRTMetaInformation.cpp +++ b/reg23Topograms/itkDTRrecon/DRTMetaInformation.cpp @@ -518,7 +518,27 @@ RTGeometryMetaInformation } +R23MetaInformation:: +R23MetaInformation (){ + m_DegreeOfFreedom = tDegreeOfFreedomEnum::UNKNOWN; + +} + + +void +R23MetaInformation +::PrintSelf(std::ostream& os, itk::Indent indent) const +{ + Superclass::PrintSelf(os, indent); +} + + +R23MetaInformation +::~R23MetaInformation () +{ + +} TransformMetaInformation :: TransformMetaInformation (){ @@ -531,11 +551,11 @@ TransformMetaInformation (){ m_UserTranslations.Fill(0.); - m_ReferenceTransform.Fill(0.); + //m_ReferenceTransform.Fill(0.); - m_CurrentTransform.Fill(0.); + //m_CurrentTransform.Fill(0.); - m_DegreeOfFreedom = tDegreeOfFreedomEnum::UNKNOWN; + // m_DegreeOfFreedom = tDegreeOfFreedomEnum::UNKNOWN; } diff --git a/reg23Topograms/itkDTRrecon/DRTMetaInformation.h b/reg23Topograms/itkDTRrecon/DRTMetaInformation.h index 1f77f24..917a7f2 100644 --- a/reg23Topograms/itkDTRrecon/DRTMetaInformation.h +++ b/reg23Topograms/itkDTRrecon/DRTMetaInformation.h @@ -514,6 +514,48 @@ private: }; +class R23MetaInformation : + public itk::Object{ + +public: + /** standard typedefs **/ + typedef R23MetaInformation Self; + typedef itk::Object Superclass; + typedef itk::SmartPointer Pointer; + + + /** Method for creation through the object factory. */ + itkNewMacro(Self); + + /** Run-time type information (and related methods). */ + itkTypeMacro(R23MetaInformation, itk::Object); + + /** object information streaming **/ + void PrintSelf(std::ostream& os, itk::Indent indent) const; + + itkSetEnumMacro(DegreeOfFreedom, tDegreeOfFreedomEnum); + itkGetEnumMacro(DegreeOfFreedom, tDegreeOfFreedomEnum); + + +protected: + + tDegreeOfFreedomEnum + m_DegreeOfFreedom; + + /** Default Constructor **/ + R23MetaInformation (); + /** Default Destructor **/ + virtual ~R23MetaInformation (); + +private: + /** purposely not implemented **/ + R23MetaInformation (const Self&); + + /** purposely not implemented **/ + void operator=(const Self&); + +}; + class TransformMetaInformation : public itk::Object{ @@ -547,14 +589,14 @@ public: itkSetMacro(UserRotations,PointType); itkGetMacro(UserRotations,PointType); - itkSetMacro(ReferenceTransform,TransformMatrixType); - itkGetMacro(ReferenceTransform,TransformMatrixType); +// itkSetMacro(ReferenceTransform,TransformMatrixType); +// itkGetMacro(ReferenceTransform,TransformMatrixType); - itkSetMacro(CurrentTransform,TransformMatrixType); - itkGetMacro(CurrentTransform,TransformMatrixType); +// itkSetMacro(CurrentTransform,TransformMatrixType); +// itkGetMacro(CurrentTransform,TransformMatrixType); - itkSetEnumMacro(DegreeOfFreedom, tDegreeOfFreedomEnum); - itkGetEnumMacro(DegreeOfFreedom, tDegreeOfFreedomEnum); +// itkSetEnumMacro(DegreeOfFreedom, tDegreeOfFreedomEnum); +// itkGetEnumMacro(DegreeOfFreedom, tDegreeOfFreedomEnum); protected: @@ -564,12 +606,12 @@ protected: m_UserTranslations, m_UserRotations; - TransformMatrixType - m_ReferenceTransform, - m_CurrentTransform; +// TransformMatrixType +// m_ReferenceTransform, +// m_CurrentTransform; - tDegreeOfFreedomEnum - m_DegreeOfFreedom; +// tDegreeOfFreedomEnum +// m_DegreeOfFreedom; /** Default Constructor **/ TransformMetaInformation (); diff --git a/reg23Topograms/itkDTRrecon/autoreg/itkTwoProjectionImageRegistrationMethod.h b/reg23Topograms/itkDTRrecon/autoreg/itkTwoProjectionImageRegistrationMethod.h index 3dd6241..7770224 100644 --- a/reg23Topograms/itkDTRrecon/autoreg/itkTwoProjectionImageRegistrationMethod.h +++ b/reg23Topograms/itkDTRrecon/autoreg/itkTwoProjectionImageRegistrationMethod.h @@ -170,8 +170,8 @@ public: itkGetConstObjectMacro(Interpolator2, InterpolatorType); /** Set/Get the Meta informations. */ - itkSetObjectMacro(TransformMetaInfo, TransformMetaInformation); - itkGetConstObjectMacro(TransformMetaInfo, TransformMetaInformation); + itkSetObjectMacro(TransformMetaInfo, R23MetaInformation); + itkGetConstObjectMacro(TransformMetaInfo, R23MetaInformation); /** Set/Get the output filters. */ itkSetObjectMacro(Filter1, ChangeInformationFilterType); @@ -253,7 +253,10 @@ private: InterpolatorPointer m_Interpolator1; InterpolatorPointer m_Interpolator2; - TransformMetaInformation::Pointer + //TransformMetaInformation::Pointer + // m_TransformMetaInfo; + + R23MetaInformation::Pointer m_TransformMetaInfo; ChangeInformationFilterPointer diff --git a/reg23Topograms/itkDTRrecon/autoreg/itkgTwoImageToOneImageMetric.h b/reg23Topograms/itkDTRrecon/autoreg/itkgTwoImageToOneImageMetric.h index 9cb93cb..c3d8712 100644 --- a/reg23Topograms/itkDTRrecon/autoreg/itkgTwoImageToOneImageMetric.h +++ b/reg23Topograms/itkDTRrecon/autoreg/itkgTwoImageToOneImageMetric.h @@ -185,10 +185,10 @@ public: itkGetConstReferenceMacro(NumberOfPixelsCounted, unsigned long); /** Connect the DRTGeometryMetaInfo. */ - itkSetObjectMacro(TransformMetaInfo, TransformMetaInformation); + itkSetObjectMacro(TransformMetaInfo, R23MetaInformation); /** Get a pointer to the DRTGeometryMetaInfo. */ - itkGetConstObjectMacro(TransformMetaInfo, TransformMetaInformation); + itkGetConstObjectMacro(TransformMetaInfo, R23MetaInformation); /** Set the region over which the metric will be computed */ itkSetMacro(FixedImageRegion1, FixedImageRegionType); @@ -274,7 +274,7 @@ protected: mutable FixedImageMaskPointer m_FixedImageMask2; mutable MovingImageMaskPointer m_MovingImageMask; - TransformMetaInformation::Pointer + R23MetaInformation::Pointer m_TransformMetaInfo; ChangeInformationFilterPointer diff --git a/reg23Topograms/itkDTRrecon/autoreg/itkgTwoImageToOneImageMetric.hxx b/reg23Topograms/itkDTRrecon/autoreg/itkgTwoImageToOneImageMetric.hxx index 0e9c600..d4ea48a 100644 --- a/reg23Topograms/itkDTRrecon/autoreg/itkgTwoImageToOneImageMetric.hxx +++ b/reg23Topograms/itkDTRrecon/autoreg/itkgTwoImageToOneImageMetric.hxx @@ -113,7 +113,9 @@ bool gTwoImageToOneImageMetric::SetTransformParameter transformParameters[4] = TranslationAlongY; transformParameters[5] = TranslationAlongZ; - bool transformValid = (std::abs(TranslationAlongX) < m_MaxTranslation) && (std::abs(TranslationAlongY) < m_MaxTranslation) && (std::abs(TranslationAlongZ) < m_MaxTranslation); + bool transformValid = (std::abs(TranslationAlongX) < m_MaxTranslation) && + (std::abs(TranslationAlongY) < m_MaxTranslation) && + (std::abs(TranslationAlongZ) < m_MaxTranslation); if (transformValid) { m_Transform1->SetParameters(transformParameters); diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp index 0049101..66326dd 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp @@ -118,6 +118,9 @@ itkImageProcessor::itkImageProcessor() m_TransformMetaInfo = NULL; m_TransformMetaInfo = TransformMetaInformation::New(); + m_r23MetaInfo = NULL; + m_r23MetaInfo = R23MetaInformation::New(); + /* Initialise the projection geoemtry with defaults */ m_DRTGeometryMetaInfo = NULL; m_DRTGeometryMetaInfo @@ -284,13 +287,16 @@ double itkImageProcessor::GetPanelOffset2(){ void itkImageProcessor::SetDegreeOfFreedom(tDegreeOfFreedomEnum dof) { - m_TransformMetaInfo->SetDegreeOfFreedom(dof); + // m_TransformMetaInfo->SetDegreeOfFreedom(dof); + m_r23MetaInfo->SetDegreeOfFreedom(dof); } tDegreeOfFreedomEnum itkImageProcessor::GetDegreeOfFreedom() { - return m_TransformMetaInfo->GetDegreeOfFreedom(); + return + m_r23MetaInfo->GetDegreeOfFreedom(); + //m_TransformMetaInfo->GetDegreeOfFreedom(); } void itkImageProcessor::SetCustom_ImportTransform(double dTx, @@ -428,6 +434,7 @@ int itkImageProcessor::unload3DVolumeAndMeta(){ m_TransformMetaInfo = NULL; m_TransformMetaInfo = TransformMetaInformation::New(); + return 1; } @@ -1436,7 +1443,8 @@ void itkImageProcessor::InitializeRegistration( metric->SetSubtractMean(true); metric->SetMaxTranslation(maxTranslation); - m_TransformMetaInfo->SetDegreeOfFreedom(dof); +// m_TransformMetaInfo->SetDegreeOfFreedom(dof); + m_r23MetaInfo->SetDegreeOfFreedom(dof); mimetric->ComputeGradientOff(); @@ -1479,7 +1487,8 @@ void itkImageProcessor::InitializeRegistration( } - registration->SetTransformMetaInfo(m_TransformMetaInfo); +// registration->SetTransformMetaInfo(m_TransformMetaInfo); + registration->SetTransformMetaInfo(m_r23MetaInfo); registration->SetFilter1(filter1); registration->SetFilter2(filter2); diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.h b/reg23Topograms/itkDTRrecon/itkImageProcessor.h index 553212e..5a25620 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.h +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.h @@ -269,18 +269,6 @@ private: TransformType::Pointer transform, DRTImageMetaInformation::Pointer imageMetaInfo); -// TransformType::Pointer -// CalculateInternalTransform( -// ImageType3D::PointType m_TranslationOffset, -// ImageType3D::PointType m_RotationOffset, -// ImageType3D::PointType m_TranslationUser, -// ImageType3D::PointType m_RotationUser, -// ImageType3D::PointType m_ProjectionTransformCenter, -// ImageType3D::PointType m_UserTransformCenter, -// ImageType3D::PointType m_OffsetTransformCenter, -// InternalImageType::DirectionType m_IECtoLPSDirections -// ); - /* Calculate the transform used in siddon. * The isocentric transform is mapped to the calibrated center of projection */ TransformType::Pointer @@ -294,8 +282,6 @@ private: InternalImageType::DirectionType m_IECtoLPSDirections ); - - TransformType::Pointer transform1, transform2; @@ -360,13 +346,6 @@ private: ); -// ImageType3D::PointType -// CalcDRTImageOffset( -// ImageType3D::PointType m_DRTOffset, -// double dAngle, -// InternalImageType::DirectionType stdDRT2LPS -// ); - TransformType::Pointer MapTransformToNewOrigin( ImageType3D::PointType m_COR, @@ -433,6 +412,8 @@ private: TransformMetaInformation::Pointer m_TransformMetaInfo; + R23MetaInformation::Pointer + m_r23MetaInfo; double m_OptmizerValue; int m_MaxNumberOfIterations; From 9a8faa0693d58c9f90501f9f4824631073ec4344 Mon Sep 17 00:00:00 2001 From: Proton local user Date: Fri, 12 May 2023 14:55:17 +0200 Subject: [PATCH 39/49] Simplified CalcInternalTransformV3 which makes use of T and R calculated by the transform Meta --- .../itkDTRrecon/DRTMetaInformation.cpp | 34 +- .../itkDTRrecon/DRTMetaInformation.h | 28 +- .../itkDTRrecon/itkImageProcessor.cpp | 402 +++++++++--------- .../itkDTRrecon/itkImageProcessor.h | 9 + 4 files changed, 261 insertions(+), 212 deletions(-) diff --git a/reg23Topograms/itkDTRrecon/DRTMetaInformation.cpp b/reg23Topograms/itkDTRrecon/DRTMetaInformation.cpp index 9b0c1dc..8395221 100644 --- a/reg23Topograms/itkDTRrecon/DRTMetaInformation.cpp +++ b/reg23Topograms/itkDTRrecon/DRTMetaInformation.cpp @@ -543,9 +543,9 @@ R23MetaInformation TransformMetaInformation :: TransformMetaInformation (){ - m_Translations.Fill(0.); + m_HiddenTranslations.Fill(0.); - m_Rotations.Fill(0.); + m_HiddenRotations.Fill(0.); m_UserRotations.Fill(0.); @@ -559,6 +559,36 @@ TransformMetaInformation (){ } +TransformMetaInformation::PointType +TransformMetaInformation::GetT(){ + + PointType + pT; + + pT[0] = m_UserTranslations[0] + m_HiddenTranslations[0]; + pT[1] = m_UserTranslations[1] + m_HiddenTranslations[1]; + pT[2] = m_UserTranslations[2] + m_HiddenTranslations[2]; + + return + pT; + +} + +TransformMetaInformation::PointType +TransformMetaInformation::TransformMetaInformation::GetR(){ + + PointType + pR; + + pR[0] = m_UserRotations[0] + m_HiddenRotations[0]; + pR[1] = m_UserRotations[1] + m_HiddenRotations[1]; + pR[2] = m_UserRotations[2] + m_HiddenRotations[2]; + + return + pR; + +} + void TransformMetaInformation ::PrintSelf(std::ostream& os, itk::Indent indent) const diff --git a/reg23Topograms/itkDTRrecon/DRTMetaInformation.h b/reg23Topograms/itkDTRrecon/DRTMetaInformation.h index 917a7f2..f797b30 100644 --- a/reg23Topograms/itkDTRrecon/DRTMetaInformation.h +++ b/reg23Topograms/itkDTRrecon/DRTMetaInformation.h @@ -577,11 +577,11 @@ public: void PrintSelf(std::ostream& os, itk::Indent indent) const; - itkSetMacro(Translations,PointType); - itkGetMacro(Translations,PointType); + itkSetMacro(HiddenTranslations,PointType); + itkGetMacro(HiddenTranslations,PointType); - itkSetMacro(Rotations,PointType); - itkGetMacro(Rotations,PointType); + itkSetMacro(HiddenRotations,PointType); + itkGetMacro(HiddenRotations,PointType); itkSetMacro(UserTranslations,PointType); itkGetMacro(UserTranslations,PointType); @@ -589,29 +589,17 @@ public: itkSetMacro(UserRotations,PointType); itkGetMacro(UserRotations,PointType); -// itkSetMacro(ReferenceTransform,TransformMatrixType); -// itkGetMacro(ReferenceTransform,TransformMatrixType); - -// itkSetMacro(CurrentTransform,TransformMatrixType); -// itkGetMacro(CurrentTransform,TransformMatrixType); - -// itkSetEnumMacro(DegreeOfFreedom, tDegreeOfFreedomEnum); -// itkGetEnumMacro(DegreeOfFreedom, tDegreeOfFreedomEnum); + PointType GetT(); + PointType GetR(); protected: PointType - m_Translations, - m_Rotations, + m_HiddenTranslations, + m_HiddenRotations, m_UserTranslations, m_UserRotations; -// TransformMatrixType -// m_ReferenceTransform, -// m_CurrentTransform; - -// tDegreeOfFreedomEnum -// m_DegreeOfFreedom; /** Default Constructor **/ TransformMetaInformation (); diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp index 66326dd..c828274 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp @@ -136,7 +136,7 @@ itkImageProcessor::itkImageProcessor() Point3D[1]=0.; Point3D[2]=175.; m_DRTGeometryMetaInfo->SetProjectionCenter(Point3D); -// m_DRTGeometryMetaInfo->SetProjectionCenter(Point3D); + // m_DRTGeometryMetaInfo->SetProjectionCenter(Point3D); ImageType3D::SizeType ImageSize; ImageSize[0]=512; @@ -287,7 +287,7 @@ double itkImageProcessor::GetPanelOffset2(){ void itkImageProcessor::SetDegreeOfFreedom(tDegreeOfFreedomEnum dof) { - // m_TransformMetaInfo->SetDegreeOfFreedom(dof); + // m_TransformMetaInfo->SetDegreeOfFreedom(dof); m_r23MetaInfo->SetDegreeOfFreedom(dof); } @@ -296,7 +296,7 @@ itkImageProcessor::GetDegreeOfFreedom() { return m_r23MetaInfo->GetDegreeOfFreedom(); - //m_TransformMetaInfo->GetDegreeOfFreedom(); + //m_TransformMetaInfo->GetDegreeOfFreedom(); } void itkImageProcessor::SetCustom_ImportTransform(double dTx, @@ -523,11 +523,11 @@ int itkImageProcessor::load3DSerieFromFiles( std::vector v_fnames){ if (m_VolumeSourceDupli == NULL) std::cout << "NEVER HERE m_VolumeSourceDupli" << std::endl; -// if (m_VolumeSourceDupli) { -// std::cout << "NEVER HERE m_VolumeSourceDupli" << std::endl; -// m_VolumeSourceDupli = NULL; -// m_VolumeSourceDupli = DuplicatorType::New(); -// } + // if (m_VolumeSourceDupli) { + // std::cout << "NEVER HERE m_VolumeSourceDupli" << std::endl; + // m_VolumeSourceDupli = NULL; + // m_VolumeSourceDupli = DuplicatorType::New(); + // } m_VolumeSourceDupli->SetInputImage(caster3D->GetOutput()); m_VolumeSourceDupli->Update(); @@ -538,7 +538,7 @@ int itkImageProcessor::load3DSerieFromFiles( std::vector v_fnames){ } catch (itk::ExceptionObject & ex) { -// std::cout << ex << std::endl; + // std::cout << ex << std::endl; return EXIT_FAILURE; } @@ -755,22 +755,22 @@ int itkImageProcessor::fill3DVolumeMeta( m_DRTGeometryMetaInfo->GetSCD2Offset() ); -// std::cout<< "///////////////// 3D VOLUME BEG ///////////////" <GetOriginLPS() <GetCOV() <GetOriginLPS() <GetCOV() <GetImportOffset() <GetLPS2IECDirections() <GetSize() <GetSpacing() <GetLPS2IECDirections() <GetSize() <GetSpacing() <GetProjectionAngleLPS() <GetSCD() <GetProjectionAngleLPS() <GetSCD() <GetProjectionAngleLPS() <GetSCD() <GetProjectionAngleLPS() <GetSCD() <UpdateProjectionGeometryMeta(); @@ -911,7 +911,7 @@ void itkImageProcessor::SetProjectionAngleOffsetIEC(double dOff1, double dOff2) m_DRTGeometryMetaInfo->SetProjectionAngle1OffsetIEC(dOff1); m_DRTGeometryMetaInfo->SetProjectionAngle2OffsetIEC(dOff2); - std::cout << "SetProjectionAngleOffsetIEC " << dOff1 << " " << dOff2 << std::endl; + std::cout << "SetProjectionAngleOffsetIEC " << dOff1 << " " << dOff2 << std::endl; } @@ -986,7 +986,7 @@ int itkImageProcessor::load2D(const char * pcFName){ strcpy( sTmpString,gGetStringValueFromTag( gdcm::Tag(0x0008,0x0008), ds)); std::string sLocalizerString = "LOCALIZER"; if (std::string(sTmpString).find(sLocalizerString) != std::string::npos) { -// std::cout << "Loading Localizer: "<GetOutput()->GetDirection(); -// std::cout<<"LocalizerImagDirectionDCM " <Update(); -// std::cout<< " ////////////// 2D Topo BEG " <GetOutput()->GetDirection()<GetOutput()->GetOrigin()<GetOutput()->GetSpacing()<GetOutput()->GetLargestPossibleRegion().GetSize()<GetOutput()->GetDirection()<GetOutput()->GetOrigin()<GetOutput()->GetSpacing()<GetOutput()->GetLargestPossibleRegion().GetSize()<SetCenter(m_CalibratedProjectionCenter); + + return m_outputTransform; + +} + + void itkImageProcessor::InitializeRegistration( double stepLength, double maxTranslation, @@ -1443,7 +1476,7 @@ void itkImageProcessor::InitializeRegistration( metric->SetSubtractMean(true); metric->SetMaxTranslation(maxTranslation); -// m_TransformMetaInfo->SetDegreeOfFreedom(dof); + // m_TransformMetaInfo->SetDegreeOfFreedom(dof); m_r23MetaInfo->SetDegreeOfFreedom(dof); mimetric->ComputeGradientOff(); @@ -1487,7 +1520,7 @@ void itkImageProcessor::InitializeRegistration( } -// registration->SetTransformMetaInfo(m_TransformMetaInfo); + // registration->SetTransformMetaInfo(m_TransformMetaInfo); registration->SetTransformMetaInfo(m_r23MetaInfo); registration->SetFilter1(filter1); @@ -1504,28 +1537,27 @@ void itkImageProcessor::InitializeRegistration( if(m_RTMetaInfo == NULL) { CurrTransform = - CalculateInternalTransformV2( - ZeroPoint, - ZeroPoint, - m_TransformMetaInfo->GetTranslations(), - m_TransformMetaInfo->GetRotations(), + CalculateInternalTransformV3( + m_TransformMetaInfo->GetT(), + m_TransformMetaInfo->GetR(), m_DRTImage1MetaInfo->GetProjectionOriginLPSZero(), m_DRTImage1MetaInfo->GetProjectionOriginLPS(), - IECtoLPS_Directions - ); + IECtoLPS_Directions); + } else { - CurrTransform = CalculateInternalTransformV2( - ZeroPoint , - m_DRTGeometryMetaInfo->GetIECS2IECScannerR(), - m_TransformMetaInfo->GetTranslations(), - m_TransformMetaInfo->GetRotations(), + CurrTransform = + CalculateInternalTransformV3( + m_TransformMetaInfo->GetT(), + m_TransformMetaInfo->GetR(), m_DRTImage1MetaInfo->GetProjectionOriginLPSZero(), m_RTMetaInfo->GetIsocenterLPS() - m_CTMetaInfo->GetOriginLPS(), IECtoLPS_Directions ); + + } @@ -1548,29 +1580,26 @@ void itkImageProcessor::InitializeRegistration( /********* BEGIN CALCULATION OF INTERNAL TRANSFORM FOR PROJ2 *********/ if(m_RTMetaInfo == NULL) { - CurrTransform = - CalculateInternalTransformV2( - ZeroPoint, - ZeroPoint, - m_TransformMetaInfo->GetTranslations(), - m_TransformMetaInfo->GetRotations(), - m_DRTImage2MetaInfo->GetProjectionOriginLPSZero(), - m_DRTImage2MetaInfo->GetProjectionOriginLPS(), - IECtoLPS_Directions - ); + CurrTransform = + CalculateInternalTransformV3( + m_TransformMetaInfo->GetT(), + m_TransformMetaInfo->GetR(), + m_DRTImage2MetaInfo->GetProjectionOriginLPSZero(), + m_DRTImage2MetaInfo->GetProjectionOriginLPS(), + IECtoLPS_Directions); + } else { - CurrTransform = CalculateInternalTransformV2( - ZeroPoint, - m_DRTGeometryMetaInfo->GetIECS2IECScannerR(), - m_TransformMetaInfo->GetTranslations(), - m_TransformMetaInfo->GetRotations(), - m_DRTImage2MetaInfo->GetProjectionOriginLPSZero(), - m_RTMetaInfo->GetIsocenterLPS() - m_CTMetaInfo->GetOriginLPS(), - IECtoLPS_Directions - ); + CurrTransform = + CalculateInternalTransformV3( + m_TransformMetaInfo->GetT(), + m_TransformMetaInfo->GetR(), + m_DRTImage2MetaInfo->GetProjectionOriginLPSZero(), + m_RTMetaInfo->GetIsocenterLPS() - m_CTMetaInfo->GetOriginLPS(), + IECtoLPS_Directions + ); } @@ -1707,10 +1736,10 @@ int itkImageProcessor::StartRegistration(std::string extraInfo) } try { -// timer.Start("Registration"); + // timer.Start("Registration"); // Start the registration. registration->StartRegistration(); -// timer.Stop("Registration"); + // timer.Stop("Registration"); } catch (itk::ExceptionObject& err) { registration->ResetPipeline(); @@ -1818,29 +1847,25 @@ void itkImageProcessor::InitializeProjector() if(m_RTMetaInfo == NULL) { - CurrTransform = CalculateInternalTransformV2( - ZeroPoint , - ZeroPoint , - m_TransformMetaInfo->GetTranslations(), - m_TransformMetaInfo->GetRotations(), - m_DRTImage1MetaInfo->GetProjectionOriginLPSZero(), - m_DRTImage1MetaInfo->GetProjectionOriginLPS(), - IECtoLPS_Directions - ); + CurrTransform = CalculateInternalTransformV3( + m_TransformMetaInfo->GetT(), + m_TransformMetaInfo->GetR(), + m_DRTImage1MetaInfo->GetProjectionOriginLPSZero(), + m_DRTImage1MetaInfo->GetProjectionOriginLPS(), + IECtoLPS_Directions); + } else { - CurrTransform = CalculateInternalTransformV2( - ZeroPoint , - m_DRTGeometryMetaInfo->GetIECS2IECScannerR(), - m_TransformMetaInfo->GetTranslations(), - m_TransformMetaInfo->GetRotations(), - m_DRTImage1MetaInfo->GetProjectionOriginLPSZero(), - m_RTMetaInfo->GetIsocenterLPS() - m_CTMetaInfo->GetOriginLPS(), - IECtoLPS_Directions - ); - + CurrTransform = + CalculateInternalTransformV3( + m_TransformMetaInfo->GetT(), + m_TransformMetaInfo->GetR(), + m_DRTImage1MetaInfo->GetProjectionOriginLPSZero(), + m_RTMetaInfo->GetIsocenterLPS() - m_CTMetaInfo->GetOriginLPS(), + IECtoLPS_Directions + ); } @@ -1877,28 +1902,25 @@ void itkImageProcessor::InitializeProjector() { CurrTransform = - CalculateInternalTransformV2( - ZeroPoint, - ZeroPoint, - m_TransformMetaInfo->GetTranslations(), - m_TransformMetaInfo->GetRotations(), - m_DRTImage2MetaInfo->GetProjectionOriginLPSZero(), - m_DRTImage2MetaInfo->GetProjectionOriginLPS(), - IECtoLPS_Directions - ); + CalculateInternalTransformV3( + m_TransformMetaInfo->GetT(), + m_TransformMetaInfo->GetR(), + m_DRTImage2MetaInfo->GetProjectionOriginLPSZero(), + m_DRTImage2MetaInfo->GetProjectionOriginLPS(), + IECtoLPS_Directions); + } else { - CurrTransform = CalculateInternalTransformV2( - ZeroPoint, - m_DRTGeometryMetaInfo->GetIECS2IECScannerR(), - m_TransformMetaInfo->GetTranslations(), - m_TransformMetaInfo->GetRotations(), + CurrTransform = CalculateInternalTransformV3( + m_TransformMetaInfo->GetT(), + m_TransformMetaInfo->GetR(), m_DRTImage2MetaInfo->GetProjectionOriginLPSZero(), m_RTMetaInfo->GetIsocenterLPS() - m_CTMetaInfo->GetOriginLPS(), IECtoLPS_Directions ); + } @@ -1985,7 +2007,7 @@ void itkImageProcessor::InitializeProjector() filter1->ChangeOriginOn(); filter1->UpdateOutputInformation(); -// std::cout<< "itkImageProcessor::InitializeProjector() " <Update(); @@ -2033,7 +2055,14 @@ int itkImageProcessor::unloadRTPlanAndMeta(){ std::cout << "*" << __COMPACT_PRETTY_FUNCTION__ << std::endl; m_RTMetaInfo = NULL; - return 1; + ImageType3D::PointType + pZero; + pZero.Fill(0.); + + m_CTMetaInfo->SetImportOffset(pZero); + m_TransformMetaInfo->SetHiddenRotations(pZero); + + return 0; } @@ -2082,6 +2111,9 @@ void itkImageProcessor::loadRTPlanInfo( ) ); + m_TransformMetaInfo->SetHiddenRotations( + m_DRTGeometryMetaInfo->GetIECS2IECScannerR()); + this->UpdateProjectionGeometryMeta(); this->InitializeProjector(); @@ -2133,11 +2165,11 @@ void itkImageProcessor::UpdateProjectionGeometryMeta(){ IsocenterOffsetLPS = m_CTMetaInfo->ConvertIECPointToLPSPoint( m_DRTGeometryMetaInfo->GetProjectionCenterOffset1()); -// std::cout<< "///////////////// PGEOM META BEG ///////////////" <GetProjectionCenter() <GetProjectionCenter() <SetProjectionAngleLPS( this->CalcProjectionAngleLPS( @@ -2334,7 +2366,7 @@ itkImageProcessor::CalcDRTImageOrigin( void itkImageProcessor::GetProjectionImages(){ -// std::cout<< "itkImageProcessor::GetProjectionImages" <GetTranslations(), - m_TransformMetaInfo->GetRotations(), - m_DRTImage1MetaInfo->GetProjectionOriginLPSZero(), - m_DRTImage1MetaInfo->GetProjectionOriginLPS(), - IECtoLPS_Directions - ); + CalculateInternalTransformV3( + m_TransformMetaInfo->GetT(), + m_TransformMetaInfo->GetR(), + m_DRTImage1MetaInfo->GetProjectionOriginLPSZero(), + m_DRTImage1MetaInfo->GetProjectionOriginLPS(), + IECtoLPS_Directions); } else { - CurrTransform = CalculateInternalTransformV2( - ZeroPoint , - m_DRTGeometryMetaInfo->GetIECS2IECScannerR(), - m_TransformMetaInfo->GetTranslations(), - m_TransformMetaInfo->GetRotations(), - m_DRTImage1MetaInfo->GetProjectionOriginLPSZero(), - m_RTMetaInfo->GetIsocenterLPS() - m_CTMetaInfo->GetOriginLPS(), - IECtoLPS_Directions - ); + CurrTransform = + CalculateInternalTransformV3( + m_TransformMetaInfo->GetT(), + m_TransformMetaInfo->GetR(), + m_DRTImage1MetaInfo->GetProjectionOriginLPSZero(), + m_RTMetaInfo->GetIsocenterLPS() - m_CTMetaInfo->GetOriginLPS(), + IECtoLPS_Directions + ); } @@ -2425,23 +2453,18 @@ void itkImageProcessor::GetProjectionImages(){ { CurrTransform = - CalculateInternalTransformV2( - ZeroPoint, - ZeroPoint, - m_TransformMetaInfo->GetTranslations(), - m_TransformMetaInfo->GetRotations(), - m_DRTImage2MetaInfo->GetProjectionOriginLPSZero(), - m_DRTImage2MetaInfo->GetProjectionOriginLPS(), - IECtoLPS_Directions - ); + CalculateInternalTransformV3( + m_TransformMetaInfo->GetT(), + m_TransformMetaInfo->GetR(), + m_DRTImage2MetaInfo->GetProjectionOriginLPSZero(), + m_DRTImage2MetaInfo->GetProjectionOriginLPS(), + IECtoLPS_Directions); } else { - CurrTransform = CalculateInternalTransformV2( - ZeroPoint, - m_DRTGeometryMetaInfo->GetIECS2IECScannerR(), - m_TransformMetaInfo->GetTranslations(), - m_TransformMetaInfo->GetRotations(), + CurrTransform = CalculateInternalTransformV3( + m_TransformMetaInfo->GetT(), + m_TransformMetaInfo->GetR(), m_DRTImage2MetaInfo->GetProjectionOriginLPSZero(), m_RTMetaInfo->GetIsocenterLPS() - m_CTMetaInfo->GetOriginLPS(), IECtoLPS_Directions @@ -2634,22 +2657,22 @@ vtkImageData* itkImageProcessor::GetLocalizer1VTK() ImageType3D::PointType LastVoxelPosition = origin3D + (imagDirection * Dest); -// std::cout<<" -------- Localizer 1 ITK --------"<GetOutput()->GetBounds(); -// std::cout<< "-------- Localizer 1 VTK --------" <SetInput( imageDRT1In ); rescaler1->Update(); -// using ImageCalculatorFilterType = itk::MinimumMaximumImageCalculator; -// auto imageCalculatorFilter = ImageCalculatorFilterType::New(); -// imageCalculatorFilter->SetImage(imageDRT1In); -// imageCalculatorFilter->Compute(); + // using ImageCalculatorFilterType = itk::MinimumMaximumImageCalculator; + // auto imageCalculatorFilter = ImageCalculatorFilterType::New(); + // imageCalculatorFilter->SetImage(imageDRT1In); + // imageCalculatorFilter->Compute(); -// std::cout<< "itkImageProcessor::imageDRT1In() " << -// imageCalculatorFilter <; -// auto imageCalculatorFilter2 = ImageCalculatorFilterType2::New(); -// imageCalculatorFilter2->SetImage(rescaler1->GetOutput()); -// imageCalculatorFilter2->Compute(); -// std::cout<< "itkImageProcessor::imageDRT2In() " << -// imageCalculatorFilter2 <; + // auto imageCalculatorFilter2 = ImageCalculatorFilterType2::New(); + // imageCalculatorFilter2->SetImage(rescaler1->GetOutput()); + // imageCalculatorFilter2->Compute(); + // std::cout<< "itkImageProcessor::imageDRT2In() " << + // imageCalculatorFilter2 <SetInput(rescaler1->GetOutput()); toVTK2D1->Update(); @@ -2908,12 +2931,12 @@ vtkImageData* itkImageProcessor::GetProjection2VTK() - //double* dBounds = toVTK2D2->GetOutput()->GetBounds(); -// std::cout<< "-------- Proj 2 --------" <GetOutput()->GetBounds(); + // std::cout<< "-------- Proj 2 --------" <GetOutput(); @@ -2947,7 +2970,7 @@ void itkImageProcessor::WriteProjectionImages() try { -// std::cout << "Writing image 1 " << std::endl; + // std::cout << "Writing image 1 " << std::endl; writer1->Update(); } catch (itk::ExceptionObject & err) @@ -2961,7 +2984,7 @@ void itkImageProcessor::WriteProjectionImages() try { -// std::cout << "Writing image 2" << std::endl; + // std::cout << "Writing image 2" << std::endl; writer2->Update(); } catch (itk::ExceptionObject & err) @@ -2983,13 +3006,12 @@ void itkImageProcessor::SetInitialTranslations(double dX, double dY, double dZ) //todo } - ImageType3D::PointType Translations; Translations[0]= dX; Translations[1]= dY; Translations[2]= dZ; - m_TransformMetaInfo->SetTranslations(Translations); + m_TransformMetaInfo->SetUserTranslations(Translations); } void itkImageProcessor::SetInitialRotations(double dX, double dY, double dZ) @@ -2999,18 +3021,19 @@ void itkImageProcessor::SetInitialRotations(double dX, double dY, double dZ) Rotations[1]= dY; Rotations[2]= dZ; - m_TransformMetaInfo->SetRotations(Rotations); + m_TransformMetaInfo->SetUserRotations(Rotations); } +// THIS IS READ FOR EXPORT. TO FIX. double* itkImageProcessor::GetTransformParameters(){ ImageType3D::PointType Translations; ImageType3D::PointType Rotations; - Translations = m_TransformMetaInfo->GetTranslations(); - Rotations = m_TransformMetaInfo->GetRotations(); + Translations = m_TransformMetaInfo->GetUserTranslations(); + Rotations = m_TransformMetaInfo->GetUserRotations(); dTransfParam[0] = Translations[0]; dTransfParam[1] = Translations[1]; @@ -3023,27 +3046,26 @@ double* itkImageProcessor::GetTransformParameters(){ return dTransfParam; } -// Doubts about this user thing +// THESE ARE CALLED AT THE END OF REG void itkImageProcessor::GetFinalTranslations(double& dX, double& dY, double& dZ) { - ImageType3D::PointType translations = m_TransformMetaInfo->GetTranslations(); ImageType3D::PointType userTranslations = m_TransformMetaInfo->GetUserTranslations(); - dX = translations[0] + userTranslations[0]; - dY = translations[1] + userTranslations[1]; - dZ = translations[2] + userTranslations[2]; + dX = userTranslations[0]; + dY = userTranslations[1]; + dZ = userTranslations[2]; } +// THESE ARE CALLED AT THE END OF REG void itkImageProcessor::GetFinalRotations(double& dRX, double& dRY, double& dRZ) { - ImageType3D::PointType rotations = m_TransformMetaInfo->GetRotations(); ImageType3D::PointType userRotations = m_TransformMetaInfo->GetUserRotations(); - dRX = rotations[0] + userRotations[0]; - dRY = rotations[1] + userRotations[1]; - dRZ = rotations[2] + userRotations[2]; -} + dRX = userRotations[0]; + dRY = userRotations[1]; + dRZ = userRotations[2]; +} double itkImageProcessor::GetOptimizerValue() { diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.h b/reg23Topograms/itkDTRrecon/itkImageProcessor.h index 5a25620..72af105 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.h +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.h @@ -282,6 +282,15 @@ private: InternalImageType::DirectionType m_IECtoLPSDirections ); + TransformType::Pointer + CalculateInternalTransformV3( + ImageType3D::PointType m_Translation, + ImageType3D::PointType m_Rotation, + ImageType3D::PointType m_CalibratedProjectionCenter, + ImageType3D::PointType m_RTIsocenter, + InternalImageType::DirectionType m_IECtoLPSDirections + ); + TransformType::Pointer transform1, transform2; From 6ad0344791e162433f70f9abb4bac787cb7fd01e Mon Sep 17 00:00:00 2001 From: Proton local user Date: Fri, 12 May 2023 16:13:12 +0200 Subject: [PATCH 40/49] MapTransformToNewOrigin and CalcInternalTransformV3 moved to another file, ouside of scout processor --- reg23Topograms/itkDTRrecon/CMakeLists.txt | 2 + .../itkTwoProjectionImageRegistrationMethod.h | 6 + ...tkTwoProjectionImageRegistrationMethod.hxx | 9 +- .../autoreg/itkgTwoImageToOneImageMetric.h | 6 + .../autoreg/itkgTwoImageToOneImageMetric.hxx | 13 +- .../itkDTRrecon/itkImageProcessor.cpp | 377 +++++++++--------- .../itkDTRrecon/itkImageProcessor.h | 45 +-- .../itkDTRrecon/itkImageProcessorHelpers.cpp | 93 +++++ .../itkDTRrecon/itkImageProcessorHelpers.h | 38 ++ 9 files changed, 377 insertions(+), 212 deletions(-) create mode 100644 reg23Topograms/itkDTRrecon/itkImageProcessorHelpers.cpp create mode 100644 reg23Topograms/itkDTRrecon/itkImageProcessorHelpers.h diff --git a/reg23Topograms/itkDTRrecon/CMakeLists.txt b/reg23Topograms/itkDTRrecon/CMakeLists.txt index fd530ce..e97344c 100644 --- a/reg23Topograms/itkDTRrecon/CMakeLists.txt +++ b/reg23Topograms/itkDTRrecon/CMakeLists.txt @@ -16,6 +16,7 @@ INCLUDE_DIRECTORIES(${GDCM_INCLUDE_DIRS}) SET(SRCS itkImageProcessor.cpp + itkImageProcessorHelpers.cpp vtkContourTopogramProjectionFilter.cxx DRTMetaInformation.cpp @@ -23,6 +24,7 @@ SET(SRCS SET(HDR itkImageProcessor.h + itkImageProcessorHelpers.h itkQtIterationUpdate.h itkgSiddonJacobsRayCastInterpolateImageFunction.h itkgSiddonJacobsRayCastInterpolateImageFunction.hxx diff --git a/reg23Topograms/itkDTRrecon/autoreg/itkTwoProjectionImageRegistrationMethod.h b/reg23Topograms/itkDTRrecon/autoreg/itkTwoProjectionImageRegistrationMethod.h index 7770224..10d638b 100644 --- a/reg23Topograms/itkDTRrecon/autoreg/itkTwoProjectionImageRegistrationMethod.h +++ b/reg23Topograms/itkDTRrecon/autoreg/itkTwoProjectionImageRegistrationMethod.h @@ -163,6 +163,10 @@ public: itkSetObjectMacro(Transform2, TransformType); itkGetConstObjectMacro(Transform2, TransformType); + /** Set/Get the IsocIECTransform. */ + itkSetObjectMacro(IsocIECTransform, TransformType); + itkGetConstObjectMacro(IsocIECTransform, TransformType); + /** Set/Get the Interpolators. */ itkSetObjectMacro(Interpolator1, InterpolatorType); itkSetObjectMacro(Interpolator2, InterpolatorType); @@ -248,6 +252,8 @@ private: FixedImageConstPointer m_FixedImage1; FixedImageConstPointer m_FixedImage2; + TransformPointer m_IsocIECTransform; + TransformPointer m_Transform1; TransformPointer m_Transform2; InterpolatorPointer m_Interpolator1; diff --git a/reg23Topograms/itkDTRrecon/autoreg/itkTwoProjectionImageRegistrationMethod.hxx b/reg23Topograms/itkDTRrecon/autoreg/itkTwoProjectionImageRegistrationMethod.hxx index 81a7e91..fa127aa 100644 --- a/reg23Topograms/itkDTRrecon/autoreg/itkTwoProjectionImageRegistrationMethod.hxx +++ b/reg23Topograms/itkDTRrecon/autoreg/itkTwoProjectionImageRegistrationMethod.hxx @@ -38,6 +38,7 @@ TwoProjectionImageRegistrationMethod::TwoProjectionIm m_MovingImage = nullptr; // has to be provided by the user. m_Transform1 = nullptr; // has to be provided by the user. m_Transform2 = nullptr; // has to be provided by the user. + m_IsocIECTransform = nullptr; m_TransformMetaInfo = nullptr; // has to be provided by the user. m_Interpolator1 = nullptr; // has to be provided by the user. m_Interpolator2 = nullptr; // has to be provided by the user. @@ -80,6 +81,7 @@ void TwoProjectionImageRegistrationMethod::SetFixedIm m_FixedImageRegionDefined2 = true; } + /* * Initialize by setting the interconnects between components. */ @@ -119,7 +121,8 @@ void TwoProjectionImageRegistrationMethod::Initialize // Connect the transform to the Decorator. auto* transformOutput = static_cast(this->ProcessObject::GetOutput(0)); - transformOutput->Set(m_Transform1.GetPointer()); + //transformOutput->Set(m_Transform1.GetPointer()); + transformOutput->Set(m_IsocIECTransform.GetPointer()); if (!m_Interpolator1) { itkExceptionMacro(<< "Interpolator1 is not present"); @@ -147,6 +150,7 @@ void TwoProjectionImageRegistrationMethod::Initialize m_Metric->SetFixedImage2(m_FixedImage2); m_Metric->SetTransform1(m_Transform1); m_Metric->SetTransform2(m_Transform2); + m_Metric->SetIsocTransf(m_IsocIECTransform); m_Metric->SetTransformMetaInfo(m_TransformMetaInfo); m_Metric->SetFilter1(m_Filter1); m_Metric->SetFilter2(m_Filter2); @@ -174,7 +178,8 @@ void TwoProjectionImageRegistrationMethod::Initialize m_Optimizer->SetScales(m_Metric->GetWeightings()); m_Optimizer->SetCostFunction(m_Metric); - m_InitialOptimizerParameters = m_Metric->GetParameters(); + m_InitialOptimizerParameters = + m_Metric->GetParameters(); m_Optimizer->SetInitialPosition(m_InitialOptimizerParameters); } diff --git a/reg23Topograms/itkDTRrecon/autoreg/itkgTwoImageToOneImageMetric.h b/reg23Topograms/itkDTRrecon/autoreg/itkgTwoImageToOneImageMetric.h index c3d8712..752f7c1 100644 --- a/reg23Topograms/itkDTRrecon/autoreg/itkgTwoImageToOneImageMetric.h +++ b/reg23Topograms/itkDTRrecon/autoreg/itkgTwoImageToOneImageMetric.h @@ -169,6 +169,10 @@ public: /** Get a pointer to the Transform2. */ itkGetConstObjectMacro(Transform2, TransformType); + itkSetObjectMacro(IsocTransf, TransformType); + itkGetObjectMacro(IsocTransf, TransformType); + + /** Connect the Interpolator. */ itkSetObjectMacro(Interpolator1, InterpolatorType); @@ -261,6 +265,8 @@ protected: mutable TransformPointer m_Transform1; mutable TransformPointer m_Transform2; + mutable TransformPointer m_IsocTransf; + InterpolatorPointer m_Interpolator1; InterpolatorPointer m_Interpolator2; diff --git a/reg23Topograms/itkDTRrecon/autoreg/itkgTwoImageToOneImageMetric.hxx b/reg23Topograms/itkDTRrecon/autoreg/itkgTwoImageToOneImageMetric.hxx index d4ea48a..8cade2d 100644 --- a/reg23Topograms/itkDTRrecon/autoreg/itkgTwoImageToOneImageMetric.hxx +++ b/reg23Topograms/itkDTRrecon/autoreg/itkgTwoImageToOneImageMetric.hxx @@ -55,7 +55,8 @@ bool gTwoImageToOneImageMetric::SetTransformParameter itkExceptionMacro(<< "Transform 2 has not been assigned"); } - auto transformParameters = m_Transform1->GetParameters(); + //auto transformParameters = m_Transform1->GetParameters(); + auto transformParameters = m_IsocTransf->GetParameters(); double TranslationAlongX = transformParameters[3]; double TranslationAlongY = transformParameters[4]; double TranslationAlongZ = transformParameters[5]; @@ -106,6 +107,10 @@ bool gTwoImageToOneImageMetric::SetTransformParameter std::cout << " Rotation Along Z = " << RotationAlongZ / dtr << " deg" << std::endl; std::cout << "+++++++++++++++++++++++++++++++++++++++++++++++++++++++" << std::endl; + + //HERE WE HAVE TO CALCULATE INTERNAL TRANSFORMS!!! + // GIOVANNI + transformParameters[0] = RotationAlongX; transformParameters[1] = RotationAlongY; transformParameters[2] = RotationAlongZ; @@ -281,10 +286,12 @@ itk::Optimizer::ScalesType gTwoImageToOneImageMetric: } template -typename gTwoImageToOneImageMetric::ParametersType gTwoImageToOneImageMetric::GetParameters() const +typename gTwoImageToOneImageMetric:: +ParametersType gTwoImageToOneImageMetric::GetParameters() const { - ParametersType parametersTransform = m_Transform1->GetParameters(); //angleX, angleY, angleZ, transX, transY, transZ +// ParametersType parametersTransform = m_Transform1->GetParameters(); //angleX, angleY, angleZ, transX, transY, transZ + ParametersType parametersTransform = m_IsocTransf->GetParameters(); //angleX, angleY, angleZ, transX, transY, transZ ParametersType parameters(this->GetNumberOfParameters()); switch (m_TransformMetaInfo->GetDegreeOfFreedom()) { case X_ONLY: diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp index c828274..0c2c739 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp @@ -1281,64 +1281,63 @@ double itkImageProcessor::GetLocalizerDisplayWindowWidth(int iImg) } -itkImageProcessor::TransformType::Pointer -itkImageProcessor::MapTransformToNewOrigin( - ImageType3D::PointType m_COR, // Center of rotation for the proj geometry. this is my new origin. - ImageType3D::PointType m_Translations, - ImageType3D::PointType m_Rotations - ){ +//itkImageProcessor::TransformType::Pointer +//itkImageProcessor::MapTransformToNewOrigin( +// ImageType3D::PointType m_COR, // Center of rotation for the proj geometry. this is my new origin. +// ImageType3D::PointType m_Translations, +// ImageType3D::PointType m_Rotations +// ){ - TransformType::Pointer InputTransform = TransformType::New(); - InputTransform->SetComputeZYX(true); - InputTransform->SetIdentity(); +// TransformType::Pointer InputTransform = TransformType::New(); +// InputTransform->SetComputeZYX(true); +// InputTransform->SetIdentity(); - TransformType::OutputVectorType translation; - translation[0] = m_Translations[0]; - translation[1] = m_Translations[1]; - translation[2] = m_Translations[2]; +// TransformType::OutputVectorType translation; +// translation[0] = m_Translations[0]; +// translation[1] = m_Translations[1]; +// translation[2] = m_Translations[2]; - InputTransform->SetTranslation(translation); +// InputTransform->SetTranslation(translation); - const double dtr = (atan(1.0) * 4.0) / 180.0; - InputTransform->SetRotation( - dtr * m_Rotations[0], - dtr * m_Rotations[1], - dtr * m_Rotations[2]); +// const double dtr = (atan(1.0) * 4.0) / 180.0; +// InputTransform->SetRotation( +// dtr * m_Rotations[0], +// dtr * m_Rotations[1], +// dtr * m_Rotations[2]); - ImageType3D::PointType m_TransformOrigin; - m_TransformOrigin.Fill(0.); - InputTransform->SetCenter( - m_TransformOrigin ); +// ImageType3D::PointType m_TransformOrigin; +// m_TransformOrigin.Fill(0.); +// InputTransform->SetCenter( +// m_TransformOrigin ); - ImageType3D::PointType NewOriginTranslations = - InputTransform->TransformPoint(m_COR); +// ImageType3D::PointType NewOriginTranslations = +// InputTransform->TransformPoint(m_COR); - ImageType3D::PointType DeltaNewOrigin = - NewOriginTranslations - m_COR; +// ImageType3D::PointType DeltaNewOrigin = +// NewOriginTranslations - m_COR; - TransformType::Pointer m_OutputTransform = - TransformType::New(); - m_OutputTransform ->SetComputeZYX(true); - m_OutputTransform ->SetIdentity(); +// TransformType::Pointer m_OutputTransform = +// TransformType::New(); +// m_OutputTransform ->SetComputeZYX(true); +// m_OutputTransform ->SetIdentity(); - translation[0] = DeltaNewOrigin[0]; - translation[1] = DeltaNewOrigin[1]; - translation[2] = DeltaNewOrigin[2]; +// translation[0] = DeltaNewOrigin[0]; +// translation[1] = DeltaNewOrigin[1]; +// translation[2] = DeltaNewOrigin[2]; - m_OutputTransform->SetTranslation(translation); - m_OutputTransform->SetRotation( - dtr * m_Rotations[0], - dtr * m_Rotations[1], - dtr * m_Rotations[2]); +// m_OutputTransform->SetTranslation(translation); +// m_OutputTransform->SetRotation( +// dtr * m_Rotations[0], +// dtr * m_Rotations[1], +// dtr * m_Rotations[2]); - m_OutputTransform->SetCenter(m_COR); +// m_OutputTransform->SetCenter(m_COR); - InputTransform = NULL; +// InputTransform = NULL; - // m_OutputTransform.Print(std::cout); - return m_OutputTransform; -} +// return m_OutputTransform; +//} // This External User Transform thing need to be checked out @@ -1369,88 +1368,88 @@ void itkImageProcessor::CalculateExternalUserTransform(TransformType::Pointer tr } -itkImageProcessor::TransformType::Pointer -itkImageProcessor::CalculateInternalTransformV2( - ImageType3D::PointType m_TranslationOffset, //IEC - ImageType3D::PointType m_RotationOffset, //IEC - ImageType3D::PointType m_TranslationUser, //IEC - ImageType3D::PointType m_RotationUser, //IEC - ImageType3D::PointType m_CalibratedProjectionCenter, //LPS - ImageType3D::PointType m_RTIsocenter, //LPS - InternalImageType::DirectionType m_IECtoLPSDirections - ) -{ +//itkImageProcessor::TransformType::Pointer +//itkImageProcessor::CalculateInternalTransformV2( +// ImageType3D::PointType m_TranslationOffset, //IEC +// ImageType3D::PointType m_RotationOffset, //IEC +// ImageType3D::PointType m_TranslationUser, //IEC +// ImageType3D::PointType m_RotationUser, //IEC +// ImageType3D::PointType m_CalibratedProjectionCenter, //LPS +// ImageType3D::PointType m_RTIsocenter, //LPS +// InternalImageType::DirectionType m_IECtoLPSDirections +// ) +//{ - //Convert all inputs into LPS +// //Convert all inputs into LPS - ImageType3D::PointType m_TOffsetLPS = - m_IECtoLPSDirections * m_TranslationOffset; +// ImageType3D::PointType m_TOffsetLPS = +// m_IECtoLPSDirections * m_TranslationOffset; - ImageType3D::PointType m_ROffsetLPS = - m_IECtoLPSDirections * m_RotationOffset; +// ImageType3D::PointType m_ROffsetLPS = +// m_IECtoLPSDirections * m_RotationOffset; - ImageType3D::PointType m_TUserLPS = - m_IECtoLPSDirections * m_TranslationUser; +// ImageType3D::PointType m_TUserLPS = +// m_IECtoLPSDirections * m_TranslationUser; - ImageType3D::PointType m_RUserLPS = - m_IECtoLPSDirections * m_RotationUser; +// ImageType3D::PointType m_RUserLPS = +// m_IECtoLPSDirections * m_RotationUser; - TransformType::OutputVectorType translation; - translation[0] = m_TOffsetLPS[0] + m_TUserLPS[0]; - translation[1] = m_TOffsetLPS[1] + m_TUserLPS[1]; - translation[2] = m_TOffsetLPS[2] + m_TUserLPS[2]; +// TransformType::OutputVectorType translation; +// translation[0] = m_TOffsetLPS[0] + m_TUserLPS[0]; +// translation[1] = m_TOffsetLPS[1] + m_TUserLPS[1]; +// translation[2] = m_TOffsetLPS[2] + m_TUserLPS[2]; - TransformType::OutputVectorType rotations; - rotations[0] = m_ROffsetLPS[0] + m_RUserLPS[0]; - rotations[1] = m_ROffsetLPS[1] + m_RUserLPS[1]; - rotations[2] = m_ROffsetLPS[2] + m_RUserLPS[2]; +// TransformType::OutputVectorType rotations; +// rotations[0] = m_ROffsetLPS[0] + m_RUserLPS[0]; +// rotations[1] = m_ROffsetLPS[1] + m_RUserLPS[1]; +// rotations[2] = m_ROffsetLPS[2] + m_RUserLPS[2]; - // Map offset to the projection center - TransformType::Pointer m_outputTransform = - MapTransformToNewOrigin ( - m_CalibratedProjectionCenter - m_RTIsocenter, - translation, - rotations - ); +// // Map offset to the projection center +// TransformType::Pointer m_outputTransform = +// MapTransformToNewOrigin ( +// m_CalibratedProjectionCenter - m_RTIsocenter, +// translation, +// rotations +// ); - m_outputTransform->SetCenter(m_CalibratedProjectionCenter); +// m_outputTransform->SetCenter(m_CalibratedProjectionCenter); - return m_outputTransform; +// return m_outputTransform; -} +//} -itkImageProcessor::TransformType::Pointer -itkImageProcessor::CalculateInternalTransformV3( - ImageType3D::PointType m_Translation, //IEC - ImageType3D::PointType m_Rotation, //IEC - ImageType3D::PointType m_CalibratedProjectionCenter, //LPS - ImageType3D::PointType m_RTIsocenter, //LPS - InternalImageType::DirectionType m_IECtoLPSDirections - ) -{ +//itkImageProcessor::TransformType::Pointer +//itkImageProcessor::CalculateInternalTransformV3( +// ImageType3D::PointType m_Translation, //IEC +// ImageType3D::PointType m_Rotation, //IEC +// ImageType3D::PointType m_CalibratedProjectionCenter, //LPS +// ImageType3D::PointType m_RTIsocenter, //LPS +// InternalImageType::DirectionType m_IECtoLPSDirections +// ) +//{ - //Convert all inputs into LPS +// //Convert all inputs into LPS - ImageType3D::PointType m_TLPS = - m_IECtoLPSDirections * m_Translation; +// ImageType3D::PointType m_TLPS = +// m_IECtoLPSDirections * m_Translation; - ImageType3D::PointType m_RLPS = - m_IECtoLPSDirections * m_Rotation; +// ImageType3D::PointType m_RLPS = +// m_IECtoLPSDirections * m_Rotation; - // Map offset to the projection center - TransformType::Pointer m_outputTransform = - MapTransformToNewOrigin ( - m_CalibratedProjectionCenter - m_RTIsocenter, - m_TLPS, - m_RLPS - ); +// // Map offset to the projection center +// TransformType::Pointer m_outputTransform = +// MapTransformToNewOrigin ( +// m_CalibratedProjectionCenter - m_RTIsocenter, +// m_TLPS, +// m_RLPS +// ); - m_outputTransform->SetCenter(m_CalibratedProjectionCenter); +// m_outputTransform->SetCenter(m_CalibratedProjectionCenter); - return m_outputTransform; +// return m_outputTransform; -} +//} void itkImageProcessor::InitializeRegistration( @@ -1528,94 +1527,109 @@ void itkImageProcessor::InitializeRegistration( //CalculateInternalTransform(transform1, m_DRTImage1MetaInfo); /********* BEGIN CALCULATION OF INTERNAL TRANSFORM FOR PROJ1 *********/ - ImageType3D::PointType ZeroPoint; - ZeroPoint.Fill(0.); - InternalImageType::DirectionType IECtoLPS_Directions; - IECtoLPS_Directions = - m_CTMetaInfo->GetLPS2IECDirections().GetTranspose(); - TransformType::Pointer CurrTransform; - if(m_RTMetaInfo == NULL) - { - CurrTransform = - CalculateInternalTransformV3( - m_TransformMetaInfo->GetT(), - m_TransformMetaInfo->GetR(), - m_DRTImage1MetaInfo->GetProjectionOriginLPSZero(), - m_DRTImage1MetaInfo->GetProjectionOriginLPS(), - IECtoLPS_Directions); +// ImageType3D::PointType ZeroPoint; +// ZeroPoint.Fill(0.); +// InternalImageType::DirectionType IECtoLPS_Directions; +// IECtoLPS_Directions = +// m_CTMetaInfo->GetLPS2IECDirections().GetTranspose(); +// TransformType::Pointer CurrTransform; +// if(m_RTMetaInfo == NULL) +// { +// CurrTransform = +// CalculateInternalTransformV3( +// m_TransformMetaInfo->GetT(), +// m_TransformMetaInfo->GetR(), +// m_DRTImage1MetaInfo->GetProjectionOriginLPSZero(), +// m_DRTImage1MetaInfo->GetProjectionOriginLPS(), +// IECtoLPS_Directions); - } else { +// } else { - CurrTransform = - CalculateInternalTransformV3( - m_TransformMetaInfo->GetT(), - m_TransformMetaInfo->GetR(), - m_DRTImage1MetaInfo->GetProjectionOriginLPSZero(), - m_RTMetaInfo->GetIsocenterLPS() - m_CTMetaInfo->GetOriginLPS(), - IECtoLPS_Directions - ); +// CurrTransform = +// CalculateInternalTransformV3( +// m_TransformMetaInfo->GetT(), +// m_TransformMetaInfo->GetR(), +// m_DRTImage1MetaInfo->GetProjectionOriginLPSZero(), +// m_RTMetaInfo->GetIsocenterLPS() - m_CTMetaInfo->GetOriginLPS(), +// IECtoLPS_Directions +// ); - } +// } - transform1->SetComputeZYX(true); - transform1->SetIdentity(); - transform1->SetTranslation( - CurrTransform->GetTranslation()); - transform1->SetRotation( - CurrTransform->GetAngleX(), - CurrTransform->GetAngleY(), - CurrTransform->GetAngleZ() - ); - transform1->SetCenter( - m_DRTImage1MetaInfo->GetProjectionOriginLPSZero() ); +// transform1->SetComputeZYX(true); +// transform1->SetIdentity(); +// transform1->SetTranslation( +// CurrTransform->GetTranslation()); +// transform1->SetRotation( +// CurrTransform->GetAngleX(), +// CurrTransform->GetAngleY(), +// CurrTransform->GetAngleZ() +// ); +// transform1->SetCenter( +// m_DRTImage1MetaInfo->GetProjectionOriginLPSZero() ); +// /********* END OF CALCULATE INTERNAL TRANSFORM FOR PROJ1 *********/ + + +// //CalculateInternalTransform(transform2, m_DRTImage2MetaInfo); +// /********* BEGIN CALCULATION OF INTERNAL TRANSFORM FOR PROJ2 *********/ +// if(m_RTMetaInfo == NULL) +// { +// CurrTransform = +// CalculateInternalTransformV3( +// m_TransformMetaInfo->GetT(), +// m_TransformMetaInfo->GetR(), +// m_DRTImage2MetaInfo->GetProjectionOriginLPSZero(), +// m_DRTImage2MetaInfo->GetProjectionOriginLPS(), +// IECtoLPS_Directions); + + +// } else { + + +// CurrTransform = +// CalculateInternalTransformV3( +// m_TransformMetaInfo->GetT(), +// m_TransformMetaInfo->GetR(), +// m_DRTImage2MetaInfo->GetProjectionOriginLPSZero(), +// m_RTMetaInfo->GetIsocenterLPS() - m_CTMetaInfo->GetOriginLPS(), +// IECtoLPS_Directions +// ); + + +// } +// transform2->SetComputeZYX(true); +// transform2->SetIdentity(); +// transform2->SetTranslation( +// CurrTransform->GetTranslation()); +// transform2->SetRotation( +// CurrTransform->GetAngleX(), +// CurrTransform->GetAngleY(), +// CurrTransform->GetAngleZ() +// ); +// transform2->SetCenter( +// m_DRTImage2MetaInfo->GetProjectionOriginLPSZero() ); /********* END OF CALCULATE INTERNAL TRANSFORM FOR PROJ1 *********/ + IsocTransf = TransformType::New(); + IsocTransf->SetRotation( + m_TransformMetaInfo->GetR()[0], + m_TransformMetaInfo->GetR()[1], + m_TransformMetaInfo->GetR()[2] + ); - //CalculateInternalTransform(transform2, m_DRTImage2MetaInfo); - /********* BEGIN CALCULATION OF INTERNAL TRANSFORM FOR PROJ2 *********/ - if(m_RTMetaInfo == NULL) - { - CurrTransform = - CalculateInternalTransformV3( - m_TransformMetaInfo->GetT(), - m_TransformMetaInfo->GetR(), - m_DRTImage2MetaInfo->GetProjectionOriginLPSZero(), - m_DRTImage2MetaInfo->GetProjectionOriginLPS(), - IECtoLPS_Directions); + TransformType::OutputVectorType TranslV; + TranslV[0] = m_TransformMetaInfo->GetT()[0]; + TranslV[1] = m_TransformMetaInfo->GetT()[1]; + TranslV[2] = m_TransformMetaInfo->GetT()[2]; + IsocTransf->SetTranslation(TranslV); - } else { - - - CurrTransform = - CalculateInternalTransformV3( - m_TransformMetaInfo->GetT(), - m_TransformMetaInfo->GetR(), - m_DRTImage2MetaInfo->GetProjectionOriginLPSZero(), - m_RTMetaInfo->GetIsocenterLPS() - m_CTMetaInfo->GetOriginLPS(), - IECtoLPS_Directions - ); - - - } - transform2->SetComputeZYX(true); - transform2->SetIdentity(); - transform2->SetTranslation( - CurrTransform->GetTranslation()); - transform2->SetRotation( - CurrTransform->GetAngleX(), - CurrTransform->GetAngleY(), - CurrTransform->GetAngleZ() - ); - transform2->SetCenter( - m_DRTImage2MetaInfo->GetProjectionOriginLPSZero() ); - /********* END OF CALCULATE INTERNAL TRANSFORM FOR PROJ1 *********/ - + registration->SetIsocIECTransform(IsocTransf); if (verbose) { registration->DebugOn(); @@ -2055,8 +2069,7 @@ int itkImageProcessor::unloadRTPlanAndMeta(){ std::cout << "*" << __COMPACT_PRETTY_FUNCTION__ << std::endl; m_RTMetaInfo = NULL; - ImageType3D::PointType - pZero; + ImageType3D::PointType pZero; pZero.Fill(0.); m_CTMetaInfo->SetImportOffset(pZero); diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.h b/reg23Topograms/itkDTRrecon/itkImageProcessor.h index 72af105..e83945c 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.h +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.h @@ -51,6 +51,8 @@ gfattori 08.11.2021 #include "itkQtIterationUpdate.h" +#include "itkImageProcessorHelpers.h" + namespace itk { @@ -271,29 +273,22 @@ private: /* Calculate the transform used in siddon. * The isocentric transform is mapped to the calibrated center of projection */ - TransformType::Pointer - CalculateInternalTransformV2( - ImageType3D::PointType m_TranslationOffset, - ImageType3D::PointType m_RotationOffset, - ImageType3D::PointType m_TranslationUser, - ImageType3D::PointType m_RotationUser, - ImageType3D::PointType m_CalibratedProjectionCenter, - ImageType3D::PointType m_RTIsocenter, - InternalImageType::DirectionType m_IECtoLPSDirections - ); +// TransformType::Pointer +// CalculateInternalTransformV2( +// ImageType3D::PointType m_TranslationOffset, +// ImageType3D::PointType m_RotationOffset, +// ImageType3D::PointType m_TranslationUser, +// ImageType3D::PointType m_RotationUser, +// ImageType3D::PointType m_CalibratedProjectionCenter, +// ImageType3D::PointType m_RTIsocenter, +// InternalImageType::DirectionType m_IECtoLPSDirections +// ); - TransformType::Pointer - CalculateInternalTransformV3( - ImageType3D::PointType m_Translation, - ImageType3D::PointType m_Rotation, - ImageType3D::PointType m_CalibratedProjectionCenter, - ImageType3D::PointType m_RTIsocenter, - InternalImageType::DirectionType m_IECtoLPSDirections - ); TransformType::Pointer transform1, - transform2; + transform2, + IsocTransf; InterpolatorType::Pointer interpolator1, @@ -355,12 +350,12 @@ private: ); - TransformType::Pointer - MapTransformToNewOrigin( - ImageType3D::PointType m_COR, - ImageType3D::PointType m_Translations, - ImageType3D::PointType m_Rotations - ); +// TransformType::Pointer +// MapTransformToNewOrigin( +// ImageType3D::PointType m_COR, +// ImageType3D::PointType m_Translations, +// ImageType3D::PointType m_Rotations +// ); double CalcProjectionAngleLPS( diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessorHelpers.cpp b/reg23Topograms/itkDTRrecon/itkImageProcessorHelpers.cpp new file mode 100644 index 0000000..018ecf1 --- /dev/null +++ b/reg23Topograms/itkDTRrecon/itkImageProcessorHelpers.cpp @@ -0,0 +1,93 @@ +#include "itkImageProcessorHelpers.h" + +itk::TransformType::Pointer +itk::MapTransformToNewOrigin( + ImageType3D::PointType m_COR, // Center of rotation for the proj geometry. this is my new origin. + ImageType3D::PointType m_Translations, + ImageType3D::PointType m_Rotations + ){ + + TransformType::Pointer InputTransform = TransformType::New(); + InputTransform->SetComputeZYX(true); + InputTransform->SetIdentity(); + + TransformType::OutputVectorType translation; + translation[0] = m_Translations[0]; + translation[1] = m_Translations[1]; + translation[2] = m_Translations[2]; + + InputTransform->SetTranslation(translation); + + const double dtr = (atan(1.0) * 4.0) / 180.0; + InputTransform->SetRotation( + dtr * m_Rotations[0], + dtr * m_Rotations[1], + dtr * m_Rotations[2]); + + ImageType3D::PointType m_TransformOrigin; + m_TransformOrigin.Fill(0.); + InputTransform->SetCenter( + m_TransformOrigin ); + + ImageType3D::PointType NewOriginTranslations = + InputTransform->TransformPoint(m_COR); + + ImageType3D::PointType DeltaNewOrigin = + NewOriginTranslations - m_COR; + + + TransformType::Pointer m_OutputTransform = + TransformType::New(); + m_OutputTransform ->SetComputeZYX(true); + m_OutputTransform ->SetIdentity(); + + translation[0] = DeltaNewOrigin[0]; + translation[1] = DeltaNewOrigin[1]; + translation[2] = DeltaNewOrigin[2]; + + m_OutputTransform->SetTranslation(translation); + m_OutputTransform->SetRotation( + dtr * m_Rotations[0], + dtr * m_Rotations[1], + dtr * m_Rotations[2]); + + m_OutputTransform->SetCenter(m_COR); + + InputTransform = NULL; + + return m_OutputTransform; +} + + + +itk::TransformType::Pointer +itk::CalculateInternalTransformV3( + ImageType3D::PointType m_Translation, //IEC + ImageType3D::PointType m_Rotation, //IEC + ImageType3D::PointType m_CalibratedProjectionCenter, //LPS + ImageType3D::PointType m_RTIsocenter, //LPS + InternalImageType::DirectionType m_IECtoLPSDirections + ) +{ + + //Convert all inputs into LPS + + ImageType3D::PointType m_TLPS = + m_IECtoLPSDirections * m_Translation; + + ImageType3D::PointType m_RLPS = + m_IECtoLPSDirections * m_Rotation; + + // Map offset to the projection center + TransformType::Pointer m_outputTransform = + MapTransformToNewOrigin ( + m_CalibratedProjectionCenter - m_RTIsocenter, + m_TLPS, + m_RLPS + ); + + m_outputTransform->SetCenter(m_CalibratedProjectionCenter); + + return m_outputTransform; + +} diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessorHelpers.h b/reg23Topograms/itkDTRrecon/itkImageProcessorHelpers.h new file mode 100644 index 0000000..2b8aec8 --- /dev/null +++ b/reg23Topograms/itkDTRrecon/itkImageProcessorHelpers.h @@ -0,0 +1,38 @@ + +#ifndef ITKIMAGEPROCESSORHELPERS_H +#define ITKIMAGEPROCESSORHELPERS_H + +#include "itkEuler3DTransform.h" +#include "itkImage.h" + + +namespace itk +{ +constexpr static unsigned int Dimension = 3; +using PixelType3D = short; +using InternalPixelType = float; + +using ImageType3D = itk::Image; +using InternalImageType = itk::Image; + +using TransformType = itk::Euler3DTransform; + +TransformType::Pointer +MapTransformToNewOrigin( + ImageType3D::PointType m_COR, + ImageType3D::PointType m_Translations, + ImageType3D::PointType m_Rotations + ); + + +TransformType::Pointer + CalculateInternalTransformV3( + ImageType3D::PointType m_Translation, + ImageType3D::PointType m_Rotation, + ImageType3D::PointType m_CalibratedProjectionCenter, + ImageType3D::PointType m_RTIsocenter, + InternalImageType::DirectionType m_IECtoLPSDirections + ); +} + +#endif From d4c800dfcd65e867376c553d7add749fcac1521a Mon Sep 17 00:00:00 2001 From: Proton local user Date: Fri, 12 May 2023 23:36:24 +0200 Subject: [PATCH 41/49] R23 optimizes the isocentric IEC transform, internally the two internal transform are computed at every iteration. As a result, the feedback to regDialog is now already correct, no need for flips or sign change. CalculateExternalTransform becomes obsolete... and has been commented out. Methods for gui to get latest paremeters have been rewritten. --- .../itkDTRrecon/DRTMetaInformation.cpp | 23 + .../itkDTRrecon/DRTMetaInformation.h | 59 ++ .../itkTwoProjectionImageRegistrationMethod.h | 10 + ...tkTwoProjectionImageRegistrationMethod.hxx | 27 +- .../autoreg/itkgTwoImageToOneImageMetric.h | 13 + .../autoreg/itkgTwoImageToOneImageMetric.hxx | 104 ++- .../itkDTRrecon/itkImageProcessor.cpp | 613 ++++++------------ .../itkDTRrecon/itkImageProcessor.h | 43 +- .../itkDTRrecon/itkImageProcessorHelpers.cpp | 81 ++- .../itkDTRrecon/itkImageProcessorHelpers.h | 73 ++- .../itkDTRrecon/itkQtIterationUpdate.h | 14 +- 11 files changed, 586 insertions(+), 474 deletions(-) diff --git a/reg23Topograms/itkDTRrecon/DRTMetaInformation.cpp b/reg23Topograms/itkDTRrecon/DRTMetaInformation.cpp index 8395221..4981437 100644 --- a/reg23Topograms/itkDTRrecon/DRTMetaInformation.cpp +++ b/reg23Topograms/itkDTRrecon/DRTMetaInformation.cpp @@ -517,6 +517,29 @@ RTGeometryMetaInformation } +InternalTransformMetaInformation::InternalTransformMetaInformation(){ + + + m_pCalProjCenter.Fill(0.); + m_pRTIsocenter.Fill(0.); + + m_IECtoLPSDirs.SetIdentity(); + +} + +void +InternalTransformMetaInformation +::PrintSelf(std::ostream& os, itk::Indent indent) const +{ + Superclass::PrintSelf(os, indent); +} + +InternalTransformMetaInformation +::~InternalTransformMetaInformation () +{ + +} + R23MetaInformation:: R23MetaInformation (){ diff --git a/reg23Topograms/itkDTRrecon/DRTMetaInformation.h b/reg23Topograms/itkDTRrecon/DRTMetaInformation.h index f797b30..5beb57a 100644 --- a/reg23Topograms/itkDTRrecon/DRTMetaInformation.h +++ b/reg23Topograms/itkDTRrecon/DRTMetaInformation.h @@ -514,6 +514,65 @@ private: }; + + + +class InternalTransformMetaInformation : + public itk::Object{ + +public: + /** standard typedefs **/ + typedef InternalTransformMetaInformation Self; + typedef itk::Object Superclass; + typedef itk::SmartPointer Pointer; + + typedef itk::Point PointType; + typedef itk::Matrix TransformMatrixType; + + /** Method for creation through the object factory. */ + itkNewMacro(Self); + + /** Run-time type information (and related methods). */ + itkTypeMacro(InternalTransformMetaInformation, itk::Object); + + /** object information streaming **/ + void PrintSelf(std::ostream& os, itk::Indent indent) const; + + itkSetMacro(pCalProjCenter,PointType); + itkSetMacro(pRTIsocenter,PointType); + itkSetMacro(IECtoLPSDirs,TransformMatrixType); + itkGetMacro(pCalProjCenter,PointType); + itkGetMacro(pRTIsocenter,PointType); + itkGetMacro(IECtoLPSDirs,TransformMatrixType); + + +protected: + + PointType + m_pCalProjCenter, + m_pRTIsocenter; + + + TransformMatrixType + m_IECtoLPSDirs; + + + /** Default Constructor **/ + InternalTransformMetaInformation (); + /** Default Destructor **/ + virtual ~InternalTransformMetaInformation (); + +private: + /** purposely not implemented **/ + InternalTransformMetaInformation (const Self&); + + /** purposely not implemented **/ + void operator=(const Self&); + +}; + + + class R23MetaInformation : public itk::Object{ diff --git a/reg23Topograms/itkDTRrecon/autoreg/itkTwoProjectionImageRegistrationMethod.h b/reg23Topograms/itkDTRrecon/autoreg/itkTwoProjectionImageRegistrationMethod.h index 10d638b..d389042 100644 --- a/reg23Topograms/itkDTRrecon/autoreg/itkTwoProjectionImageRegistrationMethod.h +++ b/reg23Topograms/itkDTRrecon/autoreg/itkTwoProjectionImageRegistrationMethod.h @@ -177,6 +177,12 @@ public: itkSetObjectMacro(TransformMetaInfo, R23MetaInformation); itkGetConstObjectMacro(TransformMetaInfo, R23MetaInformation); + itkSetObjectMacro(internalMeta1, InternalTransformMetaInformation); + itkGetConstObjectMacro(internalMeta1, InternalTransformMetaInformation); + + itkSetObjectMacro(internalMeta2, InternalTransformMetaInformation); + itkGetConstObjectMacro(internalMeta2, InternalTransformMetaInformation); + /** Set/Get the output filters. */ itkSetObjectMacro(Filter1, ChangeInformationFilterType); itkGetConstObjectMacro(Filter1, ChangeInformationFilterType); @@ -259,6 +265,10 @@ private: InterpolatorPointer m_Interpolator1; InterpolatorPointer m_Interpolator2; + InternalTransformMetaInformation::Pointer + m_internalMeta1, + m_internalMeta2; + //TransformMetaInformation::Pointer // m_TransformMetaInfo; diff --git a/reg23Topograms/itkDTRrecon/autoreg/itkTwoProjectionImageRegistrationMethod.hxx b/reg23Topograms/itkDTRrecon/autoreg/itkTwoProjectionImageRegistrationMethod.hxx index fa127aa..b871033 100644 --- a/reg23Topograms/itkDTRrecon/autoreg/itkTwoProjectionImageRegistrationMethod.hxx +++ b/reg23Topograms/itkDTRrecon/autoreg/itkTwoProjectionImageRegistrationMethod.hxx @@ -40,6 +40,8 @@ TwoProjectionImageRegistrationMethod::TwoProjectionIm m_Transform2 = nullptr; // has to be provided by the user. m_IsocIECTransform = nullptr; m_TransformMetaInfo = nullptr; // has to be provided by the user. + m_internalMeta1 = nullptr; + m_internalMeta2 = nullptr; m_Interpolator1 = nullptr; // has to be provided by the user. m_Interpolator2 = nullptr; // has to be provided by the user. m_Metric = nullptr; // has to be provided by the user. @@ -144,6 +146,14 @@ void TwoProjectionImageRegistrationMethod::Initialize itkExceptionMacro(<< "TransformMetaInfo is not present"); } + if (!m_internalMeta1) { + itkExceptionMacro(<< "internalMeta1 is not present"); + } + + if (!m_internalMeta2) { + itkExceptionMacro(<< "internalMeta1 is not present"); + } + // Setup the metric m_Metric->SetMovingImage(m_MovingImage); m_Metric->SetFixedImage1(m_FixedImage1); @@ -152,6 +162,9 @@ void TwoProjectionImageRegistrationMethod::Initialize m_Metric->SetTransform2(m_Transform2); m_Metric->SetIsocTransf(m_IsocIECTransform); m_Metric->SetTransformMetaInfo(m_TransformMetaInfo); + m_Metric->SetinternalMeta1(m_internalMeta1); + m_Metric->SetinternalMeta2(m_internalMeta2); + m_Metric->SetFilter1(m_Filter1); m_Metric->SetFilter2(m_Filter2); @@ -206,7 +219,7 @@ void TwoProjectionImageRegistrationMethod::OnInternal // if (m_CancelRequest) // filter->SetAbortGenerateData(true); // may be handled by filter - std::cout << "OnInternalFilterProgressReceptor :: filter (TURE) " << std::endl; + std::cout << "OnInternalFilterProgressReceptor :: filter (TRUE) " << std::endl; } } @@ -217,22 +230,10 @@ template void TwoProjectionImageRegistrationMethod::StartRegistration() { -// typedef itk::MemberCommand ITKCommandType; -// typedef ITKCommandType::Pointer MemberPointer ; - - -// ITKCommandType::Pointer cmd = ITKCommandType::New(); -// itk::Command cmd= itk::Command::Pointer(this); - -// cmd->SetCallbackFunction(this, -// (ITKCommandType::Pointer)&TwoProjectionImageRegistrationMethod::OnInternalFilterProgressReceptor); - itk::ProgressReporter progress( this, 1, 1000,100); -// this->SetAbortGenerateData(true); - ParametersType empty(1); empty.Fill(0.0); try { diff --git a/reg23Topograms/itkDTRrecon/autoreg/itkgTwoImageToOneImageMetric.h b/reg23Topograms/itkDTRrecon/autoreg/itkgTwoImageToOneImageMetric.h index 752f7c1..2c08287 100644 --- a/reg23Topograms/itkDTRrecon/autoreg/itkgTwoImageToOneImageMetric.h +++ b/reg23Topograms/itkDTRrecon/autoreg/itkgTwoImageToOneImageMetric.h @@ -40,6 +40,8 @@ #include #include +#include + namespace itk { /** \class gTwoImageToOneImageMetric @@ -194,6 +196,13 @@ public: /** Get a pointer to the DRTGeometryMetaInfo. */ itkGetConstObjectMacro(TransformMetaInfo, R23MetaInformation); + + itkSetObjectMacro(internalMeta1, InternalTransformMetaInformation); + itkGetConstObjectMacro(internalMeta1, InternalTransformMetaInformation); + + itkSetObjectMacro(internalMeta2, InternalTransformMetaInformation); + itkGetConstObjectMacro(internalMeta2, InternalTransformMetaInformation); + /** Set the region over which the metric will be computed */ itkSetMacro(FixedImageRegion1, FixedImageRegionType); @@ -283,6 +292,10 @@ protected: R23MetaInformation::Pointer m_TransformMetaInfo; + InternalTransformMetaInformation::Pointer + m_internalMeta1, + m_internalMeta2; + ChangeInformationFilterPointer m_Filter1, m_Filter2; diff --git a/reg23Topograms/itkDTRrecon/autoreg/itkgTwoImageToOneImageMetric.hxx b/reg23Topograms/itkDTRrecon/autoreg/itkgTwoImageToOneImageMetric.hxx index 8cade2d..b2c2f2b 100644 --- a/reg23Topograms/itkDTRrecon/autoreg/itkgTwoImageToOneImageMetric.hxx +++ b/reg23Topograms/itkDTRrecon/autoreg/itkgTwoImageToOneImageMetric.hxx @@ -32,6 +32,8 @@ gTwoImageToOneImageMetric::gTwoImageToOneImageMetric( m_Transform1 = nullptr; // has to be provided by the user. m_Transform2 = nullptr; // has to be provided by the user. m_TransformMetaInfo = nullptr; // has to be provided by the user. + m_internalMeta1 = nullptr; + m_internalMeta2 = nullptr; m_Interpolator1 = nullptr; // has to be provided by the user. m_Interpolator2 = nullptr; // has to be provided by the user. m_GradientImage = nullptr; // will receive the output of the filter; @@ -55,6 +57,13 @@ bool gTwoImageToOneImageMetric::SetTransformParameter itkExceptionMacro(<< "Transform 2 has not been assigned"); } + if (!m_internalMeta1){ + itkExceptionMacro(<< "m_internalMeta1 has not been assigned"); + } + if (!m_internalMeta2){ + itkExceptionMacro(<< "m_internalMeta2 has not been assigned"); + } + //auto transformParameters = m_Transform1->GetParameters(); auto transformParameters = m_IsocTransf->GetParameters(); double TranslationAlongX = transformParameters[3]; @@ -64,6 +73,8 @@ bool gTwoImageToOneImageMetric::SetTransformParameter double RotationAlongY = transformParameters[1]; double RotationAlongZ = transformParameters[2]; + //std::cout << "m_IsocTransf PARS: "<< transformParameters <GetDegreeOfFreedom()) { case X_ONLY: TranslationAlongX = parameters[0]; @@ -102,33 +113,73 @@ bool gTwoImageToOneImageMetric::SetTransformParameter std::cout << " Translation X = " << TranslationAlongX << " mm" << std::endl; std::cout << " Translation Y = " << TranslationAlongY << " mm" << std::endl; std::cout << " Translation Z = " << TranslationAlongZ << " mm" << std::endl; - std::cout << " Rotation Along X = " << RotationAlongX / dtr << " deg" << std::endl; - std::cout << " Rotation Along Y = " << RotationAlongY / dtr << " deg" << std::endl; - std::cout << " Rotation Along Z = " << RotationAlongZ / dtr << " deg" << std::endl; + std::cout << " Rotation Along X = " << RotationAlongX /*/ dtr*/ << " deg" << std::endl; + std::cout << " Rotation Along Y = " << RotationAlongY /*/ dtr*/ << " deg" << std::endl; + std::cout << " Rotation Along Z = " << RotationAlongZ /*/ dtr*/ << " deg" << std::endl; std::cout << "+++++++++++++++++++++++++++++++++++++++++++++++++++++++" << std::endl; //HERE WE HAVE TO CALCULATE INTERNAL TRANSFORMS!!! // GIOVANNI - transformParameters[0] = RotationAlongX; - transformParameters[1] = RotationAlongY; - transformParameters[2] = RotationAlongZ; - transformParameters[3] = TranslationAlongX; - transformParameters[4] = TranslationAlongY; - transformParameters[5] = TranslationAlongZ; + ImageType3D::PointType + pT; + pT[0] = TranslationAlongX; + pT[1] = TranslationAlongY; + pT[2] = TranslationAlongZ; - bool transformValid = (std::abs(TranslationAlongX) < m_MaxTranslation) && - (std::abs(TranslationAlongY) < m_MaxTranslation) && - (std::abs(TranslationAlongZ) < m_MaxTranslation); + ImageType3D::PointType + pR; + pR[0] = RotationAlongX; + pR[1] = RotationAlongY; + pR[2] = RotationAlongZ; - if (transformValid) { - m_Transform1->SetParameters(transformParameters); - m_Transform2->SetParameters(transformParameters); - } else { - std::cout << " Transform invalid, out of range!" << std::endl; - std::cout << "+++++++++++++++++++++++++++++++++++++++++++++++++++++++" << std::endl; - } + TransformType::Pointer CurrTransform; + CurrTransform = CalculateInternalTransformV3( + pT, + pR, + m_internalMeta1->GetpCalProjCenter(), + m_internalMeta1->GetpRTIsocenter(), + m_internalMeta1->GetIECtoLPSDirs()); + + m_Transform1->SetIdentity(); + m_Transform1->SetParameters( + CurrTransform->GetParameters()); + m_Transform1->SetCenter( + m_internalMeta1->GetpCalProjCenter()); + // std::cout << "m_Transform1 PARS: "<< m_Transform1->GetParameters()<GetpCalProjCenter(), + m_internalMeta2->GetpRTIsocenter(), + m_internalMeta2->GetIECtoLPSDirs()); + + m_Transform2->SetIdentity(); + m_Transform2->SetParameters( + CurrTransform->GetParameters()); + m_Transform2->SetCenter( + m_internalMeta2->GetpCalProjCenter()); + // std::cout << "m_Transform2 PARS: "<< m_Transform2->GetParameters()<SetParameters(transformParameters); +// m_Transform2->SetParameters(transformParameters); +// } else { +// std::cout << " Transform invalid, out of range!" << std::endl; +// std::cout << "+++++++++++++++++++++++++++++++++++++++++++++++++++++++" << std::endl; +// } return transformValid; } @@ -136,18 +187,25 @@ template void gTwoImageToOneImageMetric::Initialize() { - if (!m_Transform1) { + if (!m_IsocTransf) { itkExceptionMacro(<< "Transform is not present"); } if (!m_Transform1) { - itkExceptionMacro(<< "Transform is not present"); + itkExceptionMacro(<< "Transform1 is not present"); } if (!m_Transform2) { - itkExceptionMacro(<< "Transform is not present"); + itkExceptionMacro(<< "Transform2 is not present"); } + if(!m_internalMeta1) { + itkExceptionMacro(<< "m_internalMeta1 is not present"); + } + if(!m_internalMeta2) { + itkExceptionMacro(<< "m_internalMeta2 is not present"); + } + if (!m_Interpolator1) { itkExceptionMacro(<< "Interpolator1 is not present"); } @@ -244,7 +302,7 @@ unsigned int gTwoImageToOneImageMetric::GetNumberOfPa break; } - return m_Transform1->GetNumberOfParameters(); + return m_IsocTransf->GetNumberOfParameters(); } template diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp index 0c2c739..494217f 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp @@ -68,6 +68,10 @@ itkImageProcessor::itkImageProcessor() transform2 = TransformType::New(); transform2->SetIdentity(); + m_InternalTransf1 = InternalTransformMetaInformation::New(); + m_InternalTransf2 = InternalTransformMetaInformation::New(); + + interpolator1 = InterpolatorType::New(); interpolator2 = InterpolatorType::New(); @@ -1281,174 +1285,33 @@ double itkImageProcessor::GetLocalizerDisplayWindowWidth(int iImg) } -//itkImageProcessor::TransformType::Pointer -//itkImageProcessor::MapTransformToNewOrigin( -// ImageType3D::PointType m_COR, // Center of rotation for the proj geometry. this is my new origin. -// ImageType3D::PointType m_Translations, -// ImageType3D::PointType m_Rotations -// ){ - -// TransformType::Pointer InputTransform = TransformType::New(); -// InputTransform->SetComputeZYX(true); -// InputTransform->SetIdentity(); - -// TransformType::OutputVectorType translation; -// translation[0] = m_Translations[0]; -// translation[1] = m_Translations[1]; -// translation[2] = m_Translations[2]; - -// InputTransform->SetTranslation(translation); - -// const double dtr = (atan(1.0) * 4.0) / 180.0; -// InputTransform->SetRotation( -// dtr * m_Rotations[0], -// dtr * m_Rotations[1], -// dtr * m_Rotations[2]); - -// ImageType3D::PointType m_TransformOrigin; -// m_TransformOrigin.Fill(0.); -// InputTransform->SetCenter( -// m_TransformOrigin ); - -// ImageType3D::PointType NewOriginTranslations = -// InputTransform->TransformPoint(m_COR); - -// ImageType3D::PointType DeltaNewOrigin = -// NewOriginTranslations - m_COR; - - -// TransformType::Pointer m_OutputTransform = -// TransformType::New(); -// m_OutputTransform ->SetComputeZYX(true); -// m_OutputTransform ->SetIdentity(); - -// translation[0] = DeltaNewOrigin[0]; -// translation[1] = DeltaNewOrigin[1]; -// translation[2] = DeltaNewOrigin[2]; - -// m_OutputTransform->SetTranslation(translation); -// m_OutputTransform->SetRotation( -// dtr * m_Rotations[0], -// dtr * m_Rotations[1], -// dtr * m_Rotations[2]); - -// m_OutputTransform->SetCenter(m_COR); - -// InputTransform = NULL; - -// return m_OutputTransform; -//} // This External User Transform thing need to be checked out -void itkImageProcessor::CalculateExternalUserTransform(TransformType::Pointer transform, DRTImageMetaInformation::Pointer imageMetaInfo) -{ - //crude hack to get from internal transform in LPS to external transform in IEC. - //result is stored in m_TransformMetaInfo - - //TODO: support for projectionTransformCenter and userTransformCenter which are not the same - //currentlz we support only pFakeIsoLPS situations. - - InternalImageType::DirectionType LPStoIEC_Directions; - LPStoIEC_Directions = m_CTMetaInfo->GetLPS2IECDirections(); - - auto parameters = transform->GetParameters(); - - ImageType3D::PointType translationUser; - translationUser[0] = parameters[3]; - translationUser[1] = parameters[4]; - translationUser[2] = parameters[5]; - ImageType3D::PointType rotationUser; - rotationUser[0] = parameters[0]; - rotationUser[1] = parameters[1]; - rotationUser[2] = parameters[2]; - - m_TransformMetaInfo->SetUserTranslations(LPStoIEC_Directions * translationUser); - m_TransformMetaInfo->SetUserRotations(LPStoIEC_Directions * rotationUser); -} - - -//itkImageProcessor::TransformType::Pointer -//itkImageProcessor::CalculateInternalTransformV2( -// ImageType3D::PointType m_TranslationOffset, //IEC -// ImageType3D::PointType m_RotationOffset, //IEC -// ImageType3D::PointType m_TranslationUser, //IEC -// ImageType3D::PointType m_RotationUser, //IEC -// ImageType3D::PointType m_CalibratedProjectionCenter, //LPS -// ImageType3D::PointType m_RTIsocenter, //LPS -// InternalImageType::DirectionType m_IECtoLPSDirections -// ) +//void itkImageProcessor::CalculateExternalUserTransform(TransformType::Pointer transform, DRTImageMetaInformation::Pointer imageMetaInfo) //{ +// //crude hack to get from internal transform in LPS to external transform in IEC. +// //result is stored in m_TransformMetaInfo -// //Convert all inputs into LPS +// //TODO: support for projectionTransformCenter and userTransformCenter which are not the same +// //currentlz we support only pFakeIsoLPS situations. -// ImageType3D::PointType m_TOffsetLPS = -// m_IECtoLPSDirections * m_TranslationOffset; +// InternalImageType::DirectionType LPStoIEC_Directions; +// LPStoIEC_Directions = m_CTMetaInfo->GetLPS2IECDirections(); -// ImageType3D::PointType m_ROffsetLPS = -// m_IECtoLPSDirections * m_RotationOffset; +// auto parameters = transform->GetParameters(); -// ImageType3D::PointType m_TUserLPS = -// m_IECtoLPSDirections * m_TranslationUser; - -// ImageType3D::PointType m_RUserLPS = -// m_IECtoLPSDirections * m_RotationUser; - -// TransformType::OutputVectorType translation; -// translation[0] = m_TOffsetLPS[0] + m_TUserLPS[0]; -// translation[1] = m_TOffsetLPS[1] + m_TUserLPS[1]; -// translation[2] = m_TOffsetLPS[2] + m_TUserLPS[2]; - -// TransformType::OutputVectorType rotations; -// rotations[0] = m_ROffsetLPS[0] + m_RUserLPS[0]; -// rotations[1] = m_ROffsetLPS[1] + m_RUserLPS[1]; -// rotations[2] = m_ROffsetLPS[2] + m_RUserLPS[2]; - -// // Map offset to the projection center -// TransformType::Pointer m_outputTransform = -// MapTransformToNewOrigin ( -// m_CalibratedProjectionCenter - m_RTIsocenter, -// translation, -// rotations -// ); - -// m_outputTransform->SetCenter(m_CalibratedProjectionCenter); - -// return m_outputTransform; - -//} - - -//itkImageProcessor::TransformType::Pointer -//itkImageProcessor::CalculateInternalTransformV3( -// ImageType3D::PointType m_Translation, //IEC -// ImageType3D::PointType m_Rotation, //IEC -// ImageType3D::PointType m_CalibratedProjectionCenter, //LPS -// ImageType3D::PointType m_RTIsocenter, //LPS -// InternalImageType::DirectionType m_IECtoLPSDirections -// ) -//{ - -// //Convert all inputs into LPS - -// ImageType3D::PointType m_TLPS = -// m_IECtoLPSDirections * m_Translation; - -// ImageType3D::PointType m_RLPS = -// m_IECtoLPSDirections * m_Rotation; - -// // Map offset to the projection center -// TransformType::Pointer m_outputTransform = -// MapTransformToNewOrigin ( -// m_CalibratedProjectionCenter - m_RTIsocenter, -// m_TLPS, -// m_RLPS -// ); - -// m_outputTransform->SetCenter(m_CalibratedProjectionCenter); - -// return m_outputTransform; +// ImageType3D::PointType translationUser; +// translationUser[0] = parameters[3]; +// translationUser[1] = parameters[4]; +// translationUser[2] = parameters[5]; +// ImageType3D::PointType rotationUser; +// rotationUser[0] = parameters[0]; +// rotationUser[1] = parameters[1]; +// rotationUser[2] = parameters[2]; +// m_TransformMetaInfo->SetUserTranslations(LPStoIEC_Directions * translationUser); +// m_TransformMetaInfo->SetUserRotations(LPStoIEC_Directions * rotationUser); //} @@ -1521,103 +1384,19 @@ void itkImageProcessor::InitializeRegistration( // registration->SetTransformMetaInfo(m_TransformMetaInfo); registration->SetTransformMetaInfo(m_r23MetaInfo); + registration->SetinternalMeta1(m_InternalTransf1); + registration->SetinternalMeta2(m_InternalTransf2); registration->SetFilter1(filter1); registration->SetFilter2(filter2); - //CalculateInternalTransform(transform1, m_DRTImage1MetaInfo); - /********* BEGIN CALCULATION OF INTERNAL TRANSFORM FOR PROJ1 *********/ -// ImageType3D::PointType ZeroPoint; -// ZeroPoint.Fill(0.); -// InternalImageType::DirectionType IECtoLPS_Directions; -// IECtoLPS_Directions = -// m_CTMetaInfo->GetLPS2IECDirections().GetTranspose(); -// TransformType::Pointer CurrTransform; -// if(m_RTMetaInfo == NULL) -// { -// CurrTransform = -// CalculateInternalTransformV3( -// m_TransformMetaInfo->GetT(), -// m_TransformMetaInfo->GetR(), -// m_DRTImage1MetaInfo->GetProjectionOriginLPSZero(), -// m_DRTImage1MetaInfo->GetProjectionOriginLPS(), -// IECtoLPS_Directions); - - -// } else { - -// CurrTransform = -// CalculateInternalTransformV3( -// m_TransformMetaInfo->GetT(), -// m_TransformMetaInfo->GetR(), -// m_DRTImage1MetaInfo->GetProjectionOriginLPSZero(), -// m_RTMetaInfo->GetIsocenterLPS() - m_CTMetaInfo->GetOriginLPS(), -// IECtoLPS_Directions -// ); - - - -// } - - -// transform1->SetComputeZYX(true); -// transform1->SetIdentity(); -// transform1->SetTranslation( -// CurrTransform->GetTranslation()); -// transform1->SetRotation( -// CurrTransform->GetAngleX(), -// CurrTransform->GetAngleY(), -// CurrTransform->GetAngleZ() -// ); -// transform1->SetCenter( -// m_DRTImage1MetaInfo->GetProjectionOriginLPSZero() ); - -// /********* END OF CALCULATE INTERNAL TRANSFORM FOR PROJ1 *********/ - - -// //CalculateInternalTransform(transform2, m_DRTImage2MetaInfo); -// /********* BEGIN CALCULATION OF INTERNAL TRANSFORM FOR PROJ2 *********/ -// if(m_RTMetaInfo == NULL) -// { -// CurrTransform = -// CalculateInternalTransformV3( -// m_TransformMetaInfo->GetT(), -// m_TransformMetaInfo->GetR(), -// m_DRTImage2MetaInfo->GetProjectionOriginLPSZero(), -// m_DRTImage2MetaInfo->GetProjectionOriginLPS(), -// IECtoLPS_Directions); - - -// } else { - - -// CurrTransform = -// CalculateInternalTransformV3( -// m_TransformMetaInfo->GetT(), -// m_TransformMetaInfo->GetR(), -// m_DRTImage2MetaInfo->GetProjectionOriginLPSZero(), -// m_RTMetaInfo->GetIsocenterLPS() - m_CTMetaInfo->GetOriginLPS(), -// IECtoLPS_Directions -// ); - - -// } -// transform2->SetComputeZYX(true); -// transform2->SetIdentity(); -// transform2->SetTranslation( -// CurrTransform->GetTranslation()); -// transform2->SetRotation( -// CurrTransform->GetAngleX(), -// CurrTransform->GetAngleY(), -// CurrTransform->GetAngleZ() -// ); -// transform2->SetCenter( -// m_DRTImage2MetaInfo->GetProjectionOriginLPSZero() ); - /********* END OF CALCULATE INTERNAL TRANSFORM FOR PROJ1 *********/ IsocTransf = TransformType::New(); + IsocTransf->SetComputeZYX(true); + IsocTransf->SetIdentity(); + IsocTransf->SetRotation( - m_TransformMetaInfo->GetR()[0], + m_TransformMetaInfo->GetR()[0], m_TransformMetaInfo->GetR()[1], m_TransformMetaInfo->GetR()[2] ); @@ -1690,8 +1469,8 @@ void itkImageProcessor::InitializeRegistration( const int numberOfSteps = 25; //In each direction. Total number of steps is ((2*numberOfSteps+1))^3. For 25 -> 132651. const double stepLength = 0.1; - auto parameters = transform1->GetParameters(); - transform1->SetParameters(parameters); + //auto parameters = transform1->GetParameters(); + //transform1->SetParameters(parameters); ExhaustiveOptimizerType::StepsType steps(3); steps[0] = numberOfSteps; @@ -1717,7 +1496,7 @@ int itkImageProcessor::StartRegistration(std::string extraInfo) // TODO: Check if the registartion pipeline has been initialized using ParametersType = RegistrationType::ParametersType; - auto startParameters = transform1->GetParameters(); + //auto startParameters = transform1->GetParameters(); time_t t = time(0); // get time now struct tm* now = localtime(&t); @@ -1784,54 +1563,106 @@ int itkImageProcessor::StartRegistration(std::string extraInfo) fs.close(); + + m_OptmizerValue = optimizer->GetValue(); + auto finalParameters = optimizer->GetCurrentPosition(); - auto finalParameters = transform1->GetParameters(); - std::cout<<"-->startParameters "<finalParameters1 "<GetParameters()<finalParameters2 "<GetParameters()<GetCurrentPosition(); - finalParameters = finalParameters - startParameters; - - std::cout<<"startParameters "<GetCenter()<GetTranslation()<GetCenter()<GetTranslation()<SetParameters(finalParameters); + // auto finalParameters = transform1->GetParameters(); + // std::cout<<"-->startParameters "<finalParameters1 "<GetParameters()<finalParameters2 "<GetParameters()<GetCurrentPosition(); + // finalParameters = finalParameters - startParameters; - const double translationAlongX = finalParameters[3]; - const double translationAlongY = finalParameters[4]; - const double translationAlongZ = finalParameters[5]; - const double rotationAlongX = finalParameters[0]; - const double rotationAlongY = finalParameters[1]; - const double rotationAlongZ = finalParameters[2]; + // std::cout<<"startParameters "<GetCenter()<GetTranslation()<GetCenter()<GetTranslation()<GetCurrentIteration(); - std::cout << "Result = " << std::endl; - std::cout << " Rotation Along X = " << rotationAlongX / dtr << " deg" << std::endl; - std::cout << " Rotation Along Y = " << rotationAlongY / dtr << " deg" << std::endl; - std::cout << " Rotation Along Z = " << rotationAlongZ / dtr << " deg" << std::endl; - std::cout << " Translation X = " << translationAlongX << " mm" << std::endl; - std::cout << " Translation Y = " << translationAlongY << " mm" << std::endl; - std::cout << " Translation Z = " << translationAlongZ << " mm" << std::endl; - std::cout << " Number Of Iterations = " << numberOfIterations << std::endl; - std::cout << " Metric value = " << m_OptmizerValue << std::endl; + // TransformType::Pointer offsetTransform = TransformType::New(); + // offsetTransform->SetParameters(finalParameters); + + // CalculateExternalUserTransform(offsetTransform, m_DRTImage1MetaInfo); + + // const double translationAlongX = finalParameters[3]; + // const double translationAlongY = finalParameters[4]; + // const double translationAlongZ = finalParameters[5]; + // const double rotationAlongX = finalParameters[0]; + // const double rotationAlongY = finalParameters[1]; + // const double rotationAlongZ = finalParameters[2]; + + // const int numberOfIterations = optimizer->GetCurrentIteration(); + + // std::cout << "Result = " << std::endl; + // std::cout << " Rotation Along X = " << rotationAlongX / dtr << " deg" << std::endl; + // std::cout << " Rotation Along Y = " << rotationAlongY / dtr << " deg" << std::endl; + // std::cout << " Rotation Along Z = " << rotationAlongZ / dtr << " deg" << std::endl; + // std::cout << " Translation X = " << translationAlongX << " mm" << std::endl; + // std::cout << " Translation Y = " << translationAlongY << " mm" << std::endl; + // std::cout << " Translation Z = " << translationAlongZ << " mm" << std::endl; + // std::cout << " Number Of Iterations = " << numberOfIterations << std::endl; + // std::cout << " Metric value = " << m_OptmizerValue << std::endl; std::cout << "#" << __COMPACT_PRETTY_FUNCTION__ << std::endl; return 0; } +Optimizer::ParametersType +itkImageProcessor::GetFinalR23Parameters(){ + + Optimizer::ParametersType pPars(6); + pPars.fill(0.); + + if(optimizer == nullptr){ + return pPars; + } + + switch (m_r23MetaInfo->GetDegreeOfFreedom()) { + case THREE_DOF: + pPars[3] = optimizer->GetCurrentPosition()[0] + - m_TransformMetaInfo->GetHiddenTranslations()[0]; + pPars[4] = optimizer->GetCurrentPosition()[1] + - m_TransformMetaInfo->GetHiddenTranslations()[1]; + pPars[5] = optimizer->GetCurrentPosition()[2] + - m_TransformMetaInfo->GetHiddenTranslations()[2]; + break; + + case SIX_DOF: + pPars[0] = optimizer->GetCurrentPosition()[0] + - m_TransformMetaInfo->GetHiddenRotations()[0]; + pPars[1] = optimizer->GetCurrentPosition()[1] + - m_TransformMetaInfo->GetHiddenRotations()[1]; + pPars[2] = optimizer->GetCurrentPosition()[2] + - m_TransformMetaInfo->GetHiddenRotations()[2]; + pPars[3] = optimizer->GetCurrentPosition()[3] + - m_TransformMetaInfo->GetHiddenTranslations()[0]; + pPars[4] = optimizer->GetCurrentPosition()[4] + - m_TransformMetaInfo->GetHiddenTranslations()[1]; + pPars[5] = optimizer->GetCurrentPosition()[5] + - m_TransformMetaInfo->GetHiddenTranslations()[2]; + break; + + default: + pPars.fill(0.); + break; + } + + + return + pPars; + +} + void itkImageProcessor::InitializeProjector() { @@ -1851,37 +1682,19 @@ void itkImageProcessor::InitializeProjector() ZeroPoint.Fill(0.); - InternalImageType::DirectionType IECtoLPS_Directions; + // InternalImageType::DirectionType IECtoLPS_Directions; - IECtoLPS_Directions = - m_CTMetaInfo->GetLPS2IECDirections().GetTranspose(); + // IECtoLPS_Directions = + // m_CTMetaInfo->GetLPS2IECDirections().GetTranspose(); TransformType::Pointer CurrTransform; - if(m_RTMetaInfo == NULL) - { - - CurrTransform = CalculateInternalTransformV3( - m_TransformMetaInfo->GetT(), - m_TransformMetaInfo->GetR(), - m_DRTImage1MetaInfo->GetProjectionOriginLPSZero(), - m_DRTImage1MetaInfo->GetProjectionOriginLPS(), - IECtoLPS_Directions); - - - } else { - - - CurrTransform = - CalculateInternalTransformV3( - m_TransformMetaInfo->GetT(), - m_TransformMetaInfo->GetR(), - m_DRTImage1MetaInfo->GetProjectionOriginLPSZero(), - m_RTMetaInfo->GetIsocenterLPS() - m_CTMetaInfo->GetOriginLPS(), - IECtoLPS_Directions - ); - - } + CurrTransform= CalculateInternalTransformV3( + m_TransformMetaInfo->GetT(), + m_TransformMetaInfo->GetR(), + m_InternalTransf1->GetpCalProjCenter(), + m_InternalTransf1->GetpRTIsocenter(), + m_InternalTransf1->GetIECtoLPSDirs()); transform1->SetComputeZYX(true); @@ -1912,30 +1725,12 @@ void itkImageProcessor::InitializeProjector() interpolator1->SetTransform(transform1); interpolator1->Initialize(); - if(m_RTMetaInfo == NULL) - { - - CurrTransform = - CalculateInternalTransformV3( - m_TransformMetaInfo->GetT(), - m_TransformMetaInfo->GetR(), - m_DRTImage2MetaInfo->GetProjectionOriginLPSZero(), - m_DRTImage2MetaInfo->GetProjectionOriginLPS(), - IECtoLPS_Directions); - - - - } else { - - CurrTransform = CalculateInternalTransformV3( - m_TransformMetaInfo->GetT(), - m_TransformMetaInfo->GetR(), - m_DRTImage2MetaInfo->GetProjectionOriginLPSZero(), - m_RTMetaInfo->GetIsocenterLPS() - m_CTMetaInfo->GetOriginLPS(), - IECtoLPS_Directions - ); - - } + CurrTransform= CalculateInternalTransformV3( + m_TransformMetaInfo->GetT(), + m_TransformMetaInfo->GetR(), + m_InternalTransf2->GetpCalProjCenter(), + m_InternalTransf2->GetpRTIsocenter(), + m_InternalTransf2->GetIECtoLPSDirs()); transform2->SetComputeZYX(true); @@ -2258,6 +2053,29 @@ void itkImageProcessor::UpdateProjectionGeometryMeta(){ Std_DRT2LPS) ); + if(m_RTMetaInfo == NULL) + { + m_InternalTransf1->SetpCalProjCenter( + m_DRTImage1MetaInfo->GetProjectionOriginLPSZero()); + m_InternalTransf1->SetpRTIsocenter( + m_DRTImage1MetaInfo->GetProjectionOriginLPS()); + InternalImageType::DirectionType IECtoLPS_Directions; + IECtoLPS_Directions = + m_CTMetaInfo->GetLPS2IECDirections().GetTranspose(); + m_InternalTransf1->SetIECtoLPSDirs(IECtoLPS_Directions); + + } else { + m_InternalTransf1->SetpCalProjCenter( + m_DRTImage1MetaInfo->GetProjectionOriginLPSZero()); + m_InternalTransf1->SetpRTIsocenter( + m_RTMetaInfo->GetIsocenterLPS() - m_CTMetaInfo->GetOriginLPS()); + InternalImageType::DirectionType IECtoLPS_Directions; + IECtoLPS_Directions = + m_CTMetaInfo->GetLPS2IECDirections().GetTranspose(); + m_InternalTransf1->SetIECtoLPSDirs(IECtoLPS_Directions); + + } + // SECOND @@ -2347,6 +2165,29 @@ void itkImageProcessor::UpdateProjectionGeometryMeta(){ Std_DRT2LPS) ); + if(m_RTMetaInfo == NULL) + { + m_InternalTransf2->SetpCalProjCenter( + m_DRTImage2MetaInfo->GetProjectionOriginLPSZero()); + m_InternalTransf2->SetpRTIsocenter( + m_DRTImage2MetaInfo->GetProjectionOriginLPS()); + InternalImageType::DirectionType IECtoLPS_Directions; + IECtoLPS_Directions = + m_CTMetaInfo->GetLPS2IECDirections().GetTranspose(); + m_InternalTransf2->SetIECtoLPSDirs(IECtoLPS_Directions); + + } else { + m_InternalTransf2->SetpCalProjCenter( + m_DRTImage2MetaInfo->GetProjectionOriginLPSZero()); + m_InternalTransf2->SetpRTIsocenter( + m_RTMetaInfo->GetIsocenterLPS() - m_CTMetaInfo->GetOriginLPS()); + InternalImageType::DirectionType IECtoLPS_Directions; + IECtoLPS_Directions = + m_CTMetaInfo->GetLPS2IECDirections().GetTranspose(); + m_InternalTransf2->SetIECtoLPSDirs(IECtoLPS_Directions); + + } + } @@ -2398,35 +2239,13 @@ void itkImageProcessor::GetProjectionImages(){ transform1->SetComputeZYX(true); transform1->SetIdentity(); - InternalImageType::DirectionType IECtoLPS_Directions; - - IECtoLPS_Directions = - m_CTMetaInfo->GetLPS2IECDirections().GetTranspose(); TransformType::Pointer CurrTransform; - - - if(m_RTMetaInfo == NULL) - { - CurrTransform = - CalculateInternalTransformV3( - m_TransformMetaInfo->GetT(), - m_TransformMetaInfo->GetR(), - m_DRTImage1MetaInfo->GetProjectionOriginLPSZero(), - m_DRTImage1MetaInfo->GetProjectionOriginLPS(), - IECtoLPS_Directions); - - } else { - - CurrTransform = - CalculateInternalTransformV3( - m_TransformMetaInfo->GetT(), - m_TransformMetaInfo->GetR(), - m_DRTImage1MetaInfo->GetProjectionOriginLPSZero(), - m_RTMetaInfo->GetIsocenterLPS() - m_CTMetaInfo->GetOriginLPS(), - IECtoLPS_Directions - ); - - } + CurrTransform= CalculateInternalTransformV3( + m_TransformMetaInfo->GetT(), + m_TransformMetaInfo->GetR(), + m_InternalTransf1->GetpCalProjCenter(), + m_InternalTransf1->GetpRTIsocenter(), + m_InternalTransf1->GetIECtoLPSDirs()); transform1->SetComputeZYX(true); @@ -2460,32 +2279,12 @@ void itkImageProcessor::GetProjectionImages(){ transform2->SetComputeZYX(true); transform2->SetIdentity(); - - - if(m_RTMetaInfo == NULL) - { - - CurrTransform = - CalculateInternalTransformV3( - m_TransformMetaInfo->GetT(), - m_TransformMetaInfo->GetR(), - m_DRTImage2MetaInfo->GetProjectionOriginLPSZero(), - m_DRTImage2MetaInfo->GetProjectionOriginLPS(), - IECtoLPS_Directions); - - } else { - - CurrTransform = CalculateInternalTransformV3( - m_TransformMetaInfo->GetT(), - m_TransformMetaInfo->GetR(), - m_DRTImage2MetaInfo->GetProjectionOriginLPSZero(), - m_RTMetaInfo->GetIsocenterLPS() - m_CTMetaInfo->GetOriginLPS(), - IECtoLPS_Directions - ); - - - } - + CurrTransform = CalculateInternalTransformV3( + m_TransformMetaInfo->GetT(), + m_TransformMetaInfo->GetR(), + m_InternalTransf2->GetpCalProjCenter(), + m_InternalTransf2->GetpRTIsocenter(), + m_InternalTransf2->GetIECtoLPSDirs()); transform2->SetComputeZYX(true); @@ -3059,26 +2858,26 @@ double* itkImageProcessor::GetTransformParameters(){ return dTransfParam; } -// THESE ARE CALLED AT THE END OF REG -void itkImageProcessor::GetFinalTranslations(double& dX, double& dY, double& dZ) -{ - ImageType3D::PointType userTranslations = m_TransformMetaInfo->GetUserTranslations(); +//// THESE ARE CALLED AT THE END OF REG +//void itkImageProcessor::GetFinalTranslations(double& dX, double& dY, double& dZ) +//{ +// ImageType3D::PointType userTranslations = m_TransformMetaInfo->GetUserTranslations(); - dX = userTranslations[0]; - dY = userTranslations[1]; - dZ = userTranslations[2]; -} +// dX = userTranslations[0]; +// dY = userTranslations[1]; +// dZ = userTranslations[2]; +//} -// THESE ARE CALLED AT THE END OF REG -void itkImageProcessor::GetFinalRotations(double& dRX, double& dRY, double& dRZ) -{ - ImageType3D::PointType userRotations = m_TransformMetaInfo->GetUserRotations(); +//// THESE ARE CALLED AT THE END OF REG +//void itkImageProcessor::GetFinalRotations(double& dRX, double& dRY, double& dRZ) +//{ +// ImageType3D::PointType userRotations = m_TransformMetaInfo->GetUserRotations(); - dRX = userRotations[0]; - dRY = userRotations[1]; - dRZ = userRotations[2]; +// dRX = userRotations[0]; +// dRY = userRotations[1]; +// dRZ = userRotations[2]; -} +//} double itkImageProcessor::GetOptimizerValue() { diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.h b/reg23Topograms/itkDTRrecon/itkImageProcessor.h index e83945c..285e756 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.h +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.h @@ -139,13 +139,17 @@ public: void SetInitialTranslations(double, double, double); void SetInitialRotations(double, double, double); - /** Get transform parameters for 3D Volume */ - void GetFinalTranslations(double&, double&, double&); - void GetFinalRotations(double&, double&, double&); - /** Set user transform parameters for 3D Volume in LPS*/ - void SetUserTranslationsLPS(double, double, double); - void SetUserRotationsLPS(double, double, double); + Optimizer::ParametersType + GetFinalR23Parameters(); + + /** Get transform parameters for 3D Volume */ +// void GetFinalTranslations(double&, double&, double&); +// void GetFinalRotations(double&, double&, double&); + +// /** Set user transform parameters for 3D Volume in LPS*/ +// void SetUserTranslationsLPS(double, double, double); +// void SetUserRotationsLPS(double, double, double); /** Initialize the registration pipeline*/ void InitializeRegistration(double, double, eDegreeOfFreedomType); @@ -238,6 +242,8 @@ private: using InterpolatorType = itk::gSiddonJacobsRayCastInterpolateImageFunction; using ResampleFilterType = itk::ResampleImageFilter; + //using gTransformType = itk::gEuler3DTransform; + /** Optimizer which tries to find the minimn (Powell Optimizer)*/ using AmoebaOptimizerType = itk::AmoebaOptimizer; /** Optimizer which samples the whol space */ @@ -266,23 +272,10 @@ private: /** ITK to VTK filter */ using ITKtoVTKFilterType = itk::ImageToVTKImageFilter; - void - CalculateExternalUserTransform( - TransformType::Pointer transform, - DRTImageMetaInformation::Pointer imageMetaInfo); - - /* Calculate the transform used in siddon. - * The isocentric transform is mapped to the calibrated center of projection */ -// TransformType::Pointer -// CalculateInternalTransformV2( -// ImageType3D::PointType m_TranslationOffset, -// ImageType3D::PointType m_RotationOffset, -// ImageType3D::PointType m_TranslationUser, -// ImageType3D::PointType m_RotationUser, -// ImageType3D::PointType m_CalibratedProjectionCenter, -// ImageType3D::PointType m_RTIsocenter, -// InternalImageType::DirectionType m_IECtoLPSDirections -// ); +// void +// CalculateExternalUserTransform( +// TransformType::Pointer transform, +// DRTImageMetaInformation::Pointer imageMetaInfo); TransformType::Pointer @@ -419,6 +412,10 @@ private: R23MetaInformation::Pointer m_r23MetaInfo; + InternalTransformMetaInformation::Pointer + m_InternalTransf1, + m_InternalTransf2; + double m_OptmizerValue; int m_MaxNumberOfIterations; diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessorHelpers.cpp b/reg23Topograms/itkDTRrecon/itkImageProcessorHelpers.cpp index 018ecf1..730ceb6 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessorHelpers.cpp +++ b/reg23Topograms/itkDTRrecon/itkImageProcessorHelpers.cpp @@ -1,7 +1,78 @@ #include "itkImageProcessorHelpers.h" -itk::TransformType::Pointer -itk::MapTransformToNewOrigin( +namespace itk { + +//template +//gEuler3DTransform ::gEuler3DTransform() +//{ +// //m_CalibPrjCenter = nullptr; // has to be provided by the user. +// //m_RTIso = nullptr; // has to be provided by the user. +// // m_IECtoLPSDirs =; // has to be provided by the user. +//} + + +//template +//gEuler3DTransform::gEuler3DTransform +//(const MatrixType & matrix, const OutputPointType & offset) +//{ + + +//} + +//template +//gEuler3DTransform::gEuler3DTransform +//(unsigned int parametersDimension) +// : Superclass(parametersDimension) + +//{ + +//} + +//template +//void gEuler3DTransform ::SetParameters(const ParametersType & parameters) +//{ + +//// if(m_CalibPrjCenter != nullptr && +//// m_RTIso != nullptr //&& +//// //m_IECtoLPSDirs != nullptr +//// ){ + +//// itk::Point pT; +//// pT[0] = parameters[3]; +//// pT[1] = parameters[4]; +//// pT[2] = parameters[5]; + +//// itk::Point pR; +//// pR[0] = parameters[0]; +//// pR[1] = parameters[1]; +//// pR[2] = parameters[2]; + +//// TransformType::Pointer m_OutputTransform = +//// CalculateInternalTransformV3( +//// pT, +//// pR, +//// m_CalibPrjCenter, +//// m_RTIso, +//// m_IECtoLPSDirs); +//// Superclass::SetParameters(m_OutputTransform->GetParameters()); +//// }else{ +// Superclass::SetParameters(parameters); +//// } + + +//} + +//template +//void gEuler3DTransform ::PrintSelf(std::ostream& os, Indent indent) const +//{ +// Superclass::PrintSelf(os, indent); +// //os << indent << "ComputeGradient: " << static_cast::PrintType>(m_ComputeGradient) +// // << std::endl; +//} + + +TransformType::Pointer +MapTransformToNewOrigin( ImageType3D::PointType m_COR, // Center of rotation for the proj geometry. this is my new origin. ImageType3D::PointType m_Translations, ImageType3D::PointType m_Rotations @@ -60,8 +131,8 @@ itk::MapTransformToNewOrigin( -itk::TransformType::Pointer -itk::CalculateInternalTransformV3( +TransformType::Pointer +CalculateInternalTransformV3( ImageType3D::PointType m_Translation, //IEC ImageType3D::PointType m_Rotation, //IEC ImageType3D::PointType m_CalibratedProjectionCenter, //LPS @@ -91,3 +162,5 @@ itk::CalculateInternalTransformV3( return m_outputTransform; } + +} diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessorHelpers.h b/reg23Topograms/itkDTRrecon/itkImageProcessorHelpers.h index 2b8aec8..aa8a355 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessorHelpers.h +++ b/reg23Topograms/itkDTRrecon/itkImageProcessorHelpers.h @@ -4,10 +4,80 @@ #include "itkEuler3DTransform.h" #include "itkImage.h" +#include "itkEuler3DTransform.h" +#include "itkCommand.h" +#include "itkObject.h" +#include "itkObjectFactory.h" namespace itk { + + + + + +//template +//class ITK_TEMPLATE_EXPORT gEuler3DTransform : +// public Euler3DTransform +//{ + +//public: +// ITK_DISALLOW_COPY_AND_ASSIGN(gEuler3DTransform); +// /** Standard class type aliases. */ +// using Self = gEuler3DTransform; +// using Superclass = Euler3DTransform; +// using Pointer = SmartPointer; +// using ConstPointer = SmartPointer; + +// /** New macro for creation of through a Smart Pointer. */ +// itkNewMacro(Self); + +// /** Run-time type information (and related methods). */ +// itkTypeMacro(gEuler3DTransform, Euler3DTransform); + +// // static constexpr unsigned int ParametersDimension = 6; + +// using MatrixType = typename Superclass::MatrixType; +// using OutputPointType = typename Superclass::OutputPointType; +// using ParametersType = typename Superclass::ParametersType; +// using PointType = typename itk::Point; + +// /** Set/Get the transformation from a container of parameters +// * This is typically used by optimizers. There are 6 parameters. The first +// * three represent the angles to rotate around the coordinate axis, and the +// * last three represents the offset. */ +// void +// SetParameters(const ParametersType & parameters) override; + +// itkSetMacro (CalibPrjCenter, PointType); +// itkSetMacro (RTIso, PointType); +// itkSetMacro(IECtoLPSDirs,MatrixType); + + +//protected: +// gEuler3DTransform(const MatrixType & matrix, const OutputPointType & offset); +// gEuler3DTransform(unsigned int parametersDimension); +// gEuler3DTransform(); + +// ~gEuler3DTransform() override = default; + +// PointType +// m_CalibPrjCenter, +// m_RTIso; + +// MatrixType +// m_IECtoLPSDirs; + + +// void +// PrintSelf(std::ostream & os, Indent indent) const override; + +//}; + + + +using TransformType = itk::Euler3DTransform; constexpr static unsigned int Dimension = 3; using PixelType3D = short; using InternalPixelType = float; @@ -15,7 +85,6 @@ using InternalPixelType = float; using ImageType3D = itk::Image; using InternalImageType = itk::Image; -using TransformType = itk::Euler3DTransform; TransformType::Pointer MapTransformToNewOrigin( @@ -33,6 +102,8 @@ TransformType::Pointer ImageType3D::PointType m_RTIsocenter, InternalImageType::DirectionType m_IECtoLPSDirections ); + + } #endif diff --git a/reg23Topograms/itkDTRrecon/itkQtIterationUpdate.h b/reg23Topograms/itkDTRrecon/itkQtIterationUpdate.h index 91e982a..89b231d 100644 --- a/reg23Topograms/itkDTRrecon/itkQtIterationUpdate.h +++ b/reg23Topograms/itkDTRrecon/itkQtIterationUpdate.h @@ -118,11 +118,17 @@ public: std::cout.precision(oldprecision); std::cout << "Position: " << optimizer->GetCurrentPosition() << std::endl; +// objIterUpdate->onIteration( +// optimizer->GetCurrentIteration()+1, +// optimizer->GetCurrentPosition()[0], +// optimizer->GetCurrentPosition()[2], +// -optimizer->GetCurrentPosition()[1] +// ); objIterUpdate->onIteration( optimizer->GetCurrentIteration()+1, optimizer->GetCurrentPosition()[0], - optimizer->GetCurrentPosition()[2], - -optimizer->GetCurrentPosition()[1] + optimizer->GetCurrentPosition()[1], + optimizer->GetCurrentPosition()[2] ); } return; @@ -172,7 +178,9 @@ public: os->precision(std::numeric_limits::digits10 + 2); *os << optimizer->GetCurrentValue(); os->precision(oldprecision); - *os << "\t" << position[0] << "\t" << position[2] << "\t" << -position[1] << std::endl; + //*os << "\t" << position[0] << "\t" << position[2] << "\t" << -position[1] << std::endl; + *os << "\t" << position[0] << "\t" << position[1] << "\t" << position[2] << std::endl; + } return; } From 9b616b3b550f4001abe330f155d6e622c8d1424d Mon Sep 17 00:00:00 2001 From: Proton local user Date: Mon, 15 May 2023 17:02:18 +0200 Subject: [PATCH 42/49] a number of autoREG and geometry fixes - automatic registration actually makes use of ROI. Before were ignored. - cleanup of user and hidden transform and pass to UI after registration. - change of internal image interpolator used in autoREG. Now autoREG performs well. - general number of working units variable. - GetFinalRotations, GetFinalTranslations and GetTransformParameters become obsolete. - GetFinalR23Parameters and GetCompleteIsocentricTransform and GetUserIsocentricTransform are provided. - only GetCompleteIsocentricTransform is missing implementation. --- ...ualInformationTwoImageToOneImageMetric.hxx | 58 ++++-- .../itkTwoProjectionImageRegistrationMethod.h | 7 +- ...tkTwoProjectionImageRegistrationMethod.hxx | 43 +++-- .../autoreg/itkgTwoImageToOneImageMetric.hxx | 114 ++++++----- .../itkDTRrecon/itkImageProcessor.cpp | 181 ++++++++++-------- .../itkDTRrecon/itkImageProcessor.h | 34 ++-- .../itkDTRrecon/itkImageProcessorHelpers.cpp | 68 ------- .../itkDTRrecon/itkImageProcessorHelpers.h | 63 ------ 8 files changed, 250 insertions(+), 318 deletions(-) diff --git a/reg23Topograms/itkDTRrecon/autoreg/itkMutualInformationTwoImageToOneImageMetric.hxx b/reg23Topograms/itkDTRrecon/autoreg/itkMutualInformationTwoImageToOneImageMetric.hxx index 089c7f9..561225f 100644 --- a/reg23Topograms/itkDTRrecon/autoreg/itkMutualInformationTwoImageToOneImageMetric.hxx +++ b/reg23Topograms/itkDTRrecon/autoreg/itkMutualInformationTwoImageToOneImageMetric.hxx @@ -93,33 +93,61 @@ MutualInformationTwoImageToOneImageMetric::GetValue() itkExceptionMacro(<< "Fixed filter1 has not been assigned"); } + if (!this->m_Transform1) { + itkExceptionMacro(<< "m_Transform1 has not been assigned"); + } + + if (!this->m_Transform2) { + itkExceptionMacro(<< "m_Transform2 has not been assigned"); + } + + + std::cout<< "----- itkMutualInformationTwoImage GetValue -----" <m_Transform1.GetPointer()->GetCenter() <m_Transform1.GetPointer()->GetParameters() <m_Interpolator1->SetTransform(this->m_Transform1); this->m_Interpolator1->Initialize(); this->m_Filter1->Update(); using InternalMetricType = itk::MattesMutualInformationImageToImageMetric; - - using NearestNeighborType = itk::NearestNeighborInterpolateImageFunction; + /* + * NearestNeighborType in our images results in not resolving for the cranio-caudal direction. + * in LPS-Z we are very much bound to the CT resolution, therefore if we take the Nearest Neighbor + * we simply do not explore that direction... and will always have an uncertainty of 1 slice thickness. + * */ + //using NearestNeighborType = itk::NearestNeighborInterpolateImageFunction; + /* + * LinearInterpolateImageFunction performs better for us, performance degradation not noticeable. + * */ + using LinearInterpType = itk::LinearInterpolateImageFunction; //We need to set transform and parameters. auto dummyTransform = TransformType::New(); auto dummyParameters = dummyTransform->GetParameters(); - auto dummyInterpolator1 = NearestNeighborType::New(); + auto dummyInterpolator1 = LinearInterpType::New(); auto metric1 = InternalMetricType::New(); metric1->SetTransform(dummyTransform); metric1->SetTransformParameters(dummyParameters); metric1->SetInterpolator(dummyInterpolator1); - auto fixedImageRegion1 = fixedImage1->GetBufferedRegion(); - metric1->SetFixedImageRegion(fixedImageRegion1); + //auto fixedImageRegion1 = fixedImage1->GetBufferedRegion(); + //metric1->SetFixedImageRegion(fixedImageRegion1); + /* We get the fixed image region from the parent class... */ + metric1->SetFixedImageRegion(Superclass::GetFixedImageRegion1()); + std::cout<< "-----> Mutual :: fixedImageRegion1: "<< metric1->GetFixedImageRegion() << std::endl; auto movingImageRegion = this->m_Filter1->GetOutput()->GetBufferedRegion(); unsigned int numberOfPixels = movingImageRegion.GetNumberOfPixels(); //auto numberOfSamples = static_cast(numberOfPixels * 0.50); //100% - metric1->UseAllPixelsOn(); - metric1->SetNumberOfHistogramBins(30); + // since we have a ROI, then we should not set allPixels to TRUE. + //metric1->UseAllPixelsOn(); + metric1->SetNumberOfHistogramBins(50); metric1->SetFixedImage(fixedImage1); metric1->SetMovingImage(this->m_Filter1->GetOutput()); @@ -132,26 +160,26 @@ MutualInformationTwoImageToOneImageMetric::GetValue() this->m_Interpolator2->Initialize(); this->m_Filter2->Update(); - auto dummyInterpolator2 = NearestNeighborType::New(); + auto dummyInterpolator2 = LinearInterpType::New(); auto metric2 = InternalMetricType::New(); metric2->SetTransform(dummyTransform); metric2->SetTransformParameters(dummyParameters); metric2->SetInterpolator(dummyInterpolator2); - auto fixedImageRegion2 = fixedImage1->GetBufferedRegion(); - metric2->SetFixedImageRegion(fixedImageRegion2); +// auto fixedImageRegion2 = fixedImage2->GetBufferedRegion(); +// metric2->SetFixedImageRegion(fixedImageRegion2); + metric2->SetFixedImageRegion(Superclass::GetFixedImageRegion2()); + std::cout<< "-----> Mutual :: fixedImageRegion2: "<< metric2->GetFixedImageRegion() << std::endl; movingImageRegion = this->m_Filter2->GetOutput()->GetBufferedRegion(); numberOfPixels = movingImageRegion.GetNumberOfPixels(); //numberOfSamples = static_cast(numberOfPixels * 0.50); //100% - //%metric2->SetNumberOfSpatialSamples(numberOfSamples); - metric2->UseAllPixelsOn(); - metric2->SetNumberOfHistogramBins(30); - + //metric2->SetNumberOfSpatialSamples(numberOfSamples); + //metric2->UseAllPixelsOn(); + metric2->SetNumberOfHistogramBins(50); metric2->SetFixedImage(fixedImage2); metric2->SetMovingImage(this->m_Filter2->GetOutput()); - metric2->Initialize(); auto measure2 = metric2->GetValue(dummyParameters); diff --git a/reg23Topograms/itkDTRrecon/autoreg/itkTwoProjectionImageRegistrationMethod.h b/reg23Topograms/itkDTRrecon/autoreg/itkTwoProjectionImageRegistrationMethod.h index d389042..9ddf934 100644 --- a/reg23Topograms/itkDTRrecon/autoreg/itkTwoProjectionImageRegistrationMethod.h +++ b/reg23Topograms/itkDTRrecon/autoreg/itkTwoProjectionImageRegistrationMethod.h @@ -246,8 +246,8 @@ protected: itkSetMacro(LastOptimizerParameters, ParametersType); /** Entry-point for internal ITK filter observer. **/ - void OnInternalFilterProgressReceptor(itk::Object *caller, - const itk::EventObject &event); +// void OnInternalFilterProgressReceptor(itk::Object *caller, +// const itk::EventObject &event); private: @@ -269,9 +269,6 @@ private: m_internalMeta1, m_internalMeta2; - //TransformMetaInformation::Pointer - // m_TransformMetaInfo; - R23MetaInformation::Pointer m_TransformMetaInfo; diff --git a/reg23Topograms/itkDTRrecon/autoreg/itkTwoProjectionImageRegistrationMethod.hxx b/reg23Topograms/itkDTRrecon/autoreg/itkTwoProjectionImageRegistrationMethod.hxx index b871033..2c9b6e0 100644 --- a/reg23Topograms/itkDTRrecon/autoreg/itkTwoProjectionImageRegistrationMethod.hxx +++ b/reg23Topograms/itkDTRrecon/autoreg/itkTwoProjectionImageRegistrationMethod.hxx @@ -160,6 +160,7 @@ void TwoProjectionImageRegistrationMethod::Initialize m_Metric->SetFixedImage2(m_FixedImage2); m_Metric->SetTransform1(m_Transform1); m_Metric->SetTransform2(m_Transform2); + m_Metric->SetIsocTransf(m_IsocIECTransform); m_Metric->SetTransformMetaInfo(m_TransformMetaInfo); m_Metric->SetinternalMeta1(m_internalMeta1); @@ -197,31 +198,31 @@ void TwoProjectionImageRegistrationMethod::Initialize m_Optimizer->SetInitialPosition(m_InitialOptimizerParameters); } -template -void TwoProjectionImageRegistrationMethod::OnInternalFilterProgressReceptor( - itk::Object *caller, const itk::EventObject &event) -{ - itk::ProcessObject *filter = dynamic_cast(caller); +//template +//void TwoProjectionImageRegistrationMethod::OnInternalFilterProgressReceptor( +// itk::Object *caller, const itk::EventObject &event) +//{ +// itk::ProcessObject *filter = dynamic_cast(caller); - if(!itk::ProgressEvent().CheckEvent(&event) || !filter) - return; +// if(!itk::ProgressEvent().CheckEvent(&event) || !filter) +// return; - if (filter) - { -// double p = m_CurrentProgressStart; -// // filter->GetProgress() in [0;1] -// p += m_CurrentProgressSpan * filter->GetProgress(); -// // NOTE: filter is buggy - not in [0;1] if multi-threading is activated! -// if (p > (m_CurrentProgressStart + m_CurrentProgressSpan)) -// p = m_CurrentProgressStart + m_CurrentProgressSpan; -// TaskProgressInfo(m_CurrentProgressDirection, p); +// if (filter) +// { +//// double p = m_CurrentProgressStart; +//// // filter->GetProgress() in [0;1] +//// p += m_CurrentProgressSpan * filter->GetProgress(); +//// // NOTE: filter is buggy - not in [0;1] if multi-threading is activated! +//// if (p > (m_CurrentProgressStart + m_CurrentProgressSpan)) +//// p = m_CurrentProgressStart + m_CurrentProgressSpan; +//// TaskProgressInfo(m_CurrentProgressDirection, p); -// if (m_CancelRequest) -// filter->SetAbortGenerateData(true); // may be handled by filter +//// if (m_CancelRequest) +//// filter->SetAbortGenerateData(true); // may be handled by filter - std::cout << "OnInternalFilterProgressReceptor :: filter (TRUE) " << std::endl; - } -} +// std::cout << "OnInternalFilterProgressReceptor :: filter (TRUE) " << std::endl; +// } +//} /* * Starts the Registration Process diff --git a/reg23Topograms/itkDTRrecon/autoreg/itkgTwoImageToOneImageMetric.hxx b/reg23Topograms/itkDTRrecon/autoreg/itkgTwoImageToOneImageMetric.hxx index b2c2f2b..d8b0cea 100644 --- a/reg23Topograms/itkDTRrecon/autoreg/itkgTwoImageToOneImageMetric.hxx +++ b/reg23Topograms/itkDTRrecon/autoreg/itkgTwoImageToOneImageMetric.hxx @@ -56,13 +56,15 @@ bool gTwoImageToOneImageMetric::SetTransformParameter if (!m_Transform2) { itkExceptionMacro(<< "Transform 2 has not been assigned"); } - if (!m_internalMeta1){ itkExceptionMacro(<< "m_internalMeta1 has not been assigned"); } if (!m_internalMeta2){ - itkExceptionMacro(<< "m_internalMeta2 has not been assigned"); - } + itkExceptionMacro(<< "m_internalMeta2 has not been assigned"); + } + if (!m_IsocTransf){ + itkExceptionMacro(<< "m_IsocTransf has not been assigned"); + } //auto transformParameters = m_Transform1->GetParameters(); auto transformParameters = m_IsocTransf->GetParameters(); @@ -109,7 +111,7 @@ bool gTwoImageToOneImageMetric::SetTransformParameter break; } - std::cout << "New Transform Parameters = " << std::endl; + std::cout << "New Transform Parameters ISOC IEC = " << std::endl; std::cout << " Translation X = " << TranslationAlongX << " mm" << std::endl; std::cout << " Translation Y = " << TranslationAlongY << " mm" << std::endl; std::cout << " Translation Z = " << TranslationAlongZ << " mm" << std::endl; @@ -119,67 +121,72 @@ bool gTwoImageToOneImageMetric::SetTransformParameter std::cout << "+++++++++++++++++++++++++++++++++++++++++++++++++++++++" << std::endl; - //HERE WE HAVE TO CALCULATE INTERNAL TRANSFORMS!!! - // GIOVANNI - + // individual R and T components of the IsoC transform ImageType3D::PointType - pT; + pT; pT[0] = TranslationAlongX; pT[1] = TranslationAlongY; pT[2] = TranslationAlongZ; ImageType3D::PointType - pR; + pR; pR[0] = RotationAlongX; pR[1] = RotationAlongY; pR[2] = RotationAlongZ; - TransformType::Pointer CurrTransform; - CurrTransform = CalculateInternalTransformV3( - pT, - pR, - m_internalMeta1->GetpCalProjCenter(), - m_internalMeta1->GetpRTIsocenter(), - m_internalMeta1->GetIECtoLPSDirs()); + // check if we are within tolerance + bool transformValid = + (std::abs(pT[0]) < m_MaxTranslation) && + (std::abs(pT[1]) < m_MaxTranslation) && + (std::abs(pT[2]) < m_MaxTranslation); - m_Transform1->SetIdentity(); - m_Transform1->SetParameters( - CurrTransform->GetParameters()); - m_Transform1->SetCenter( + if (transformValid) { + /* + Here we calculate the transform for eack projection corresponding to the isocentric + one we are optimizing. + This calculation takes into account calibrated center of projection for each view. + */ + + // Calculate internal transform1 + TransformType::Pointer CurrTransform; + CurrTransform = CalculateInternalTransformV3( + pT, + pR, + m_internalMeta1->GetpCalProjCenter(), + m_internalMeta1->GetpRTIsocenter(), + m_internalMeta1->GetIECtoLPSDirs()); + + m_Transform1->SetIdentity(); + m_Transform1->SetParameters( + CurrTransform->GetParameters()); + m_Transform1->SetCenter( m_internalMeta1->GetpCalProjCenter()); - // std::cout << "m_Transform1 PARS: "<< m_Transform1->GetParameters()<GetpCalProjCenter(), - m_internalMeta2->GetpRTIsocenter(), - m_internalMeta2->GetIECtoLPSDirs()); - m_Transform2->SetIdentity(); - m_Transform2->SetParameters( - CurrTransform->GetParameters()); - m_Transform2->SetCenter( - m_internalMeta2->GetpCalProjCenter()); - // std::cout << "m_Transform2 PARS: "<< m_Transform2->GetParameters()<GetCenter()<GetParameters()<SetParameters(transformParameters); -// m_Transform2->SetParameters(transformParameters); -// } else { -// std::cout << " Transform invalid, out of range!" << std::endl; -// std::cout << "+++++++++++++++++++++++++++++++++++++++++++++++++++++++" << std::endl; -// } + // Calculate internal transform2 + CurrTransform = CalculateInternalTransformV3( + pT, + pR, + m_internalMeta2->GetpCalProjCenter(), + m_internalMeta2->GetpRTIsocenter(), + m_internalMeta2->GetIECtoLPSDirs()); + + m_Transform2->SetIdentity(); + m_Transform2->SetParameters( + CurrTransform->GetParameters()); + m_Transform2->SetCenter( + m_internalMeta2->GetpCalProjCenter()); + + } else { + std::cout << " Transform invalid, out of range!" << std::endl; + std::cout << "+++++++++++++++++++++++++++++++++++++++++++++++++++++++" << std::endl; + } + return transformValid; } @@ -203,8 +210,8 @@ void gTwoImageToOneImageMetric::Initialize() itkExceptionMacro(<< "m_internalMeta1 is not present"); } if(!m_internalMeta2) { - itkExceptionMacro(<< "m_internalMeta2 is not present"); - } + itkExceptionMacro(<< "m_internalMeta2 is not present"); + } if (!m_Interpolator1) { itkExceptionMacro(<< "Interpolator1 is not present"); @@ -328,6 +335,7 @@ itk::Optimizer::ScalesType gTwoImageToOneImageMetric: weightings[2] = 1. / dtr; break; case SIX_DOF: + //G: ITHINKTHOSEARE FLIPPED!! weightings[0] = 1.; weightings[1] = 1.; weightings[2] = 1.; @@ -348,7 +356,7 @@ typename gTwoImageToOneImageMetric:: ParametersType gTwoImageToOneImageMetric::GetParameters() const { -// ParametersType parametersTransform = m_Transform1->GetParameters(); //angleX, angleY, angleZ, transX, transY, transZ + // ParametersType parametersTransform = m_Transform1->GetParameters(); //angleX, angleY, angleZ, transX, transY, transZ ParametersType parametersTransform = m_IsocTransf->GetParameters(); //angleX, angleY, angleZ, transX, transY, transZ ParametersType parameters(this->GetNumberOfParameters()); switch (m_TransformMetaInfo->GetDegreeOfFreedom()) { diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp index 494217f..6e98f98 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp @@ -61,6 +61,7 @@ const char *gGetStringValueFromTag(const gdcm::Tag& t, const gdcm::DataSet& ds) itkImageProcessor::itkImageProcessor() { + iNWUnits = 1; // std::cout<<"itkImageProcessor::itkImageProcessor contructor"<SetProjectionCenterOffset1(Point3D); m_DRTGeometryMetaInfo->SetProjectionCenterOffset2(Point3D); - - // // TEST MAPPING - // { - - // ImageType3D::PointType m_COR; - // ImageType3D::PointType m_TransformOrigin; // Origin of the user defined trasnform. likely isocenter. - // ImageType3D::PointType m_Translations; - // ImageType3D::PointType m_Rotations; - - // TransformType::Pointer m_OutputTransform ; - - // m_COR[0] = 4.70067; - // m_COR[1] = -775.183; - // m_COR[2] = 202.321 ; - - // m_TransformOrigin.Fill(0.); - - // m_Translations[0] = 85.33068531; - // m_Translations[1] = 61.87811729; - // m_Translations[2] = -1.13774466 ; - - // m_Rotations[0] = -0.09535216; - // m_Rotations[1] = 0.15113885; - // m_Rotations[2] = -5.19765723; - - // m_OutputTransform= - // this->CalculateIsocentricTransform( - // m_COR, - // m_TransformOrigin, - // m_Translations, - // m_Rotations - // ); - - // m_OutputTransform->Print(std::cout); - - // }; - // setup the Automatic Registration metric = MetricType::New(); mimetric = MIMetricType::New(); @@ -239,6 +203,13 @@ itkImageProcessor::~itkImageProcessor() } +void itkImageProcessor::SetNumberOfWorkingUnits(int iN){ + if(iN>0){ + iNWUnits = iN; + } +} + + void itkImageProcessor::PrintSelf(std::ostream& os, Indent indent) const { Superclass::PrintSelf(os, indent); @@ -482,7 +453,7 @@ int itkImageProcessor::load3DSerieFromFiles( std::vector v_fnames){ imageSeriesReader3D->SetImageIO(dicomIO); imageSeriesReader3D->SetFileNames(v_sortedFnames); - imageSeriesReader3D->SetNumberOfWorkUnits(8); + imageSeriesReader3D->SetNumberOfWorkUnits(iNWUnits); imageSeriesReader3D->ForceOrthogonalDirectionOff(); // properly read CTs with gantry tilt //imageSeriesReader3D->SetSpacingWarningRelThreshold(); @@ -621,7 +592,7 @@ int itkImageProcessor::load3DSerieFromFolder(const char * pcDirName) imageSeriesReader3D->SetImageIO(dicomIO); imageSeriesReader3D->SetFileNames(fileNames); - imageSeriesReader3D->SetNumberOfWorkUnits(12); + imageSeriesReader3D->SetNumberOfWorkUnits(iNWUnits); imageSeriesReader3D->ForceOrthogonalDirectionOff(); // properly read CTs with gantry tilt imageSeriesReader3D->Update(); @@ -1287,33 +1258,6 @@ double itkImageProcessor::GetLocalizerDisplayWindowWidth(int iImg) -// This External User Transform thing need to be checked out -//void itkImageProcessor::CalculateExternalUserTransform(TransformType::Pointer transform, DRTImageMetaInformation::Pointer imageMetaInfo) -//{ -// //crude hack to get from internal transform in LPS to external transform in IEC. -// //result is stored in m_TransformMetaInfo - -// //TODO: support for projectionTransformCenter and userTransformCenter which are not the same -// //currentlz we support only pFakeIsoLPS situations. - -// InternalImageType::DirectionType LPStoIEC_Directions; -// LPStoIEC_Directions = m_CTMetaInfo->GetLPS2IECDirections(); - -// auto parameters = transform->GetParameters(); - -// ImageType3D::PointType translationUser; -// translationUser[0] = parameters[3]; -// translationUser[1] = parameters[4]; -// translationUser[2] = parameters[5]; -// ImageType3D::PointType rotationUser; -// rotationUser[0] = parameters[0]; -// rotationUser[1] = parameters[1]; -// rotationUser[2] = parameters[2]; - -// m_TransformMetaInfo->SetUserTranslations(LPStoIEC_Directions * translationUser); -// m_TransformMetaInfo->SetUserRotations(LPStoIEC_Directions * rotationUser); -//} - void itkImageProcessor::InitializeRegistration( double stepLength, @@ -1338,6 +1282,7 @@ void itkImageProcessor::InitializeRegistration( metric->SetSubtractMean(true); metric->SetMaxTranslation(maxTranslation); + // m_TransformMetaInfo->SetDegreeOfFreedom(dof); m_r23MetaInfo->SetDegreeOfFreedom(dof); @@ -1364,6 +1309,8 @@ void itkImageProcessor::InitializeRegistration( registration->SetFixedImageRegion1(roiAutoReg1); registration->SetFixedImageRegion2(roiAutoReg2); + mimetric->SetFixedImageRegion1(roiAutoReg1); + mimetric->SetFixedImageRegion2(roiAutoReg2); std::cout << "using ROIs for Auto Reg " << std::endl; @@ -1379,6 +1326,8 @@ void itkImageProcessor::InitializeRegistration( registration->SetFixedImageRegion1(region1); registration->SetFixedImageRegion2(region2); + mimetric->SetFixedImageRegion1(roiAutoReg1); + mimetric->SetFixedImageRegion2(roiAutoReg2); } @@ -1620,6 +1569,11 @@ int itkImageProcessor::StartRegistration(std::string extraInfo) Optimizer::ParametersType itkImageProcessor::GetFinalR23Parameters(){ + + if (!m_TransformMetaInfo) { + itkExceptionMacro(<< "m_TransformMetaInfo not present"); + } + Optimizer::ParametersType pPars(6); pPars.fill(0.); @@ -1767,7 +1721,7 @@ void itkImageProcessor::InitializeProjector() resampleFilter1->SetInput( image3DIn); resampleFilter1->SetDefaultPixelValue(0); - resampleFilter1->SetNumberOfWorkUnits(8); + resampleFilter1->SetNumberOfWorkUnits(iNWUnits); // The parameters of interpolator1, such as ProjectionAngle and FocalPointToIsocenterDistance // have been set before registration. Here we only need to replace the initial @@ -1786,7 +1740,7 @@ void itkImageProcessor::InitializeProjector() resampleFilter2->SetInput( image3DIn); resampleFilter2->SetDefaultPixelValue(0); - resampleFilter2->SetNumberOfWorkUnits(8); + resampleFilter2->SetNumberOfWorkUnits(iNWUnits); // The parameters of interpolator2, such as ProjectionAngle and FocalPointToIsocenterDistance @@ -2268,6 +2222,9 @@ void itkImageProcessor::GetProjectionImages(){ std::cout<< "CurrTransform Translations: "<< CurrTransform->GetTranslation()<GetCenter()<Print(std::cout); // The parameters of interpolator1, such as ProjectionAngle and FocalPointToIsocenterDistance @@ -2838,26 +2795,87 @@ void itkImageProcessor::SetInitialRotations(double dX, double dY, double dZ) } -// THIS IS READ FOR EXPORT. TO FIX. -double* itkImageProcessor::GetTransformParameters(){ +Optimizer::ParametersType +itkImageProcessor::GetUserIsocentricTransform(){ - ImageType3D::PointType Translations; - ImageType3D::PointType Rotations; + Optimizer::ParametersType + m_Pars(6); + m_Pars.fill(0.); - Translations = m_TransformMetaInfo->GetUserTranslations(); - Rotations = m_TransformMetaInfo->GetUserRotations(); + if(!m_TransformMetaInfo){ + return m_Pars; + } - dTransfParam[0] = Translations[0]; - dTransfParam[1] = Translations[1]; - dTransfParam[2] = Translations[2]; + m_Pars[0] = m_TransformMetaInfo->GetUserRotations()[0]; + m_Pars[1] = m_TransformMetaInfo->GetUserRotations()[1]; + m_Pars[2] = m_TransformMetaInfo->GetUserRotations()[2]; - dTransfParam[3] = Rotations[0]; - dTransfParam[4] = Rotations[1]; - dTransfParam[5] = Rotations[2]; + m_Pars[3] = m_TransformMetaInfo->GetUserTranslations()[0]; + m_Pars[4] = m_TransformMetaInfo->GetUserTranslations()[1]; + m_Pars[5] = m_TransformMetaInfo->GetUserTranslations()[2]; + + return + m_Pars; - return dTransfParam; } + + +TransformType::Pointer +itkImageProcessor::GetCompleteIsocentricTransform +(ImageType3D::PointType TransformCenter){ + + TransformType::Pointer + regTransform = TransformType::New(); + regTransform->SetComputeZYX(true); + regTransform->SetIdentity(); + + if(m_TransformMetaInfo == nullptr || + m_CTMetaInfo == nullptr){ + return regTransform; + } + + std::cout<<" --- GetCompleteIsocentricTransform --- "<GetR()[0] <<" "<< + m_TransformMetaInfo->GetR()[1] <<" "<< + m_TransformMetaInfo->GetR()[2] <<" "<GetT()[0] <<" "<< + m_TransformMetaInfo->GetT()[1] <<" "<< + m_TransformMetaInfo->GetT()[2] <<" "<GetImportOffset()[0]<<" "<< + m_CTMetaInfo->GetImportOffset()[1]<<" "<< + m_CTMetaInfo->GetImportOffset()[2]<<" "<GetUserTranslations(); +// Rotations = m_TransformMetaInfo->GetUserRotations(); + +// dTransfParam[0] = Translations[0]; +// dTransfParam[1] = Translations[1]; +// dTransfParam[2] = Translations[2]; + +// dTransfParam[3] = Rotations[0]; +// dTransfParam[4] = Rotations[1]; +// dTransfParam[5] = Rotations[2]; + +// return dTransfParam; +//} + //// THESE ARE CALLED AT THE END OF REG //void itkImageProcessor::GetFinalTranslations(double& dX, double& dY, double& dZ) //{ @@ -2963,6 +2981,7 @@ void itkImageProcessor::SetRegionFixed1( std::cout << "itkImageProcessor " << std::endl; std::cout << roiAutoReg1 << std::endl; + } void itkImageProcessor::SetRegionFixed2( diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.h b/reg23Topograms/itkDTRrecon/itkImageProcessor.h index 285e756..825ba79 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.h +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.h @@ -78,6 +78,7 @@ public: CommandIterationUpdate::Pointer optimizerObserver; + void SetNumberOfWorkingUnits(int iN); /** Input data load methods*/ int load3DSerieFromFolder(const char* ); @@ -156,8 +157,21 @@ public: /** Start the registration process*/ int StartRegistration(std::string extraInfo); - /** Get transform parameters for 3D Volume */ - double* GetTransformParameters(); + ///** Get transform parameters for 3D Volume */ + //double* GetTransformParameters(); + /** Get the complete transform, likely for export to SRO. + * This includes user and hidden contributions. + * Transform center has to be specified, Zero would result + * in Isocentric transform with center at the RT Iso. + */ + TransformType::Pointer + GetCompleteIsocentricTransform(ImageType3D::PointType TransformCenter); + + /** Get only the User component of the transform + * as parameters' list */ + Optimizer::ParametersType + GetUserIsocentricTransform(); + /** Initialize projection geometry */ void InitializeProjector(); @@ -238,7 +252,7 @@ private: /** The following lines define each of the components used in the registration: The transform, optimizer, metric, interpolator and the registration method itself. */ - using TransformType = itk::Euler3DTransform; + //using TransformType = itk::Euler3DTransform; using InterpolatorType = itk::gSiddonJacobsRayCastInterpolateImageFunction; using ResampleFilterType = itk::ResampleImageFilter; @@ -343,13 +357,6 @@ private: ); -// TransformType::Pointer -// MapTransformToNewOrigin( -// ImageType3D::PointType m_COR, -// ImageType3D::PointType m_Translations, -// ImageType3D::PointType m_Rotations -// ); - double CalcProjectionAngleLPS( tPatOrientation pOrient, @@ -383,8 +390,8 @@ private: * m_Projection1VTKTransform, * m_Projection2VTKTransform; - /*Transformation Parameters */ - double dTransfParam[6]; + ///*Transformation Parameters */ + // double dTransfParam[6]; /** * Many meta containers @@ -430,6 +437,9 @@ private: bool m_UseMutualInformation; bool m_UseDumptoFile; + int + iNWUnits; + }; diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessorHelpers.cpp b/reg23Topograms/itkDTRrecon/itkImageProcessorHelpers.cpp index 730ceb6..eb9ac1a 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessorHelpers.cpp +++ b/reg23Topograms/itkDTRrecon/itkImageProcessorHelpers.cpp @@ -2,74 +2,6 @@ namespace itk { -//template -//gEuler3DTransform ::gEuler3DTransform() -//{ -// //m_CalibPrjCenter = nullptr; // has to be provided by the user. -// //m_RTIso = nullptr; // has to be provided by the user. -// // m_IECtoLPSDirs =; // has to be provided by the user. -//} - - -//template -//gEuler3DTransform::gEuler3DTransform -//(const MatrixType & matrix, const OutputPointType & offset) -//{ - - -//} - -//template -//gEuler3DTransform::gEuler3DTransform -//(unsigned int parametersDimension) -// : Superclass(parametersDimension) - -//{ - -//} - -//template -//void gEuler3DTransform ::SetParameters(const ParametersType & parameters) -//{ - -//// if(m_CalibPrjCenter != nullptr && -//// m_RTIso != nullptr //&& -//// //m_IECtoLPSDirs != nullptr -//// ){ - -//// itk::Point pT; -//// pT[0] = parameters[3]; -//// pT[1] = parameters[4]; -//// pT[2] = parameters[5]; - -//// itk::Point pR; -//// pR[0] = parameters[0]; -//// pR[1] = parameters[1]; -//// pR[2] = parameters[2]; - -//// TransformType::Pointer m_OutputTransform = -//// CalculateInternalTransformV3( -//// pT, -//// pR, -//// m_CalibPrjCenter, -//// m_RTIso, -//// m_IECtoLPSDirs); -//// Superclass::SetParameters(m_OutputTransform->GetParameters()); -//// }else{ -// Superclass::SetParameters(parameters); -//// } - - -//} - -//template -//void gEuler3DTransform ::PrintSelf(std::ostream& os, Indent indent) const -//{ -// Superclass::PrintSelf(os, indent); -// //os << indent << "ComputeGradient: " << static_cast::PrintType>(m_ComputeGradient) -// // << std::endl; -//} - TransformType::Pointer MapTransformToNewOrigin( diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessorHelpers.h b/reg23Topograms/itkDTRrecon/itkImageProcessorHelpers.h index aa8a355..04f504e 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessorHelpers.h +++ b/reg23Topograms/itkDTRrecon/itkImageProcessorHelpers.h @@ -14,69 +14,6 @@ namespace itk { - - - -//template -//class ITK_TEMPLATE_EXPORT gEuler3DTransform : -// public Euler3DTransform -//{ - -//public: -// ITK_DISALLOW_COPY_AND_ASSIGN(gEuler3DTransform); -// /** Standard class type aliases. */ -// using Self = gEuler3DTransform; -// using Superclass = Euler3DTransform; -// using Pointer = SmartPointer; -// using ConstPointer = SmartPointer; - -// /** New macro for creation of through a Smart Pointer. */ -// itkNewMacro(Self); - -// /** Run-time type information (and related methods). */ -// itkTypeMacro(gEuler3DTransform, Euler3DTransform); - -// // static constexpr unsigned int ParametersDimension = 6; - -// using MatrixType = typename Superclass::MatrixType; -// using OutputPointType = typename Superclass::OutputPointType; -// using ParametersType = typename Superclass::ParametersType; -// using PointType = typename itk::Point; - -// /** Set/Get the transformation from a container of parameters -// * This is typically used by optimizers. There are 6 parameters. The first -// * three represent the angles to rotate around the coordinate axis, and the -// * last three represents the offset. */ -// void -// SetParameters(const ParametersType & parameters) override; - -// itkSetMacro (CalibPrjCenter, PointType); -// itkSetMacro (RTIso, PointType); -// itkSetMacro(IECtoLPSDirs,MatrixType); - - -//protected: -// gEuler3DTransform(const MatrixType & matrix, const OutputPointType & offset); -// gEuler3DTransform(unsigned int parametersDimension); -// gEuler3DTransform(); - -// ~gEuler3DTransform() override = default; - -// PointType -// m_CalibPrjCenter, -// m_RTIso; - -// MatrixType -// m_IECtoLPSDirs; - - -// void -// PrintSelf(std::ostream & os, Indent indent) const override; - -//}; - - - using TransformType = itk::Euler3DTransform; constexpr static unsigned int Dimension = 3; using PixelType3D = short; From 646ba2e0af41e9c4fb363511ad0e35ed082f6dd3 Mon Sep 17 00:00:00 2001 From: Proton local user Date: Mon, 15 May 2023 18:09:04 +0200 Subject: [PATCH 43/49] Calculate Transfrom for SRO isocetric mapped to pCT Zero. --- ...ualInformationTwoImageToOneImageMetric.hxx | 30 +++++------ .../autoreg/itkgTwoImageToOneImageMetric.hxx | 24 ++++----- .../itkDTRrecon/itkImageProcessor.cpp | 52 +++++++++++++++---- .../itkDTRrecon/itkImageProcessor.h | 8 +-- 4 files changed, 70 insertions(+), 44 deletions(-) diff --git a/reg23Topograms/itkDTRrecon/autoreg/itkMutualInformationTwoImageToOneImageMetric.hxx b/reg23Topograms/itkDTRrecon/autoreg/itkMutualInformationTwoImageToOneImageMetric.hxx index 561225f..2e18525 100644 --- a/reg23Topograms/itkDTRrecon/autoreg/itkMutualInformationTwoImageToOneImageMetric.hxx +++ b/reg23Topograms/itkDTRrecon/autoreg/itkMutualInformationTwoImageToOneImageMetric.hxx @@ -102,12 +102,12 @@ MutualInformationTwoImageToOneImageMetric::GetValue() } - std::cout<< "----- itkMutualInformationTwoImage GetValue -----" <m_Transform1.GetPointer()->GetCenter() <m_Transform1.GetPointer()->GetParameters() <m_Transform1.GetPointer()->GetCenter() <m_Transform1.GetPointer()->GetParameters() <m_Interpolator1->SetTransform(this->m_Transform1); this->m_Interpolator1->Initialize(); @@ -139,7 +139,7 @@ MutualInformationTwoImageToOneImageMetric::GetValue() //metric1->SetFixedImageRegion(fixedImageRegion1); /* We get the fixed image region from the parent class... */ metric1->SetFixedImageRegion(Superclass::GetFixedImageRegion1()); - std::cout<< "-----> Mutual :: fixedImageRegion1: "<< metric1->GetFixedImageRegion() << std::endl; + //std::cout<< "-----> Mutual :: fixedImageRegion1: "<< metric1->GetFixedImageRegion() << std::endl; auto movingImageRegion = this->m_Filter1->GetOutput()->GetBufferedRegion(); unsigned int numberOfPixels = movingImageRegion.GetNumberOfPixels(); @@ -169,7 +169,7 @@ MutualInformationTwoImageToOneImageMetric::GetValue() // auto fixedImageRegion2 = fixedImage2->GetBufferedRegion(); // metric2->SetFixedImageRegion(fixedImageRegion2); metric2->SetFixedImageRegion(Superclass::GetFixedImageRegion2()); - std::cout<< "-----> Mutual :: fixedImageRegion2: "<< metric2->GetFixedImageRegion() << std::endl; + //std::cout<< "-----> Mutual :: fixedImageRegion2: "<< metric2->GetFixedImageRegion() << std::endl; movingImageRegion = this->m_Filter2->GetOutput()->GetBufferedRegion(); numberOfPixels = movingImageRegion.GetNumberOfPixels(); @@ -191,13 +191,13 @@ MutualInformationTwoImageToOneImageMetric::GetValue() auto measure = (measure1 + measure2) / 2.0; - auto oldprecision = std::cout.precision(); - std::cout.precision(std::numeric_limits::digits10 + 2); - std::cout << "Measure1: " << measure1 << " Counts: " << this->m_NumberOfPixelsCounted << std::endl; - std::cout << "Measure2: " << measure2 << " Counts: " << this->m_NumberOfPixelsCounted << std::endl; - std::cout << "Measure: " << measure << std::endl; - std::cout << "=======================================================" << std::endl; - std::cout.precision(oldprecision); +// auto oldprecision = std::cout.precision(); +// std::cout.precision(std::numeric_limits::digits10 + 2); +// std::cout << "Measure1: " << measure1 << " Counts: " << this->m_NumberOfPixelsCounted << std::endl; +// std::cout << "Measure2: " << measure2 << " Counts: " << this->m_NumberOfPixelsCounted << std::endl; +// std::cout << "Measure: " << measure << std::endl; +// std::cout << "=======================================================" << std::endl; +// std::cout.precision(oldprecision); return measure; } diff --git a/reg23Topograms/itkDTRrecon/autoreg/itkgTwoImageToOneImageMetric.hxx b/reg23Topograms/itkDTRrecon/autoreg/itkgTwoImageToOneImageMetric.hxx index d8b0cea..770ba54 100644 --- a/reg23Topograms/itkDTRrecon/autoreg/itkgTwoImageToOneImageMetric.hxx +++ b/reg23Topograms/itkDTRrecon/autoreg/itkgTwoImageToOneImageMetric.hxx @@ -111,14 +111,14 @@ bool gTwoImageToOneImageMetric::SetTransformParameter break; } - std::cout << "New Transform Parameters ISOC IEC = " << std::endl; - std::cout << " Translation X = " << TranslationAlongX << " mm" << std::endl; - std::cout << " Translation Y = " << TranslationAlongY << " mm" << std::endl; - std::cout << " Translation Z = " << TranslationAlongZ << " mm" << std::endl; - std::cout << " Rotation Along X = " << RotationAlongX /*/ dtr*/ << " deg" << std::endl; - std::cout << " Rotation Along Y = " << RotationAlongY /*/ dtr*/ << " deg" << std::endl; - std::cout << " Rotation Along Z = " << RotationAlongZ /*/ dtr*/ << " deg" << std::endl; - std::cout << "+++++++++++++++++++++++++++++++++++++++++++++++++++++++" << std::endl; +// std::cout << "New Transform Parameters ISOC IEC = " << std::endl; +// std::cout << " Translation X = " << TranslationAlongX << " mm" << std::endl; +// std::cout << " Translation Y = " << TranslationAlongY << " mm" << std::endl; +// std::cout << " Translation Z = " << TranslationAlongZ << " mm" << std::endl; +// std::cout << " Rotation Along X = " << RotationAlongX /*/ dtr*/ << " deg" << std::endl; +// std::cout << " Rotation Along Y = " << RotationAlongY /*/ dtr*/ << " deg" << std::endl; +// std::cout << " Rotation Along Z = " << RotationAlongZ /*/ dtr*/ << " deg" << std::endl; +// std::cout << "+++++++++++++++++++++++++++++++++++++++++++++++++++++++" << std::endl; // individual R and T components of the IsoC transform @@ -162,10 +162,10 @@ bool gTwoImageToOneImageMetric::SetTransformParameter m_Transform1->SetCenter( m_internalMeta1->GetpCalProjCenter()); - std::cout<<"----- itkgTwoImageToOne SetTransformParameters -----"<GetCenter()<GetParameters()<GetCenter()<GetParameters()<SetCenter( m_DRTImage1MetaInfo->GetProjectionOriginLPSZero()); - std::cout<< "CurrTransform Rotations: "<< - CurrTransform->GetAngleX() <<" "<< - CurrTransform->GetAngleY() <<" "<< - CurrTransform->GetAngleZ() <<" "<< std::endl; +// std::cout<< "CurrTransform Rotations: "<< +// CurrTransform->GetAngleX() <<" "<< +// CurrTransform->GetAngleY() <<" "<< +// CurrTransform->GetAngleZ() <<" "<< std::endl; - std::cout<< "CurrTransform Translations: "<< - CurrTransform->GetTranslation()<GetCenter()<GetTranslation()<GetCenter()<Print(std::cout); @@ -2823,7 +2823,7 @@ itkImageProcessor::GetUserIsocentricTransform(){ TransformType::Pointer itkImageProcessor::GetCompleteIsocentricTransform -(ImageType3D::PointType TransformCenter){ +(/*ImageType3D::PointType TransformCenter*/){ TransformType::Pointer regTransform = TransformType::New(); @@ -2851,6 +2851,38 @@ itkImageProcessor::GetCompleteIsocentricTransform m_CTMetaInfo->GetImportOffset()[2]<<" "<GetLPS2IECDirections() * m_RTMetaInfo->GetIsocenterLPS(); + + mISORTIEC[0] *= -1; + mISORTIEC[1] *= -1; + mISORTIEC[2] *= -1; + + TransformType::Pointer mTransf= + MapTransformToNewOrigin( + mISORTIEC, + m_TransformMetaInfo->GetT(), + m_TransformMetaInfo->GetR() + ); + + itk::TransformMetaInformation::PointType + pTM = m_CTMetaInfo->GetLPS2IECDirections() * m_CTMetaInfo->GetImportOffset(); + + TransformType::OutputVectorType pTransl; + + pTransl[0] = mTransf->GetTranslation()[0] - pTM[0]; + pTransl[1] = mTransf->GetTranslation()[1] - pTM[1]; + pTransl[2] = mTransf->GetTranslation()[2] - pTM[2]; + + mTransf->SetTranslation(pTransl); + itk::PointpZero; + pZero.Fill(0.); + mTransf->SetCenter(pZero); + + std::cout<<"mTransf R"<< mTransf->GetMatrix().GetVnlMatrix() << std::endl; + std::cout<<"mTransf T"<< mTransf->GetTranslation() << std::endl; + + return mTransf; } diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.h b/reg23Topograms/itkDTRrecon/itkImageProcessor.h index 825ba79..88ba2fc 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.h +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.h @@ -165,7 +165,7 @@ public: * in Isocentric transform with center at the RT Iso. */ TransformType::Pointer - GetCompleteIsocentricTransform(ImageType3D::PointType TransformCenter); + GetCompleteIsocentricTransform(/*ImageType3D::PointType TransformCenter*/); /** Get only the User component of the transform * as parameters' list */ @@ -286,12 +286,6 @@ private: /** ITK to VTK filter */ using ITKtoVTKFilterType = itk::ImageToVTKImageFilter; -// void -// CalculateExternalUserTransform( -// TransformType::Pointer transform, -// DRTImageMetaInformation::Pointer imageMetaInfo); - - TransformType::Pointer transform1, transform2, From e97a24642720ebc9d00791c03458d683de925e03 Mon Sep 17 00:00:00 2001 From: Proton local user Date: Tue, 16 May 2023 13:57:58 +0200 Subject: [PATCH 44/49] Crash on close patient and removal of uncessary load from dir - flipped unload sequence, Scouts, RTP, RTS, CT - removed unused load functions --- .../itkDTRrecon/itkImageProcessor.cpp | 139 ------------------ .../itkDTRrecon/itkImageProcessor.h | 25 ++-- 2 files changed, 12 insertions(+), 152 deletions(-) diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp index d39df10..f74f9db 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp @@ -524,141 +524,6 @@ int itkImageProcessor::load3DSerieFromFiles( std::vector v_fnames){ } -int itkImageProcessor::load3DSerieFromFolder(const char * pcDirName) -{ - - using NamesGeneratorType = itk::GDCMSeriesFileNames; - NamesGeneratorType::Pointer nameGenerator = NamesGeneratorType::New(); - - nameGenerator->SetUseSeriesDetails(true); - nameGenerator->AddSeriesRestriction("0008|0021"); - nameGenerator->SetGlobalWarningDisplay(false); - nameGenerator->SetDirectory(pcDirName); - - - tPatOrientation m_PatOrientation - = tPatOrientation::NotDefined; - - try - { - using SeriesIdContainer = std::vector; - const SeriesIdContainer & seriesUID = nameGenerator->GetSeriesUIDs(); - auto seriesItr = seriesUID.begin(); - auto seriesEnd = seriesUID.end(); - - if (seriesItr != seriesEnd) - { - std::cout << "The directory: "; - std::cout << pcDirName << std::endl; - std::cout << "Contains the following DICOM Series: "; - std::cout << std::endl; - } - else - { - std::cout << "No DICOMs in: " << pcDirName << std::endl; - return EXIT_FAILURE; - } - - while (seriesItr != seriesEnd) - { - std::cout << seriesItr->c_str() << std::endl; - ++seriesItr; - } - - /* we expect only one serie at this point... */ - if(seriesUID.size() != 1){ - std::cout<<"More than one serie in the selected folder. returning..."<c_str(); - seriesItr++; - - std::cout << "\nReading: "; - std::cout << seriesIdentifier << std::endl; - using FileNamesContainer = std::vector; - FileNamesContainer fileNames = nameGenerator->GetFileNames(seriesIdentifier); - - using ImageIOType = itk::GDCMImageIO; - ImageIOType::Pointer dicomIO = ImageIOType::New(); - ImageSeriesReaderType3D::Pointer - imageSeriesReader3D = ImageSeriesReaderType3D::New(); - - imageSeriesReader3D->SetImageIO(dicomIO); - imageSeriesReader3D->SetFileNames(fileNames); - imageSeriesReader3D->SetNumberOfWorkUnits(iNWUnits); - imageSeriesReader3D->ForceOrthogonalDirectionOff(); // properly read CTs with gantry tilt - - imageSeriesReader3D->Update(); - - if(fileNames.size()>0){ - - gdcm::Reader R; - R.SetFileName(fileNames.at(0).c_str()); - if(!R.Read()) - { - cerr<<"ERROR: cannot read file: "<SetInput(imageSeriesReader3D->GetOutput()); - caster3D->Update(); - - if (m_VolumeSourceDupli) { - m_VolumeSourceDupli = NULL; - m_VolumeSourceDupli = DuplicatorType::New(); - } - - m_VolumeSourceDupli->SetInputImage(caster3D->GetOutput()); - m_VolumeSourceDupli->Update(); - - caster3D = NULL; - - } - - } - catch (itk::ExceptionObject & ex) - { - std::cout << ex << std::endl; - return EXIT_FAILURE; - } - - InternalImageType::Pointer m_InputImage = - m_VolumeSourceDupli->GetOutput(); - return - this->fill3DVolumeMeta(m_InputImage, m_PatOrientation); - -} - /** Fill Meta after 3D volume load */ int itkImageProcessor::fill3DVolumeMeta( InternalImageType::Pointer m_InputImage, @@ -2951,10 +2816,6 @@ double itkImageProcessor::GetCurrentMetricValue() } } -void itkImageProcessor::SetROI(double, double, double, double) -{ - //TODO: Not implemanted yet. ROI are hard coded and can be enabled using SetFullROI. -} void itkImageProcessor::SetOptimizer(std::string optimizer) { diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.h b/reg23Topograms/itkDTRrecon/itkImageProcessor.h index 88ba2fc..c451a42 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.h +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.h @@ -78,10 +78,10 @@ public: CommandIterationUpdate::Pointer optimizerObserver; + /** Set number of logic CPU to be made available to interpolators*/ void SetNumberOfWorkingUnits(int iN); /** Input data load methods*/ - int load3DSerieFromFolder(const char* ); int load3DSerieFromFiles( std::vector ); int unload3DVolumeAndMeta(); @@ -144,21 +144,12 @@ public: Optimizer::ParametersType GetFinalR23Parameters(); - /** Get transform parameters for 3D Volume */ -// void GetFinalTranslations(double&, double&, double&); -// void GetFinalRotations(double&, double&, double&); - -// /** Set user transform parameters for 3D Volume in LPS*/ -// void SetUserTranslationsLPS(double, double, double); -// void SetUserRotationsLPS(double, double, double); - /** Initialize the registration pipeline*/ void InitializeRegistration(double, double, eDegreeOfFreedomType); /** Start the registration process*/ int StartRegistration(std::string extraInfo); ///** Get transform parameters for 3D Volume */ - //double* GetTransformParameters(); /** Get the complete transform, likely for export to SRO. * This includes user and hidden contributions. * Transform center has to be specified, Zero would result @@ -168,7 +159,10 @@ public: GetCompleteIsocentricTransform(/*ImageType3D::PointType TransformCenter*/); /** Get only the User component of the transform - * as parameters' list */ + * as parameters' list. Import offset and hidden not included. + * This can be use to update UI transform display + * ParametersType :: Rx Ry Rz Tx Ty Tz + */ Optimizer::ParametersType GetUserIsocentricTransform(); @@ -204,18 +198,23 @@ public: void WriteProjectionImages(); void Write2DImages(); + /** Auto Reg23 methods */ + /** Get the current cost function value from the optimizer*/ double GetOptimizerValue(); /** Get the cost function value for the current transform*/ double GetCurrentMetricValue(); - void SetROI(double, double, double, double); - + /** Set Optimizer type */ void SetOptimizer(std::string); + /** Set Metric type */ void SetMetric(std::string); + /** Use full image as ROI */ void SetFullROI(bool); + /** Maximum number of iterations for the optimizer */ void SetMaxNumberOfIterations(int); + /** Define the region to be used as ROI on fixed images */ void SetRegionFixed1(int,int,int,int); void SetRegionFixed2(int,int,int,int); From 21751524bb20b1143493ed35191bed715fdb1991 Mon Sep 17 00:00:00 2001 From: Proton local user Date: Tue, 16 May 2023 17:03:26 +0200 Subject: [PATCH 45/49] Calculation of offset in PAT and rework of signals to approval. - offset calc is verified against outside script. To be careful now in case we want to exclude the rotations from import offset. For PAT calc we need the complete matrix, therefore we may need to filter the rotations somewhere else. - initial work on signal of current transform. was based on readout of spin box. i would use internal storage and check it against spin. - i leave it broken so that we know where to continue --- .../itkDTRrecon/itkImageProcessor.cpp | 104 +++++++----------- .../itkDTRrecon/itkImageProcessor.h | 14 ++- 2 files changed, 53 insertions(+), 65 deletions(-) diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp index f74f9db..f69b637 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp @@ -204,12 +204,36 @@ itkImageProcessor::~itkImageProcessor() } void itkImageProcessor::SetNumberOfWorkingUnits(int iN){ - if(iN>0){ + if(iN>0 && iN<50){ iNWUnits = iN; } } +const CTVolumeImageMetaInformation::Pointer +itkImageProcessor::GetCTMetaInfo( + ){ + + return m_CTMetaInfo; + +} + +const RTGeometryMetaInformation::Pointer +itkImageProcessor::GetRTMetaInfo( + ){ + + return m_RTMetaInfo; + +} + +const DRTProjectionGeometryImageMetaInformation::Pointer +itkImageProcessor::GetDRTGeoMetaInfo(){ + + return m_DRTGeometryMetaInfo; + +} + + void itkImageProcessor::PrintSelf(std::ostream& os, Indent indent) const { Superclass::PrintSelf(os, indent); @@ -262,7 +286,6 @@ double itkImageProcessor::GetPanelOffset2(){ void itkImageProcessor::SetDegreeOfFreedom(tDegreeOfFreedomEnum dof) { - // m_TransformMetaInfo->SetDegreeOfFreedom(dof); m_r23MetaInfo->SetDegreeOfFreedom(dof); } @@ -271,7 +294,6 @@ itkImageProcessor::GetDegreeOfFreedom() { return m_r23MetaInfo->GetDegreeOfFreedom(); - //m_TransformMetaInfo->GetDegreeOfFreedom(); } void itkImageProcessor::SetCustom_ImportTransform(double dTx, @@ -2697,24 +2719,24 @@ itkImageProcessor::GetCompleteIsocentricTransform if(m_TransformMetaInfo == nullptr || m_CTMetaInfo == nullptr){ - return regTransform; + return nullptr; } - std::cout<<" --- GetCompleteIsocentricTransform --- "<GetR()[0] <<" "<< - m_TransformMetaInfo->GetR()[1] <<" "<< - m_TransformMetaInfo->GetR()[2] <<" "<GetT()[0] <<" "<< - m_TransformMetaInfo->GetT()[1] <<" "<< - m_TransformMetaInfo->GetT()[2] <<" "<GetImportOffset()[0]<<" "<< - m_CTMetaInfo->GetImportOffset()[1]<<" "<< - m_CTMetaInfo->GetImportOffset()[2]<<" "<GetR()[0] <<" "<< +// m_TransformMetaInfo->GetR()[1] <<" "<< +// m_TransformMetaInfo->GetR()[2] <<" "<GetT()[0] <<" "<< +// m_TransformMetaInfo->GetT()[1] <<" "<< +// m_TransformMetaInfo->GetT()[2] <<" "<GetImportOffset()[0]<<" "<< +// m_CTMetaInfo->GetImportOffset()[1]<<" "<< +// m_CTMetaInfo->GetImportOffset()[2]<<" "<GetLPS2IECDirections() * m_RTMetaInfo->GetIsocenterLPS(); @@ -2744,56 +2766,10 @@ itkImageProcessor::GetCompleteIsocentricTransform pZero.Fill(0.); mTransf->SetCenter(pZero); - std::cout<<"mTransf R"<< mTransf->GetMatrix().GetVnlMatrix() << std::endl; - std::cout<<"mTransf T"<< mTransf->GetTranslation() << std::endl; - return mTransf; } -// THIS IS READ FOR EXPORT. TO FIX. -//double* itkImageProcessor::GetTransformParameters(){ - -// ImageType3D::PointType Translations; -// ImageType3D::PointType Rotations; - - - -// Translations = m_TransformMetaInfo->GetUserTranslations(); -// Rotations = m_TransformMetaInfo->GetUserRotations(); - -// dTransfParam[0] = Translations[0]; -// dTransfParam[1] = Translations[1]; -// dTransfParam[2] = Translations[2]; - -// dTransfParam[3] = Rotations[0]; -// dTransfParam[4] = Rotations[1]; -// dTransfParam[5] = Rotations[2]; - -// return dTransfParam; -//} - -//// THESE ARE CALLED AT THE END OF REG -//void itkImageProcessor::GetFinalTranslations(double& dX, double& dY, double& dZ) -//{ -// ImageType3D::PointType userTranslations = m_TransformMetaInfo->GetUserTranslations(); - -// dX = userTranslations[0]; -// dY = userTranslations[1]; -// dZ = userTranslations[2]; -//} - -//// THESE ARE CALLED AT THE END OF REG -//void itkImageProcessor::GetFinalRotations(double& dRX, double& dRY, double& dRZ) -//{ -// ImageType3D::PointType userRotations = m_TransformMetaInfo->GetUserRotations(); - -// dRX = userRotations[0]; -// dRY = userRotations[1]; -// dRZ = userRotations[2]; - -//} - double itkImageProcessor::GetOptimizerValue() { return m_OptmizerValue; diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.h b/reg23Topograms/itkDTRrecon/itkImageProcessor.h index c451a42..43f6108 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.h +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.h @@ -140,7 +140,8 @@ public: void SetInitialTranslations(double, double, double); void SetInitialRotations(double, double, double); - + /** Returns user components only of the autoReg + * */ Optimizer::ParametersType GetFinalR23Parameters(); @@ -166,6 +167,17 @@ public: Optimizer::ParametersType GetUserIsocentricTransform(); + /** Return useful meta info for external use + * Consumer should check for nullptr... + */ + const CTVolumeImageMetaInformation::Pointer + GetCTMetaInfo(); + + const RTGeometryMetaInformation::Pointer + GetRTMetaInfo(); + + const DRTProjectionGeometryImageMetaInformation::Pointer + GetDRTGeoMetaInfo(); /** Initialize projection geometry */ void InitializeProjector(); From ab29d81e5e81658a7d3677112ba796f360e8e4e1 Mon Sep 17 00:00:00 2001 From: Proton local user Date: Wed, 17 May 2023 10:49:22 +0200 Subject: [PATCH 46/49] UseOfRotations for hidden transform and station name - itkDRT has method to set whether rotations should be used for import offset and hidden transform. Results checked against external code for final PAT conversion. - helpers for query of station name and Fov moved to helpers functions file - preparation of station name check in scout processor load of 2D and 3D images --- .../itkDTRrecon/DRTMetaInformation.cpp | 2 + .../itkDTRrecon/DRTMetaInformation.h | 7 ++ .../itkDTRrecon/itkImageProcessor.cpp | 76 +++++++++---------- .../itkDTRrecon/itkImageProcessor.h | 24 +++--- .../itkDTRrecon/itkImageProcessorHelpers.cpp | 67 ++++++++++++++++ .../itkDTRrecon/itkImageProcessorHelpers.h | 9 +++ 6 files changed, 132 insertions(+), 53 deletions(-) diff --git a/reg23Topograms/itkDTRrecon/DRTMetaInformation.cpp b/reg23Topograms/itkDTRrecon/DRTMetaInformation.cpp index 4981437..ff6ae1c 100644 --- a/reg23Topograms/itkDTRrecon/DRTMetaInformation.cpp +++ b/reg23Topograms/itkDTRrecon/DRTMetaInformation.cpp @@ -474,6 +474,8 @@ DRTProjectionGeometryImageMetaInformation(){ this->m_ProjectionCenter.Fill(0.); + this->m_UseRotationsForHiddenTransform = true; + } void diff --git a/reg23Topograms/itkDTRrecon/DRTMetaInformation.h b/reg23Topograms/itkDTRrecon/DRTMetaInformation.h index 5beb57a..0e6e9cd 100644 --- a/reg23Topograms/itkDTRrecon/DRTMetaInformation.h +++ b/reg23Topograms/itkDTRrecon/DRTMetaInformation.h @@ -408,6 +408,10 @@ public: itkSetMacro(ProjectionCenter, PointType); itkGetMacro(ProjectionCenter, PointType); + itkSetMacro(UseRotationsForHiddenTransform, bool); + itkGetMacro(UseRotationsForHiddenTransform, bool); + + protected: double @@ -447,6 +451,9 @@ protected: m_ProjectionCenterOffset2; + bool + m_UseRotationsForHiddenTransform; + /** Default Constructor **/ DRTProjectionGeometryImageMetaInformation (); /** Default Destructor **/ diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp index f69b637..ecaf8ed 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp @@ -36,29 +36,6 @@ gfattori 08.11.2021 namespace itk { - -//FUNCTION DECLARATION NECESSARY FOR COPY/PASTE FROM vtkGDCMImageReader -// const char *gGetStringValueFromTag(const gdcm::Tag& t, const gdcm::DataSet& ds); - -const char *gGetStringValueFromTag(const gdcm::Tag& t, const gdcm::DataSet& ds) -{ - static std::string buffer; - buffer = ""; // cleanup previous call - if( ds.FindDataElement( t ) ) - { - const gdcm::DataElement& de = ds.GetDataElement( t ); - const gdcm::ByteValue *bv = de.GetByteValue(); - if( bv ) // Can be Type 2 - { - buffer = std::string( bv->GetPointer(), bv->GetLength() ); - // Will be padded with at least one \0 - } - } - // Since return is a const char* the very first \0 will be considered - return buffer.c_str(); -}; - - itkImageProcessor::itkImageProcessor() { iNWUnits = 1; @@ -296,6 +273,17 @@ itkImageProcessor::GetDegreeOfFreedom() m_r23MetaInfo->GetDegreeOfFreedom(); } +void itkImageProcessor::SetUseRotationsForImportOffset(bool bVal){ + + if(m_DRTGeometryMetaInfo == NULL){ + return; + } + m_DRTGeometryMetaInfo->SetUseRotationsForHiddenTransform(bVal); + + return; +} + + void itkImageProcessor::SetCustom_ImportTransform(double dTx, double dTy, double dTz, @@ -1060,25 +1048,25 @@ int itkImageProcessor::load2D(const char * pcFName){ -int itkImageProcessor::query2DimageReconstructionDiameter(const char *pcFName){ +//int itkImageProcessor::query2DimageReconstructionDiameter(const char *pcFName){ - /* Check if we can open the file */ - gdcm::Reader R; - R.SetFileName(pcFName); - if(!R.Read()) - { cerr<<"ERROR: cannot read file: "<SetIsocenterIECS(Point); + + ImageType3D::PointType + pZero (3); + pZero.Fill(0.); + m_CTMetaInfo->SetImportOffset( CalcImportVolumeOffset( m_RTMetaInfo->GetIsocenterIECS(), m_CTMetaInfo->GetLPS2IECDirections(), m_RTMetaInfo->GetIsocenterLPS(), m_DRTGeometryMetaInfo->GetIECS2IECScannerT(), - m_DRTGeometryMetaInfo->GetIECS2IECScannerR() + (m_DRTGeometryMetaInfo->GetUseRotationsForHiddenTransform() ? + m_DRTGeometryMetaInfo->GetIECS2IECScannerR() : pZero) ) ); m_TransformMetaInfo->SetHiddenRotations( - m_DRTGeometryMetaInfo->GetIECS2IECScannerR()); + (m_DRTGeometryMetaInfo->GetUseRotationsForHiddenTransform() ? + m_DRTGeometryMetaInfo->GetIECS2IECScannerR() : pZero) + ); this->UpdateProjectionGeometryMeta(); diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.h b/reg23Topograms/itkDTRrecon/itkImageProcessor.h index 43f6108..df9f45b 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.h +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.h @@ -87,7 +87,7 @@ public: int load2D(const char *); int unload2DAndMeta(int); - int query2DimageReconstructionDiameter(const char*); + //int query2DimageReconstructionDiameter(const char*); void loadRTPlanInfo(double, double, double, double, double ,double); int unloadRTPlanAndMeta(); @@ -121,7 +121,6 @@ public: tDegreeOfFreedomEnum GetDegreeOfFreedom(); void SetCustom_ProjectionCenterOffsetFixedAxes_IEC(double,double,double,double,double,double); - void SetCustom_ProjectionCenterFixedAxes_IEC(double,double,double); /** Intensity threshold used for image projection, @@ -131,8 +130,16 @@ public: /** Custom settings of the projection images */ void SetCustom_2Dres(double,double,double,double); void SetCustom_2Dsize(int,int,int,int); + + /** Custom transform to map IEC of imaging device into IEC-Support + * Tx Ty Tz [mm] Rx Ry Rz [deg] + */ void SetCustom_ImportTransform(double, double, double, double, double, double); + + /** Should rotations be used when computing import offset and hidden transform? */ + void SetUseRotationsForImportOffset(bool bVal); + void SetCustom_UpdateMetaInfo(); @@ -172,10 +179,8 @@ public: */ const CTVolumeImageMetaInformation::Pointer GetCTMetaInfo(); - const RTGeometryMetaInformation::Pointer GetRTMetaInfo(); - const DRTProjectionGeometryImageMetaInformation::Pointer GetDRTGeoMetaInfo(); @@ -230,9 +235,6 @@ public: void SetRegionFixed1(int,int,int,int); void SetRegionFixed2(int,int,int,int); - /** Optimizer which tries to find the minimn (Powell Optimizer)*/ - using OptimizerType = itk::PowellOptimizer; - protected: /** Various pixel types */ using InternalPixelType = float; @@ -263,12 +265,11 @@ private: /** The following lines define each of the components used in the registration: The transform, optimizer, metric, interpolator and the registration method itself. */ - //using TransformType = itk::Euler3DTransform; using InterpolatorType = itk::gSiddonJacobsRayCastInterpolateImageFunction; using ResampleFilterType = itk::ResampleImageFilter; - //using gTransformType = itk::gEuler3DTransform; - + /** Optimizer which tries to find the minimun (Powell Optimizer)*/ + using OptimizerType = itk::PowellOptimizer; /** Optimizer which tries to find the minimn (Powell Optimizer)*/ using AmoebaOptimizerType = itk::AmoebaOptimizer; /** Optimizer which samples the whol space */ @@ -395,9 +396,6 @@ private: * m_Projection1VTKTransform, * m_Projection2VTKTransform; - ///*Transformation Parameters */ - // double dTransfParam[6]; - /** * Many meta containers */ diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessorHelpers.cpp b/reg23Topograms/itkDTRrecon/itkImageProcessorHelpers.cpp index eb9ac1a..bb93324 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessorHelpers.cpp +++ b/reg23Topograms/itkDTRrecon/itkImageProcessorHelpers.cpp @@ -1,4 +1,6 @@ #include "itkImageProcessorHelpers.h" +#include +#include namespace itk { @@ -95,4 +97,69 @@ CalculateInternalTransformV3( } +const char* queryStationName(const char* pcFName){ + + static std::string buffer; + + /* Check if we can open the file */ + gdcm::Reader R; + R.SetFileName(pcFName); + if(!R.Read()) + {std::cerr<<"ERROR: cannot read file: "<GetPointer(), bv->GetLength() ); + // Will be padded with at least one \0 + } + } + // Since return is a const char* the very first \0 will be considered + return buffer.c_str(); +} + } diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessorHelpers.h b/reg23Topograms/itkDTRrecon/itkImageProcessorHelpers.h index 04f504e..ea16394 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessorHelpers.h +++ b/reg23Topograms/itkDTRrecon/itkImageProcessorHelpers.h @@ -10,6 +10,9 @@ #include "itkObject.h" #include "itkObjectFactory.h" +#include +#include + namespace itk { @@ -40,7 +43,13 @@ TransformType::Pointer InternalImageType::DirectionType m_IECtoLPSDirections ); +const char *gGetStringValueFromTag(const gdcm::Tag& t, const gdcm::DataSet& ds); + +int query2DimageReconstructionDiameter(const char*); + +const char* queryStationName(const char*); } + #endif From d67627a6fc567f5949c01dd2ced071a56a7e4a0e Mon Sep 17 00:00:00 2001 From: Proton local user Date: Wed, 17 May 2023 23:53:02 +0200 Subject: [PATCH 47/49] Review of multiple optimizers - metrics - not usuable util the opti and metric types are better defined using enums - ROI are passed to both metrics - Full functionalty only for Powell(NCC or MI), mainly due to GetFinalR23Parameters which get those from Powell.... --- .../itkDTRrecon/autoreg/CMakeLists.txt | 3 +- ...ualInformationTwoImageToOneImageMetric.hxx | 6 + ...zedCorrelationTwoImageToOneImageMetric.hxx | 1 - .../itkDTRrecon/itkImageProcessor.cpp | 205 +++++++++++------- .../itkDTRrecon/itkImageProcessor.h | 16 +- 5 files changed, 138 insertions(+), 93 deletions(-) diff --git a/reg23Topograms/itkDTRrecon/autoreg/CMakeLists.txt b/reg23Topograms/itkDTRrecon/autoreg/CMakeLists.txt index adee1d8..4921214 100644 --- a/reg23Topograms/itkDTRrecon/autoreg/CMakeLists.txt +++ b/reg23Topograms/itkDTRrecon/autoreg/CMakeLists.txt @@ -1,6 +1,5 @@ SET(LIB_NAME autoreg) -SET(CMAKE_CXX_FLAGS "-std=c++11 -fPIC") - +#SET(CMAKE_CXX_FLAGS "-std=c++11 -fPIC") find_package(ITK REQUIRED) include(${ITK_USE_FILE}) diff --git a/reg23Topograms/itkDTRrecon/autoreg/itkMutualInformationTwoImageToOneImageMetric.hxx b/reg23Topograms/itkDTRrecon/autoreg/itkMutualInformationTwoImageToOneImageMetric.hxx index 2e18525..b7c03a7 100644 --- a/reg23Topograms/itkDTRrecon/autoreg/itkMutualInformationTwoImageToOneImageMetric.hxx +++ b/reg23Topograms/itkDTRrecon/autoreg/itkMutualInformationTwoImageToOneImageMetric.hxx @@ -149,6 +149,12 @@ MutualInformationTwoImageToOneImageMetric::GetValue() //metric1->UseAllPixelsOn(); metric1->SetNumberOfHistogramBins(50); +// InternalImageType::IndexType pIndex; +// pIndex[0]=200; +// pIndex[1]=300; +// InternalImageType::PixelType pPixel = fixedImage1->GetPixel(pIndex); +// std::cout<<"MATTES PIXEL: "<SetFixedImage(fixedImage1); metric1->SetMovingImage(this->m_Filter1->GetOutput()); diff --git a/reg23Topograms/itkDTRrecon/autoreg/itkNormalizedCorrelationTwoImageToOneImageMetric.hxx b/reg23Topograms/itkDTRrecon/autoreg/itkNormalizedCorrelationTwoImageToOneImageMetric.hxx index 06e9c34..cd14a02 100644 --- a/reg23Topograms/itkDTRrecon/autoreg/itkNormalizedCorrelationTwoImageToOneImageMetric.hxx +++ b/reg23Topograms/itkDTRrecon/autoreg/itkNormalizedCorrelationTwoImageToOneImageMetric.hxx @@ -76,7 +76,6 @@ NormalizedCorrelationTwoImageToOneImageMetric::Calcul this->m_NumberOfPixelsCounted = 0; int numberOfPixelsVisited = 0; - //filter->Update(); filter->Update(); MovingImageConstPointer imageDRTIn = filter->GetOutput(); //this->WriteImage(imageDRTIn, "", ""); diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp index ecaf8ed..63c2628 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp @@ -142,37 +142,38 @@ itkImageProcessor::itkImageProcessor() m_DRTGeometryMetaInfo->SetProjectionCenterOffset2(Point3D); // setup the Automatic Registration - metric = MetricType::New(); - mimetric = MIMetricType::New(); - optimizer = OptimizerType::New(); + NCCmetric = MetricType::New(); + MImetric = MIMetricType::New(); + PowellOptimizer = PowellOptimizerType::New(); - amoebaoptimizer = AmoebaOptimizerType::New(); + AmoebaOptimizer = AmoebaOptimizerType::New(); optimizerObserver = CommandIterationUpdate::New(); - exhaustiveOptimizer = ExhaustiveOptimizerType::New(); - exhaustiveOptimizerObserver = ExhaustiveCommandIterationUpdate::New(); + ExhaustiveOptimizer = ExhaustiveOptimizerType::New(); + ExhaustiveOptimizerObserver = ExhaustiveCommandIterationUpdate::New(); registration = RegistrationType::New(); optimizerObserver->SetProcess(registration); - if (m_UseMutualInformation) { - registration->SetMetric(mimetric); - } else { - registration->SetMetric(metric); - } + /* default is MI */ + m_UseMutualInformation = true; //oterwise NCC is used + registration->SetMetric(MImetric); + /* default is Powell */ + m_UseExhaustiveOptmizer = false; //if the exhaustive optimizer shal be used, ovverrides ameoba + m_UseAmeobaOptimizer = false; //if the ameoba optimzer shall be used, otherwise Powell. Overriden by Exhaustive option. + registration->SetOptimizer(PowellOptimizer); - registration->SetOptimizer(optimizer); registration->SetTransform1(transform1); registration->SetTransform2(transform2); registration->SetInterpolator1(interpolator1); registration->SetInterpolator2(interpolator2); - m_UseExhaustiveOptmizer = false; //if the exhaustive optimizer shal be used, ovverrides ameoba - m_UseAmeobaOptimizer = false; //if the ameoba optimzer shall be used, otherwise Powell. Overriden by Exhaustive option. m_UseFullROI = true; // if the full image ROI shall be used - m_UseMutualInformation = false; //oterwise NCC is used m_UseDumptoFile = false; //If each (!) optimzer result shall be dumpped into a file. + + + } itkImageProcessor::~itkImageProcessor() @@ -1031,7 +1032,12 @@ int itkImageProcessor::load2D(const char * pcFName){ m_Duplicator->SetInputImage(caster2DInput->GetOutput() ); m_Duplicator->Update(); - + InternalImageType::IndexType pIndex; + pIndex[0]=200; + pIndex[1]=300; + InternalImageType::PixelType pPixel = + m_Duplicator->GetOutput()->GetPixel(pIndex); + std::cout<<"processro PIXEL: "<GetOutput()->GetDirection()<ComputeGradientOff(); - metric->SetSubtractMean(true); - metric->SetMaxTranslation(maxTranslation); + NCCmetric->ComputeGradientOff(); + MImetric->ComputeGradientOff(); + NCCmetric->SetSubtractMean(true); + + NCCmetric->SetMaxTranslation(maxTranslation); + MImetric->SetMaxTranslation(maxTranslation); - // m_TransformMetaInfo->SetDegreeOfFreedom(dof); m_r23MetaInfo->SetDegreeOfFreedom(dof); - mimetric->ComputeGradientOff(); if (verbose) { - metric->DebugOn(); + NCCmetric->DebugOn(); + MImetric->DebugOn(); } @@ -1184,8 +1192,10 @@ void itkImageProcessor::InitializeRegistration( registration->SetFixedImageRegion1(roiAutoReg1); registration->SetFixedImageRegion2(roiAutoReg2); - mimetric->SetFixedImageRegion1(roiAutoReg1); - mimetric->SetFixedImageRegion2(roiAutoReg2); + MImetric->SetFixedImageRegion1(roiAutoReg1); + MImetric->SetFixedImageRegion2(roiAutoReg2); + NCCmetric->SetFixedImageRegion1(roiAutoReg1); + NCCmetric->SetFixedImageRegion2(roiAutoReg2); std::cout << "using ROIs for Auto Reg " << std::endl; @@ -1201,8 +1211,10 @@ void itkImageProcessor::InitializeRegistration( registration->SetFixedImageRegion1(region1); registration->SetFixedImageRegion2(region2); - mimetric->SetFixedImageRegion1(roiAutoReg1); - mimetric->SetFixedImageRegion2(roiAutoReg2); + MImetric->SetFixedImageRegion1(roiAutoReg1); + MImetric->SetFixedImageRegion2(roiAutoReg2); + NCCmetric->SetFixedImageRegion1(roiAutoReg1); + NCCmetric->SetFixedImageRegion2(roiAutoReg2); } @@ -1244,35 +1256,35 @@ void itkImageProcessor::InitializeRegistration( // The metric will return 0 or a "large" negative number in case of high correspondence of the images // Thus, we need to minimze - optimizer->SetMaximize(false); // for NCC and MI - optimizer->SetMaximumIteration(m_MaxNumberOfIterations); - optimizer->SetMaximumLineIteration(4); // for Powell's method - optimizer->SetStepLength(stepLength); - optimizer->SetStepTolerance(0.01); - optimizer->SetValueTolerance(0.000002); + PowellOptimizer->SetMaximize(false); // for NCC and MI + PowellOptimizer->SetMaximumIteration(m_MaxNumberOfIterations); + PowellOptimizer->SetMaximumLineIteration(4); // for Powell's method + PowellOptimizer->SetStepLength(stepLength); + PowellOptimizer->SetStepTolerance(0.01); + PowellOptimizer->SetValueTolerance(0.000002); if (verbose) { - optimizer->DebugOn(); - optimizer->Print(std::cout); + PowellOptimizer->DebugOn(); + PowellOptimizer->Print(std::cout); } - optimizer->RemoveAllObservers(); - optimizer->AddObserver(itk::AnyEvent(), optimizerObserver); + PowellOptimizer->RemoveAllObservers(); + PowellOptimizer->AddObserver(itk::AnyEvent(), optimizerObserver); - registration->SetOptimizer(optimizer); + registration->SetOptimizer(PowellOptimizer); registration->RemoveAllObservers(); } else { - amoebaoptimizer->SetMinimize(true); - amoebaoptimizer->SetMaximumNumberOfIterations(100); - amoebaoptimizer->SetParametersConvergenceTolerance(0.1); - amoebaoptimizer->SetFunctionConvergenceTolerance(0.000002); + AmoebaOptimizer->SetMinimize(true); + AmoebaOptimizer->SetMaximumNumberOfIterations(100); + AmoebaOptimizer->SetParametersConvergenceTolerance(0.1); + AmoebaOptimizer->SetFunctionConvergenceTolerance(0.000002); - amoebaoptimizer->SetAutomaticInitialSimplex(false); + AmoebaOptimizer->SetAutomaticInitialSimplex(false); //Initial size of the simplex (otherwise it is a very small number and optimizer stops immeditaly) // 2 mm / 2 degrees seems to be a good value which performs well. - OptimizerType::ParametersType simplexDelta(3); + AmoebaOptimizerType::ParametersType simplexDelta(3); int numberOfDOF = GetNumberOfDOF(dof); if (numberOfDOF == 0) { itkExceptionMacro(<< "Unkown or unsupported degree of freedom"); @@ -1280,12 +1292,12 @@ void itkImageProcessor::InitializeRegistration( for (int i = 0; i < numberOfDOF; i++) { simplexDelta[i] = 2.0; } - amoebaoptimizer->SetInitialSimplexDelta(simplexDelta); + AmoebaOptimizer->SetInitialSimplexDelta(simplexDelta); - amoebaoptimizer->RemoveAllObservers(); - amoebaoptimizer->AddObserver(itk::IterationEvent(), optimizerObserver); + AmoebaOptimizer->RemoveAllObservers(); + AmoebaOptimizer->AddObserver(itk::IterationEvent(), optimizerObserver); - registration->SetOptimizer(amoebaoptimizer); + registration->SetOptimizer(AmoebaOptimizer); } } else { @@ -1300,14 +1312,14 @@ void itkImageProcessor::InitializeRegistration( steps[0] = numberOfSteps; steps[1] = numberOfSteps; steps[2] = numberOfSteps; - exhaustiveOptimizer->SetNumberOfSteps(steps); - exhaustiveOptimizer->SetStepLength(stepLength); + ExhaustiveOptimizer->SetNumberOfSteps(steps); + ExhaustiveOptimizer->SetStepLength(stepLength); - exhaustiveOptimizer->RemoveAllObservers(); - exhaustiveOptimizer->AddObserver(itk::IterationEvent(), exhaustiveOptimizerObserver); + ExhaustiveOptimizer->RemoveAllObservers(); + ExhaustiveOptimizer->AddObserver(itk::IterationEvent(), ExhaustiveOptimizerObserver); - exhaustiveOptimizer->SetStepLength(stepLength); - registration->SetOptimizer(exhaustiveOptimizer); + ExhaustiveOptimizer->SetStepLength(stepLength); + registration->SetOptimizer(ExhaustiveOptimizer); } std::cout << "#" << __COMPACT_PRETTY_FUNCTION__ << std::endl; @@ -1338,7 +1350,7 @@ int itkImageProcessor::StartRegistration(std::string extraInfo) fs << "Value\tX\tY\tZ " << std::endl; if (m_UseExhaustiveOptmizer) { - exhaustiveOptimizerObserver->set_stream(fs); + ExhaustiveOptimizerObserver->set_stream(fs); } } @@ -1369,30 +1381,47 @@ int itkImageProcessor::StartRegistration(std::string extraInfo) if (m_UseExhaustiveOptmizer) { fs.precision(std::numeric_limits::digits10 + 2); - fs << " MinimumMetricValue: " << exhaustiveOptimizer->GetMinimumMetricValue() << std::endl; - fs << " MaximumMetricValue: " << exhaustiveOptimizer->GetMaximumMetricValue() << std::endl; + fs << " MinimumMetricValue: " << ExhaustiveOptimizer->GetMinimumMetricValue() << std::endl; + fs << " MaximumMetricValue: " << ExhaustiveOptimizer->GetMaximumMetricValue() << std::endl; fs.precision(oldprecision); - fs << " MinimumMetricValuePosition: " << exhaustiveOptimizer->GetMinimumMetricValuePosition() << std::endl; - fs << " MaximumMetricValuePosition: " << exhaustiveOptimizer->GetMaximumMetricValuePosition() << std::endl; - fs << " StopConditionDescription: " << exhaustiveOptimizer->GetStopConditionDescription() << std::endl; - fs << " MaximumMetricValuePosition: " << exhaustiveOptimizer->GetMaximumMetricValuePosition() << std::endl; + fs << " MinimumMetricValuePosition: " << ExhaustiveOptimizer->GetMinimumMetricValuePosition() << std::endl; + fs << " MaximumMetricValuePosition: " << ExhaustiveOptimizer->GetMaximumMetricValuePosition() << std::endl; + fs << " StopConditionDescription: " << ExhaustiveOptimizer->GetStopConditionDescription() << std::endl; + fs << " MaximumMetricValuePosition: " << ExhaustiveOptimizer->GetMaximumMetricValuePosition() << std::endl; } else if (useDumpToFile) { fs.precision(std::numeric_limits::digits10 + 2); - fs << " FinalMetricValue: " << optimizer->GetValue() << std::endl; //same as GetCurrentCost + fs << " FinalMetricValue: " << PowellOptimizer->GetValue() << std::endl; //same as GetCurrentCost fs.precision(oldprecision); - fs << " FinalPosition: " << optimizer->GetCurrentPosition() << std::endl; - fs << " Iterations: " << optimizer->GetCurrentIteration() << std::endl; - fs << " StopConditionDescription: " << optimizer->GetStopConditionDescription() << std::endl; + fs << " FinalPosition: " << PowellOptimizer->GetCurrentPosition() << std::endl; + fs << " Iterations: " << PowellOptimizer->GetCurrentIteration() << std::endl; + fs << " StopConditionDescription: " << PowellOptimizer->GetStopConditionDescription() << std::endl; } fs.close(); - m_OptmizerValue = optimizer->GetValue(); - auto finalParameters = optimizer->GetCurrentPosition(); + m_OptmizerValue = PowellOptimizer->GetValue(); + + if(!m_UseExhaustiveOptmizer){ + if(!m_UseAmeobaOptimizer){ + //Powell + auto finalParameters = PowellOptimizer->GetCurrentPosition(); + std::cout<<"REG FINAL PARS: "<GetCurrentPosition(); + std::cout<<"REG FINAL PARS: "<GetCurrentPosition(); + std::cout<<"REG FINAL PARS: "<GetParameters(); @@ -1452,32 +1481,32 @@ itkImageProcessor::GetFinalR23Parameters(){ Optimizer::ParametersType pPars(6); pPars.fill(0.); - if(optimizer == nullptr){ + if(PowellOptimizer == nullptr){ return pPars; } switch (m_r23MetaInfo->GetDegreeOfFreedom()) { case THREE_DOF: - pPars[3] = optimizer->GetCurrentPosition()[0] + pPars[3] = PowellOptimizer->GetCurrentPosition()[0] - m_TransformMetaInfo->GetHiddenTranslations()[0]; - pPars[4] = optimizer->GetCurrentPosition()[1] + pPars[4] = PowellOptimizer->GetCurrentPosition()[1] - m_TransformMetaInfo->GetHiddenTranslations()[1]; - pPars[5] = optimizer->GetCurrentPosition()[2] + pPars[5] = PowellOptimizer->GetCurrentPosition()[2] - m_TransformMetaInfo->GetHiddenTranslations()[2]; break; case SIX_DOF: - pPars[0] = optimizer->GetCurrentPosition()[0] + pPars[0] = PowellOptimizer->GetCurrentPosition()[0] - m_TransformMetaInfo->GetHiddenRotations()[0]; - pPars[1] = optimizer->GetCurrentPosition()[1] + pPars[1] = PowellOptimizer->GetCurrentPosition()[1] - m_TransformMetaInfo->GetHiddenRotations()[1]; - pPars[2] = optimizer->GetCurrentPosition()[2] + pPars[2] = PowellOptimizer->GetCurrentPosition()[2] - m_TransformMetaInfo->GetHiddenRotations()[2]; - pPars[3] = optimizer->GetCurrentPosition()[3] + pPars[3] = PowellOptimizer->GetCurrentPosition()[3] - m_TransformMetaInfo->GetHiddenTranslations()[0]; - pPars[4] = optimizer->GetCurrentPosition()[4] + pPars[4] = PowellOptimizer->GetCurrentPosition()[4] - m_TransformMetaInfo->GetHiddenTranslations()[1]; - pPars[5] = optimizer->GetCurrentPosition()[5] + pPars[5] = PowellOptimizer->GetCurrentPosition()[5] - m_TransformMetaInfo->GetHiddenTranslations()[2]; break; @@ -2776,15 +2805,15 @@ double itkImageProcessor::GetCurrentMetricValue() //Note: this fails if the metric has not been propperly initilzed. if (!m_UseMutualInformation) { - if (metric == NULL) { + if (NCCmetric == NULL) { return nan(""); } - return metric->GetValue(); + return NCCmetric->GetValue(); } else { - if (mimetric == NULL) { + if (MImetric == NULL) { return nan(""); } - return mimetric->GetValue(); + return MImetric->GetValue(); } } @@ -2794,15 +2823,20 @@ void itkImageProcessor::SetOptimizer(std::string optimizer) if (optimizer.compare("Powell") == 0) { m_UseAmeobaOptimizer = false; m_UseExhaustiveOptmizer = false; + registration->SetOptimizer(PowellOptimizer); } else if (optimizer.compare("Amoeba") == 0) { m_UseExhaustiveOptmizer = false; m_UseAmeobaOptimizer = true; + registration->SetOptimizer(AmoebaOptimizer); } else if (optimizer.compare("Exhaustive") == 0) { m_UseExhaustiveOptmizer = true; m_UseAmeobaOptimizer = false; + registration->SetOptimizer(ExhaustiveOptimizer); } else { itkExceptionMacro(<< "Unkown optimzer string : " << optimizer); } + + } void itkImageProcessor::SetMetric(std::string metric) { @@ -2811,8 +2845,15 @@ void itkImageProcessor::SetMetric(std::string metric) } else if (metric.compare("MI") == 0) { m_UseMutualInformation = true; } else { - itkExceptionMacro(<< "Unkown metric string : " << optimizer); + itkExceptionMacro(<< "Unkown metric string : " << metric); } + + if (m_UseMutualInformation) { + registration->SetMetric(this->MImetric); + } else { + registration->SetMetric(this->NCCmetric); + } + } void itkImageProcessor::SetFullROI(bool fullROI) { diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.h b/reg23Topograms/itkDTRrecon/itkImageProcessor.h index df9f45b..42ac0ee 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.h +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.h @@ -269,7 +269,7 @@ private: using ResampleFilterType = itk::ResampleImageFilter; /** Optimizer which tries to find the minimun (Powell Optimizer)*/ - using OptimizerType = itk::PowellOptimizer; + using PowellOptimizerType = itk::PowellOptimizer; /** Optimizer which tries to find the minimn (Powell Optimizer)*/ using AmoebaOptimizerType = itk::AmoebaOptimizer; /** Optimizer which samples the whol space */ @@ -321,17 +321,17 @@ private: RegistrationType::Pointer registration; MetricType::Pointer - metric; + NCCmetric; MIMetricType::Pointer - mimetric; - OptimizerType::Pointer - optimizer; + MImetric; + PowellOptimizerType::Pointer + PowellOptimizer; AmoebaOptimizerType::Pointer - amoebaoptimizer; + AmoebaOptimizer; ExhaustiveOptimizerType::Pointer - exhaustiveOptimizer; + ExhaustiveOptimizer; ExhaustiveCommandIterationUpdate::Pointer - exhaustiveOptimizerObserver; + ExhaustiveOptimizerObserver; DuplicatorType::Pointer m_LATSourceDupli, From bc3d3e7e547363abb4b0bb8b675441eb1780df5b Mon Sep 17 00:00:00 2001 From: Proton local user Date: Fri, 19 May 2023 16:03:59 +0200 Subject: [PATCH 48/49] autoReg23 code restructure - all automatic registration stuff moved to another itk object - most of input are passed as pointers from the parent --- reg23Topograms/itkDTRrecon/CMakeLists.txt | 3 +- .../itkDTRrecon/DRTMetaInformation.cpp | 4 +- .../itkDTRrecon/DRTMetaInformation.h | 36 +- .../itkDTRrecon/itkImageProcessor.cpp | 570 +++--------------- .../itkDTRrecon/itkImageProcessor.h | 107 ++-- reg23Topograms/itkDTRrecon/itkReg23.cpp | 401 ++++++++++++ reg23Topograms/itkDTRrecon/itkReg23.h | 197 ++++++ 7 files changed, 765 insertions(+), 553 deletions(-) create mode 100644 reg23Topograms/itkDTRrecon/itkReg23.cpp create mode 100644 reg23Topograms/itkDTRrecon/itkReg23.h diff --git a/reg23Topograms/itkDTRrecon/CMakeLists.txt b/reg23Topograms/itkDTRrecon/CMakeLists.txt index e97344c..dff2dd7 100644 --- a/reg23Topograms/itkDTRrecon/CMakeLists.txt +++ b/reg23Topograms/itkDTRrecon/CMakeLists.txt @@ -19,7 +19,7 @@ SET(SRCS itkImageProcessorHelpers.cpp vtkContourTopogramProjectionFilter.cxx DRTMetaInformation.cpp - + itkReg23.cpp ) SET(HDR @@ -30,6 +30,7 @@ SET(HDR itkgSiddonJacobsRayCastInterpolateImageFunction.hxx vtkContourTopogramProjectionFilter.h DRTMetaInformation.h + itkReg23.h ) ADD_LIBRARY(${LIB_NAME} ${SRCS} ${HDR}) diff --git a/reg23Topograms/itkDTRrecon/DRTMetaInformation.cpp b/reg23Topograms/itkDTRrecon/DRTMetaInformation.cpp index ff6ae1c..1681aad 100644 --- a/reg23Topograms/itkDTRrecon/DRTMetaInformation.cpp +++ b/reg23Topograms/itkDTRrecon/DRTMetaInformation.cpp @@ -547,7 +547,9 @@ R23MetaInformation:: R23MetaInformation (){ m_DegreeOfFreedom = tDegreeOfFreedomEnum::UNKNOWN; - + m_OptimizerType = tOptimizerTypeEnum::POWELL; + m_MetricType = tMetricTypeEnum::NCC; + m_MaxIterations = 6; } diff --git a/reg23Topograms/itkDTRrecon/DRTMetaInformation.h b/reg23Topograms/itkDTRrecon/DRTMetaInformation.h index 0e6e9cd..2c59bfc 100644 --- a/reg23Topograms/itkDTRrecon/DRTMetaInformation.h +++ b/reg23Topograms/itkDTRrecon/DRTMetaInformation.h @@ -35,6 +35,19 @@ typedef enum eDegreeOfFreedomType { OTHER } tDegreeOfFreedomEnum; + +typedef enum eOptimizerType{ + POWELL, + AMOEBA, + EXHAUSTIVE +} tOptimizerTypeEnum; + +typedef enum eMetricType{ + NCC, + MI +} tMetricTypeEnum; + + inline int GetNumberOfDOF(eDegreeOfFreedomType dof) { switch (dof) { @@ -597,16 +610,35 @@ public: itkTypeMacro(R23MetaInformation, itk::Object); /** object information streaming **/ - void PrintSelf(std::ostream& os, itk::Indent indent) const; + void PrintSelf(std::ostream& os, itk::Indent indent) const override; itkSetEnumMacro(DegreeOfFreedom, tDegreeOfFreedomEnum); itkGetEnumMacro(DegreeOfFreedom, tDegreeOfFreedomEnum); + itkSetEnumMacro(OptimizerType, tOptimizerTypeEnum); + itkGetEnumMacro(OptimizerType, tOptimizerTypeEnum); + + + itkSetEnumMacro(MetricType, tMetricTypeEnum); + itkGetEnumMacro(MetricType, tMetricTypeEnum); + + itkSetEnumMacro(MaxIterations, int); + itkGetEnumMacro(MaxIterations, int); + protected: tDegreeOfFreedomEnum - m_DegreeOfFreedom; + m_DegreeOfFreedom; + + tOptimizerTypeEnum + m_OptimizerType; + + tMetricTypeEnum + m_MetricType; + + int + m_MaxIterations; /** Default Constructor **/ R23MetaInformation (); diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp index 63c2628..030e36d 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp @@ -40,7 +40,7 @@ itkImageProcessor::itkImageProcessor() { iNWUnits = 1; - // std::cout<<"itkImageProcessor::itkImageProcessor contructor"<SetIdentity(); transform2 = TransformType::New(); @@ -53,11 +53,6 @@ itkImageProcessor::itkImageProcessor() interpolator1 = InterpolatorType::New(); interpolator2 = InterpolatorType::New(); - // TZero[0]=TZero[1]=TZero[2]=0.; - // RZero[0]=RZero[1]=RZero[2]=0.; - - - toVTK2D1 = ITKtoVTKFilterType::New(); toVTK2D2 = ITKtoVTKFilterType::New(); toVTKLocalizer1 = ITKtoVTKFilterType::New(); @@ -141,37 +136,14 @@ itkImageProcessor::itkImageProcessor() m_DRTGeometryMetaInfo->SetProjectionCenterOffset1(Point3D); m_DRTGeometryMetaInfo->SetProjectionCenterOffset2(Point3D); - // setup the Automatic Registration - NCCmetric = MetricType::New(); - MImetric = MIMetricType::New(); - PowellOptimizer = PowellOptimizerType::New(); - AmoebaOptimizer = AmoebaOptimizerType::New(); optimizerObserver = CommandIterationUpdate::New(); - - - ExhaustiveOptimizer = ExhaustiveOptimizerType::New(); ExhaustiveOptimizerObserver = ExhaustiveCommandIterationUpdate::New(); - registration = RegistrationType::New(); - optimizerObserver->SetProcess(registration); - - /* default is MI */ - m_UseMutualInformation = true; //oterwise NCC is used - registration->SetMetric(MImetric); - /* default is Powell */ - m_UseExhaustiveOptmizer = false; //if the exhaustive optimizer shal be used, ovverrides ameoba - m_UseAmeobaOptimizer = false; //if the ameoba optimzer shall be used, otherwise Powell. Overriden by Exhaustive option. - registration->SetOptimizer(PowellOptimizer); - - registration->SetTransform1(transform1); - registration->SetTransform2(transform2); - registration->SetInterpolator1(interpolator1); - registration->SetInterpolator2(interpolator2); - - m_UseFullROI = true; // if the full image ROI shall be used - m_UseDumptoFile = false; //If each (!) optimzer result shall be dumpped into a file. + // TOOOOODOOOOO optimizerObserver->SetProcess(registration); + m_R23 = itkReg23::New(); + m_R23->SetOptimizerObserver(optimizerObserver); } @@ -262,11 +234,6 @@ double itkImageProcessor::GetPanelOffset2(){ -void itkImageProcessor::SetDegreeOfFreedom(tDegreeOfFreedomEnum dof) -{ - m_r23MetaInfo->SetDegreeOfFreedom(dof); -} - tDegreeOfFreedomEnum itkImageProcessor::GetDegreeOfFreedom() { @@ -1032,12 +999,12 @@ int itkImageProcessor::load2D(const char * pcFName){ m_Duplicator->SetInputImage(caster2DInput->GetOutput() ); m_Duplicator->Update(); - InternalImageType::IndexType pIndex; - pIndex[0]=200; - pIndex[1]=300; - InternalImageType::PixelType pPixel = - m_Duplicator->GetOutput()->GetPixel(pIndex); - std::cout<<"processro PIXEL: "<GetOutput()->GetPixel(pIndex); + //std::cout<<"processro PIXEL: "<GetOutput()->GetDirection()<ComputeGradientOff(); - MImetric->ComputeGradientOff(); - - NCCmetric->SetSubtractMean(true); - - NCCmetric->SetMaxTranslation(maxTranslation); - MImetric->SetMaxTranslation(maxTranslation); - - m_r23MetaInfo->SetDegreeOfFreedom(dof); - - - if (verbose) { - NCCmetric->DebugOn(); - MImetric->DebugOn(); - } - - - registration->SetFixedImage1(m_PASourceDupli->GetOutput()); - registration->SetFixedImage2(m_LATSourceDupli->GetOutput()); - registration->SetMovingImage(m_VolumeSourceDupli->GetOutput()); - - //TODO: Here we could set the ROI for image registartion - - - if (m_UseFullROI == false) { - - auto region1 = m_PASourceDupli->GetOutput()->GetBufferedRegion(); - auto region2 = m_LATSourceDupli->GetOutput()->GetBufferedRegion(); - std::cout << "region1 of opti - NO ROI " << region1 << std::endl; - std::cout << "region2 of opti - NO ROI " << region2 << std::endl; - - registration->SetFixedImageRegion1(roiAutoReg1); - registration->SetFixedImageRegion2(roiAutoReg2); - MImetric->SetFixedImageRegion1(roiAutoReg1); - MImetric->SetFixedImageRegion2(roiAutoReg2); - NCCmetric->SetFixedImageRegion1(roiAutoReg1); - NCCmetric->SetFixedImageRegion2(roiAutoReg2); - - std::cout << "using ROIs for Auto Reg " << std::endl; - - std::cout << "region1 of opti " << roiAutoReg1 << std::endl; - std::cout << "region2 of opti " << roiAutoReg2 << std::endl; - - }else{ - - auto region1 = m_PASourceDupli->GetOutput()->GetBufferedRegion(); - auto region2 = m_LATSourceDupli->GetOutput()->GetBufferedRegion(); - std::cout << "region1 of opti - NO ROI " << region1 << std::endl; - std::cout << "region2 of opti - NO ROI " << region2 << std::endl; - - registration->SetFixedImageRegion1(region1); - registration->SetFixedImageRegion2(region2); - MImetric->SetFixedImageRegion1(roiAutoReg1); - MImetric->SetFixedImageRegion2(roiAutoReg2); - NCCmetric->SetFixedImageRegion1(roiAutoReg1); - NCCmetric->SetFixedImageRegion2(roiAutoReg2); - } - - - // registration->SetTransformMetaInfo(m_TransformMetaInfo); - registration->SetTransformMetaInfo(m_r23MetaInfo); - registration->SetinternalMeta1(m_InternalTransf1); - registration->SetinternalMeta2(m_InternalTransf2); - - registration->SetFilter1(filter1); - registration->SetFilter2(filter2); - - - IsocTransf = TransformType::New(); - IsocTransf->SetComputeZYX(true); - IsocTransf->SetIdentity(); - - IsocTransf->SetRotation( - m_TransformMetaInfo->GetR()[0], - m_TransformMetaInfo->GetR()[1], - m_TransformMetaInfo->GetR()[2] - ); - - TransformType::OutputVectorType TranslV; - TranslV[0] = m_TransformMetaInfo->GetT()[0]; - TranslV[1] = m_TransformMetaInfo->GetT()[1]; - TranslV[2] = m_TransformMetaInfo->GetT()[2]; - - IsocTransf->SetTranslation(TranslV); - - registration->SetIsocIECTransform(IsocTransf); - - if (verbose) { - registration->DebugOn(); - registration->Print(std::cout); - } - - if (!m_UseExhaustiveOptmizer) { - if (!m_UseAmeobaOptimizer) { - - // The metric will return 0 or a "large" negative number in case of high correspondence of the images - // Thus, we need to minimze - PowellOptimizer->SetMaximize(false); // for NCC and MI - PowellOptimizer->SetMaximumIteration(m_MaxNumberOfIterations); - PowellOptimizer->SetMaximumLineIteration(4); // for Powell's method - PowellOptimizer->SetStepLength(stepLength); - PowellOptimizer->SetStepTolerance(0.01); - PowellOptimizer->SetValueTolerance(0.000002); - if (verbose) { - PowellOptimizer->DebugOn(); - PowellOptimizer->Print(std::cout); - } - - - PowellOptimizer->RemoveAllObservers(); - PowellOptimizer->AddObserver(itk::AnyEvent(), optimizerObserver); - - registration->SetOptimizer(PowellOptimizer); - registration->RemoveAllObservers(); - - } else { - - AmoebaOptimizer->SetMinimize(true); - AmoebaOptimizer->SetMaximumNumberOfIterations(100); - AmoebaOptimizer->SetParametersConvergenceTolerance(0.1); - AmoebaOptimizer->SetFunctionConvergenceTolerance(0.000002); - - AmoebaOptimizer->SetAutomaticInitialSimplex(false); - //Initial size of the simplex (otherwise it is a very small number and optimizer stops immeditaly) - // 2 mm / 2 degrees seems to be a good value which performs well. - AmoebaOptimizerType::ParametersType simplexDelta(3); - int numberOfDOF = GetNumberOfDOF(dof); - if (numberOfDOF == 0) { - itkExceptionMacro(<< "Unkown or unsupported degree of freedom"); - } - for (int i = 0; i < numberOfDOF; i++) { - simplexDelta[i] = 2.0; - } - AmoebaOptimizer->SetInitialSimplexDelta(simplexDelta); - - AmoebaOptimizer->RemoveAllObservers(); - AmoebaOptimizer->AddObserver(itk::IterationEvent(), optimizerObserver); - - registration->SetOptimizer(AmoebaOptimizer); - } - - } else { - //only support for 3DOF - const int numberOfSteps = 25; //In each direction. Total number of steps is ((2*numberOfSteps+1))^3. For 25 -> 132651. - const double stepLength = 0.1; - - //auto parameters = transform1->GetParameters(); - //transform1->SetParameters(parameters); - - ExhaustiveOptimizerType::StepsType steps(3); - steps[0] = numberOfSteps; - steps[1] = numberOfSteps; - steps[2] = numberOfSteps; - ExhaustiveOptimizer->SetNumberOfSteps(steps); - ExhaustiveOptimizer->SetStepLength(stepLength); - - ExhaustiveOptimizer->RemoveAllObservers(); - ExhaustiveOptimizer->AddObserver(itk::IterationEvent(), ExhaustiveOptimizerObserver); - - ExhaustiveOptimizer->SetStepLength(stepLength); - registration->SetOptimizer(ExhaustiveOptimizer); - } - - std::cout << "#" << __COMPACT_PRETTY_FUNCTION__ << std::endl; -} - -int itkImageProcessor::StartRegistration(std::string extraInfo) -{ - - std::cout << "*" << __COMPACT_PRETTY_FUNCTION__ << std::endl; - // TODO: Check if the registartion pipeline has been initialized - using ParametersType = RegistrationType::ParametersType; - - //auto startParameters = transform1->GetParameters(); - - time_t t = time(0); // get time now - struct tm* now = localtime(&t); - - bool useDumpToFile = false; - - char buffer[255]; - strftime(buffer, 255, "test-%F-%H%M%S.txt", now); - - std::fstream fs; - - if (useDumpToFile || m_UseExhaustiveOptmizer) { - fs.open(buffer, std::fstream::out); - fs << extraInfo; - fs << "Value\tX\tY\tZ " << std::endl; - - if (m_UseExhaustiveOptmizer) { - ExhaustiveOptimizerObserver->set_stream(fs); - } - } - - // Start the registration - // ~~~~~~~~~~~~~~~~~~~~~~ - - // Create a timer to record calculation time. - itk::TimeProbesCollectorBase timer; - - if (verbose) { - std::cout << "Starting the registration now..." << std::endl; - } - - try { - // timer.Start("Registration"); - // Start the registration. - registration->StartRegistration(); - // timer.Stop("Registration"); - } catch (itk::ExceptionObject& err) { - - registration->ResetPipeline(); - std::cout << "ExceptionObject caught !" << std::endl; - std::cout << err << std::endl; - return -1; - } - - auto oldprecision = fs.precision(); - - if (m_UseExhaustiveOptmizer) { - fs.precision(std::numeric_limits::digits10 + 2); - fs << " MinimumMetricValue: " << ExhaustiveOptimizer->GetMinimumMetricValue() << std::endl; - fs << " MaximumMetricValue: " << ExhaustiveOptimizer->GetMaximumMetricValue() << std::endl; - fs.precision(oldprecision); - fs << " MinimumMetricValuePosition: " << ExhaustiveOptimizer->GetMinimumMetricValuePosition() << std::endl; - fs << " MaximumMetricValuePosition: " << ExhaustiveOptimizer->GetMaximumMetricValuePosition() << std::endl; - fs << " StopConditionDescription: " << ExhaustiveOptimizer->GetStopConditionDescription() << std::endl; - fs << " MaximumMetricValuePosition: " << ExhaustiveOptimizer->GetMaximumMetricValuePosition() << std::endl; - } else if (useDumpToFile) { - fs.precision(std::numeric_limits::digits10 + 2); - fs << " FinalMetricValue: " << PowellOptimizer->GetValue() << std::endl; //same as GetCurrentCost - fs.precision(oldprecision); - fs << " FinalPosition: " << PowellOptimizer->GetCurrentPosition() << std::endl; - fs << " Iterations: " << PowellOptimizer->GetCurrentIteration() << std::endl; - fs << " StopConditionDescription: " << PowellOptimizer->GetStopConditionDescription() << std::endl; - } - - fs.close(); - - - - m_OptmizerValue = PowellOptimizer->GetValue(); - - if(!m_UseExhaustiveOptmizer){ - if(!m_UseAmeobaOptimizer){ - //Powell - auto finalParameters = PowellOptimizer->GetCurrentPosition(); - std::cout<<"REG FINAL PARS: "<GetCurrentPosition(); - std::cout<<"REG FINAL PARS: "<GetCurrentPosition(); - std::cout<<"REG FINAL PARS: "<GetParameters(); - // std::cout<<"-->startParameters "<finalParameters1 "<GetParameters()<finalParameters2 "<GetParameters()<GetCurrentPosition(); - // finalParameters = finalParameters - startParameters; - - // std::cout<<"startParameters "<GetCenter()<GetTranslation()<GetCenter()<GetTranslation()<SetParameters(finalParameters); - - // CalculateExternalUserTransform(offsetTransform, m_DRTImage1MetaInfo); - - // const double translationAlongX = finalParameters[3]; - // const double translationAlongY = finalParameters[4]; - // const double translationAlongZ = finalParameters[5]; - // const double rotationAlongX = finalParameters[0]; - // const double rotationAlongY = finalParameters[1]; - // const double rotationAlongZ = finalParameters[2]; - - // const int numberOfIterations = optimizer->GetCurrentIteration(); - - // std::cout << "Result = " << std::endl; - // std::cout << " Rotation Along X = " << rotationAlongX / dtr << " deg" << std::endl; - // std::cout << " Rotation Along Y = " << rotationAlongY / dtr << " deg" << std::endl; - // std::cout << " Rotation Along Z = " << rotationAlongZ / dtr << " deg" << std::endl; - // std::cout << " Translation X = " << translationAlongX << " mm" << std::endl; - // std::cout << " Translation Y = " << translationAlongY << " mm" << std::endl; - // std::cout << " Translation Z = " << translationAlongZ << " mm" << std::endl; - // std::cout << " Number Of Iterations = " << numberOfIterations << std::endl; - // std::cout << " Metric value = " << m_OptmizerValue << std::endl; - - std::cout << "#" << __COMPACT_PRETTY_FUNCTION__ << std::endl; - - return 0; -} Optimizer::ParametersType itkImageProcessor::GetFinalR23Parameters(){ @@ -1481,32 +1098,31 @@ itkImageProcessor::GetFinalR23Parameters(){ Optimizer::ParametersType pPars(6); pPars.fill(0.); - if(PowellOptimizer == nullptr){ - return pPars; - } + itk::Optimizer::ParametersType currentPosition = + m_R23->GetCurrentPosition(); switch (m_r23MetaInfo->GetDegreeOfFreedom()) { case THREE_DOF: - pPars[3] = PowellOptimizer->GetCurrentPosition()[0] + pPars[3] = currentPosition[0] - m_TransformMetaInfo->GetHiddenTranslations()[0]; - pPars[4] = PowellOptimizer->GetCurrentPosition()[1] + pPars[4] = currentPosition[1] - m_TransformMetaInfo->GetHiddenTranslations()[1]; - pPars[5] = PowellOptimizer->GetCurrentPosition()[2] + pPars[5] = currentPosition[2] - m_TransformMetaInfo->GetHiddenTranslations()[2]; break; case SIX_DOF: - pPars[0] = PowellOptimizer->GetCurrentPosition()[0] + pPars[0] = currentPosition[0] - m_TransformMetaInfo->GetHiddenRotations()[0]; - pPars[1] = PowellOptimizer->GetCurrentPosition()[1] + pPars[1] = currentPosition[1] - m_TransformMetaInfo->GetHiddenRotations()[1]; - pPars[2] = PowellOptimizer->GetCurrentPosition()[2] + pPars[2] = currentPosition[2] - m_TransformMetaInfo->GetHiddenRotations()[2]; - pPars[3] = PowellOptimizer->GetCurrentPosition()[3] + pPars[3] = currentPosition[3] - m_TransformMetaInfo->GetHiddenTranslations()[0]; - pPars[4] = PowellOptimizer->GetCurrentPosition()[4] + pPars[4] = currentPosition[4] - m_TransformMetaInfo->GetHiddenTranslations()[1]; - pPars[5] = PowellOptimizer->GetCurrentPosition()[5] + pPars[5] = currentPosition[5] - m_TransformMetaInfo->GetHiddenTranslations()[2]; break; @@ -1521,6 +1137,41 @@ itkImageProcessor::GetFinalR23Parameters(){ } + +void itkImageProcessor::SetOptimizer(std::string optimizer) +{ + + if (optimizer.compare("Powell") == 0) { + m_r23MetaInfo->SetOptimizerType(tOptimizerTypeEnum::POWELL); + } else if (optimizer.compare("Amoeba") == 0) { + m_r23MetaInfo->SetOptimizerType(tOptimizerTypeEnum::AMOEBA); + } else if (optimizer.compare("Exhaustive") == 0) { + m_r23MetaInfo->SetOptimizerType(tOptimizerTypeEnum::EXHAUSTIVE); + } else { + itkExceptionMacro(<< "Unkown optimzer string : " << optimizer); + } + + +} +void itkImageProcessor::SetMetric(std::string metric) +{ + + if (metric.compare("NCC") == 0) { + m_r23MetaInfo->SetMetricType(tMetricTypeEnum::NCC); + } else if (metric.compare("MI") == 0) { + m_r23MetaInfo->SetMetricType(tMetricTypeEnum::MI); + } else { + itkExceptionMacro(<< "Unkown metric string : " << metric); + } + + +} + +void itkImageProcessor::SetMaxNumberOfIterations(int iNum) +{ + m_r23MetaInfo->SetMaxIterations(iNum); +} + void itkImageProcessor::InitializeProjector() { @@ -2795,77 +2446,6 @@ itkImageProcessor::GetCompleteIsocentricTransform } -double itkImageProcessor::GetOptimizerValue() -{ - return m_OptmizerValue; -} - -double itkImageProcessor::GetCurrentMetricValue() -{ - //Note: this fails if the metric has not been propperly initilzed. - - if (!m_UseMutualInformation) { - if (NCCmetric == NULL) { - return nan(""); - } - return NCCmetric->GetValue(); - } else { - if (MImetric == NULL) { - return nan(""); - } - return MImetric->GetValue(); - } -} - - -void itkImageProcessor::SetOptimizer(std::string optimizer) -{ - if (optimizer.compare("Powell") == 0) { - m_UseAmeobaOptimizer = false; - m_UseExhaustiveOptmizer = false; - registration->SetOptimizer(PowellOptimizer); - } else if (optimizer.compare("Amoeba") == 0) { - m_UseExhaustiveOptmizer = false; - m_UseAmeobaOptimizer = true; - registration->SetOptimizer(AmoebaOptimizer); - } else if (optimizer.compare("Exhaustive") == 0) { - m_UseExhaustiveOptmizer = true; - m_UseAmeobaOptimizer = false; - registration->SetOptimizer(ExhaustiveOptimizer); - } else { - itkExceptionMacro(<< "Unkown optimzer string : " << optimizer); - } - - -} -void itkImageProcessor::SetMetric(std::string metric) -{ - if (metric.compare("NCC") == 0) { - m_UseMutualInformation = false; - } else if (metric.compare("MI") == 0) { - m_UseMutualInformation = true; - } else { - itkExceptionMacro(<< "Unkown metric string : " << metric); - } - - if (m_UseMutualInformation) { - registration->SetMetric(this->MImetric); - } else { - registration->SetMetric(this->NCCmetric); - } - -} -void itkImageProcessor::SetFullROI(bool fullROI) -{ - m_UseFullROI = fullROI; - // TODO: Remove this function when ROI functinalitz has been implemented. -} - -void itkImageProcessor::SetMaxNumberOfIterations(int iNum) -{ - m_MaxNumberOfIterations = iNum; - // TODO: Remove this function when ROI functinalitz has been implemented. -} void itkImageProcessor::SetRegionFixed1( int iIdx0, int iIdx1, int iSz0, int iSz1){ @@ -2888,6 +2468,8 @@ void itkImageProcessor::SetRegionFixed1( std::cout << "itkImageProcessor " << std::endl; std::cout << roiAutoReg1 << std::endl; + this->m_R23->SetroiAutoReg1(roiAutoReg1); + } void itkImageProcessor::SetRegionFixed2( @@ -2911,7 +2493,43 @@ void itkImageProcessor::SetRegionFixed2( std::cout << "itkImageProcessor " << std::endl; std::cout << roiAutoReg2 << std::endl; + this->m_R23->SetroiAutoReg2(roiAutoReg2); + } +void itkImageProcessor::ResetROIRegions(){ + + auto region1temp = m_PASourceDupli->GetOutput()->GetBufferedRegion(); + auto region2temp = m_LATSourceDupli->GetOutput()->GetBufferedRegion(); + + this->m_R23->SetroiAutoReg1(region1temp); + this->m_R23->SetroiAutoReg2(region2temp); + +} + +void itkImageProcessor::InizializeRegistration(double stepLength, + double maxTranslation, + eDegreeOfFreedomType dof){ + + m_r23MetaInfo->SetDegreeOfFreedom(dof); + m_R23->SetPA(m_PASourceDupli->GetOutput()); + m_R23->SetLAT(m_LATSourceDupli->GetOutput()); + m_R23->SetVolume(m_VolumeSourceDupli->GetOutput()); + m_R23->Setr23Meta(m_r23MetaInfo); + m_R23->SetInternalTransf1(m_InternalTransf1); + m_R23->SetInternalTransf2(m_InternalTransf2); + m_R23->Setfilter1(filter1); + m_R23->Setfilter2(filter2); + m_R23->Setinterpolator1(interpolator1); + m_R23->Setinterpolator2(interpolator2); + m_R23->SetTransformMetaInfo(m_TransformMetaInfo); + + m_R23->InitializeRegistration( + stepLength,maxTranslation,dof); + +} + + + } // end namespace itk diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.h b/reg23Topograms/itkDTRrecon/itkImageProcessor.h index 42ac0ee..b4f2400 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.h +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.h @@ -30,13 +30,6 @@ gfattori 08.11.2021 #include "itkObjectFactory.h" #include "itkSmartPointer.h" -#include "itkExhaustiveOptimizer.h" -#include "itkMutualInformationTwoImageToOneImageMetric.h" -#include "itkNormalizedCorrelationTwoImageToOneImageMetric.h" -#include "itkPowellOptimizer.h" -#include "itkTwoProjectionImageRegistrationMethod.h" -#include "itkAmoebaOptimizer.h" - #include "itkImageToVTKImageFilter.h" #include "itkImageFileReader.h" @@ -53,6 +46,8 @@ gfattori 08.11.2021 #include "itkImageProcessorHelpers.h" +#include "itkReg23.h" + namespace itk { @@ -78,6 +73,33 @@ public: CommandIterationUpdate::Pointer optimizerObserver; + ExhaustiveCommandIterationUpdate::Pointer + ExhaustiveOptimizerObserver; + + /** Sets the degree of freedom for optimzation*/ + tDegreeOfFreedomEnum GetDegreeOfFreedom(); + /** Returns user components only of the autoReg + * */ + Optimizer::ParametersType + GetFinalR23Parameters(); + /** Define the region to be used as ROI on fixed images */ + void SetRegionFixed1(int,int,int,int); + void SetRegionFixed2(int,int,int,int); + void ResetROIRegions(); + void InizializeRegistration(double stepLength, + double maxTranslation, + eDegreeOfFreedomType dof); + + /** Maximum number of iterations for the optimizer */ + void SetMaxNumberOfIterations(int); + itkGetMacro(R23, itkReg23::Pointer); + + + /** Set Optimizer type */ + void SetOptimizer(std::string); + /** Set Metric type */ + void SetMetric(std::string); + /** Set number of logic CPU to be made available to interpolators*/ void SetNumberOfWorkingUnits(int iN); @@ -116,10 +138,6 @@ public: double GetPanelOffset1(); double GetPanelOffset2(); - /** Sets the degree of freedom for omptimzation*/ - void SetDegreeOfFreedom(tDegreeOfFreedomEnum); - tDegreeOfFreedomEnum GetDegreeOfFreedom(); - void SetCustom_ProjectionCenterOffsetFixedAxes_IEC(double,double,double,double,double,double); void SetCustom_ProjectionCenterFixedAxes_IEC(double,double,double); @@ -147,16 +165,6 @@ public: void SetInitialTranslations(double, double, double); void SetInitialRotations(double, double, double); - /** Returns user components only of the autoReg - * */ - Optimizer::ParametersType - GetFinalR23Parameters(); - - /** Initialize the registration pipeline*/ - void InitializeRegistration(double, double, eDegreeOfFreedomType); - /** Start the registration process*/ - int StartRegistration(std::string extraInfo); - ///** Get transform parameters for 3D Volume */ /** Get the complete transform, likely for export to SRO. * This includes user and hidden contributions. @@ -215,25 +223,6 @@ public: void WriteProjectionImages(); void Write2DImages(); - /** Auto Reg23 methods */ - - /** Get the current cost function value from the optimizer*/ - double GetOptimizerValue(); - - /** Get the cost function value for the current transform*/ - double GetCurrentMetricValue(); - - /** Set Optimizer type */ - void SetOptimizer(std::string); - /** Set Metric type */ - void SetMetric(std::string); - /** Use full image as ROI */ - void SetFullROI(bool); - /** Maximum number of iterations for the optimizer */ - void SetMaxNumberOfIterations(int); - /** Define the region to be used as ROI on fixed images */ - void SetRegionFixed1(int,int,int,int); - void SetRegionFixed2(int,int,int,int); protected: /** Various pixel types */ @@ -268,17 +257,6 @@ private: using InterpolatorType = itk::gSiddonJacobsRayCastInterpolateImageFunction; using ResampleFilterType = itk::ResampleImageFilter; - /** Optimizer which tries to find the minimun (Powell Optimizer)*/ - using PowellOptimizerType = itk::PowellOptimizer; - /** Optimizer which tries to find the minimn (Powell Optimizer)*/ - using AmoebaOptimizerType = itk::AmoebaOptimizer; - /** Optimizer which samples the whol space */ - using ExhaustiveOptimizerType = itk::ExhaustiveOptimizer; - /** Metric to calculate similarites between images*/ - using MetricType = itk::NormalizedCorrelationTwoImageToOneImageMetric; - using MIMetricType = itk::MutualInformationTwoImageToOneImageMetric; - /** The thing which actuall does the image registration*/ - using RegistrationType = itk::TwoProjectionImageRegistrationMethod; using RoiForRegistration = itk::ImageRegion; @@ -318,20 +296,7 @@ private: imageDRT1In, imageDRT2In; - RegistrationType::Pointer - registration; - MetricType::Pointer - NCCmetric; - MIMetricType::Pointer - MImetric; - PowellOptimizerType::Pointer - PowellOptimizer; - AmoebaOptimizerType::Pointer - AmoebaOptimizer; - ExhaustiveOptimizerType::Pointer - ExhaustiveOptimizer; - ExhaustiveCommandIterationUpdate::Pointer - ExhaustiveOptimizerObserver; + DuplicatorType::Pointer m_LATSourceDupli, @@ -426,23 +391,19 @@ private: m_InternalTransf1, m_InternalTransf2; - double m_OptmizerValue; - int m_MaxNumberOfIterations; RoiForRegistration roiAutoReg1, roiAutoReg2; - bool m_UseExhaustiveOptmizer; - bool m_UseAmeobaOptimizer; - bool m_UseFullROI; - bool m_UseMutualInformation; - bool m_UseDumptoFile; - int iNWUnits; + + itk::itkReg23::Pointer + m_R23; + }; diff --git a/reg23Topograms/itkDTRrecon/itkReg23.cpp b/reg23Topograms/itkDTRrecon/itkReg23.cpp new file mode 100644 index 0000000..4f1c903 --- /dev/null +++ b/reg23Topograms/itkDTRrecon/itkReg23.cpp @@ -0,0 +1,401 @@ +#include "itkReg23.h" + + + +#include "itkTimeProbesCollectorBase.h" + +namespace itk +{ + +itkReg23::itkReg23() +{ + // Metrics + NCCmetric = MetricType::New(); + MImetric = MIMetricType::New(); + + // Optimizers + PowellOptimizer = PowellOptimizerType::New(); + AmoebaOptimizer = AmoebaOptimizerType::New(); + ExhaustiveOptimizer = ExhaustiveOptimizerType::New(); + + // Registration + registration = RegistrationType::New(); + + //internalTransforms + Transform1 = TransformType::New(); + Transform2 = TransformType::New(); + IsocTransform = TransformType::New(); + + registration->SetTransform1(Transform1); + registration->SetTransform2(Transform2); + + + + // to be provided by the user + m_r23Meta = nullptr; + m_Volume = nullptr; + m_PA = nullptr; + m_LAT = nullptr; + m_InternalTransf1 = nullptr; + m_InternalTransf2 = nullptr; + m_filter1 = nullptr; + m_filter2 = nullptr; + m_TransformMetaInfo = nullptr; + m_OptimizerObserver = nullptr; + + // m_UseFullROI = true; // if the full image ROI shall be used + m_UseDumptoFile = false; //If each (!) optimzer result shall be dumpped into a file. + +} + + +itkReg23::~itkReg23() +{ + +} + +void itkReg23::PrintSelf(std::ostream& os, Indent indent) const +{ + Superclass::PrintSelf(os, indent); +} + +void itkReg23::InitializeRegistration( + double stepLength, + double maxTranslation, + eDegreeOfFreedomType dof) +{ + std::cout << "*" << __COMPACT_PRETTY_FUNCTION__ << std::endl; + + if (!m_PA) { + itkExceptionMacro(<< "PA topogram not present"); + } + + if (!m_LAT) { + itkExceptionMacro(<< "LAT topogram not present"); + } + + if (!m_Volume) { + itkExceptionMacro(<< "CT data not present"); + } + + if (!m_r23Meta) { + itkExceptionMacro(<< "r23Meta data not present"); + } + + if (!m_OptimizerObserver) { + itkExceptionMacro(<< "m_OptimizerObserver data not present"); + } + + if (!m_InternalTransf1) { + itkExceptionMacro(<< "m_InternalTransf1 data not present"); + } + + if (!m_InternalTransf2) { + itkExceptionMacro(<< "m_InternalTransf2 data not present"); + } + + if (!m_filter1) { + itkExceptionMacro(<< "m_filter1 data not present"); + } + + if (!m_filter2) { + itkExceptionMacro(<< "m_filter2 data not present"); + } + + if (!m_TransformMetaInfo) { + itkExceptionMacro(<< "m_TransformMetaInfo data not present"); + } + + if(!m_interpolator1){ + itkExceptionMacro(<< "m_interpolator1 data not present"); + } + + if(!m_interpolator2){ + itkExceptionMacro(<< "m_interpolator2 data not present"); + } + + AmoebaOptimizerType::ParametersType simplexDelta(3); + ExhaustiveOptimizerType::StepsType steps(3); + const int numberOfSteps = 25; //In each direction. Total number of steps is ((2*numberOfSteps+1))^3. For 25 -> 132651. + //const double stepLength = 0.1; + + switch (m_r23Meta->GetOptimizerType()) { + + case tOptimizerTypeEnum::POWELL: + std::cout<< "Using POWELL Optimizer" <SetMaximize(false); // for NCC and MI + PowellOptimizer->SetMaximumIteration(m_r23Meta->GetMaxIterations()); + PowellOptimizer->SetMaximumLineIteration(4); // for Powell's method + PowellOptimizer->SetStepLength(stepLength); + PowellOptimizer->SetStepTolerance(0.01); + PowellOptimizer->SetValueTolerance(0.000002); + PowellOptimizer->RemoveAllObservers(); + PowellOptimizer->AddObserver(itk::IterationEvent(), m_OptimizerObserver); + + registration->SetOptimizer(PowellOptimizer); + + break; + + case tOptimizerTypeEnum::AMOEBA: + std::cout<< "Using AMOEBA Optimizer" <SetMinimize(true); + AmoebaOptimizer->SetMaximumNumberOfIterations(m_r23Meta->GetMaxIterations()); + AmoebaOptimizer->SetParametersConvergenceTolerance(0.1); + AmoebaOptimizer->SetFunctionConvergenceTolerance(0.000002); + AmoebaOptimizer->SetAutomaticInitialSimplex(false); + //Initial size of the simplex (otherwise it is a very small number and optimizer stops immeditaly) + // 2 mm / 2 degrees seems to be a good value which performs well. + if (GetNumberOfDOF(dof) == 0) { + itkExceptionMacro(<< "Unkown or unsupported degree of freedom"); + } + for (int i = 0; i < GetNumberOfDOF(dof); i++) { + simplexDelta[i] = 2.0; + } + AmoebaOptimizer->SetInitialSimplexDelta(simplexDelta); + AmoebaOptimizer->RemoveAllObservers(); + AmoebaOptimizer->AddObserver(itk::IterationEvent(), m_OptimizerObserver); + + registration->SetOptimizer(AmoebaOptimizer); + + break; + + case tOptimizerTypeEnum::EXHAUSTIVE: + std::cout<< "Using Extensive Optimizer" <SetNumberOfSteps(steps); + ExhaustiveOptimizer->SetStepLength(stepLength); + + registration->SetOptimizer(ExhaustiveOptimizer); + + break; + + default: + break; + + } + + switch (m_r23Meta->GetMetricType()) { + + case tMetricTypeEnum::MI: + std::cout<< "Using MI Metric" <SetMetric(MImetric); + MImetric->ComputeGradientOff(); + MImetric->SetMaxTranslation(maxTranslation); + + break; + + case tMetricTypeEnum::NCC: + std::cout<< "Using NCC Metric" <SetMetric(NCCmetric); + NCCmetric->ComputeGradientOff(); + NCCmetric->SetSubtractMean(true); + NCCmetric->SetMaxTranslation(maxTranslation); + + break; + + default: + break; + + } + + registration->SetFixedImage1(m_PA); + registration->SetFixedImage2(m_LAT); + registration->SetMovingImage(m_Volume); + + registration->SetFixedImageRegion1(m_roiAutoReg1); + registration->SetFixedImageRegion2(m_roiAutoReg2); + std::cout<< "Using Region1:"<SetTransformMetaInfo(m_r23Meta); + + registration->SetinternalMeta1(m_InternalTransf1); + registration->SetinternalMeta2(m_InternalTransf2); + + registration->SetInterpolator1(m_interpolator1); + registration->SetInterpolator2(m_interpolator2); + + registration->SetFilter1(m_filter1); + registration->SetFilter2(m_filter2); + + + IsocTransform = TransformType::New(); + IsocTransform->SetComputeZYX(true); + IsocTransform->SetIdentity(); + + IsocTransform->SetRotation( + m_TransformMetaInfo->GetR()[0], + m_TransformMetaInfo->GetR()[1], + m_TransformMetaInfo->GetR()[2] + ); + + TransformType::OutputVectorType TranslV; + TranslV[0] = m_TransformMetaInfo->GetT()[0]; + TranslV[1] = m_TransformMetaInfo->GetT()[1]; + TranslV[2] = m_TransformMetaInfo->GetT()[2]; + + IsocTransform->SetTranslation(TranslV); + + registration->SetIsocIECTransform(IsocTransform); + + // if (verbose) { + // registration->DebugOn(); + // registration->Print(std::cout); + // } + + + std::cout << "#" << __COMPACT_PRETTY_FUNCTION__ << std::endl; +} + + + +int itkReg23::StartRegistration(std::string extraInfo) +{ + + std::cout << "*" << __COMPACT_PRETTY_FUNCTION__ << std::endl; + // TODO: Check if the registartion pipeline has been initialized + using ParametersType = RegistrationType::ParametersType; + + //auto startParameters = transform1->GetParameters(); + + time_t t = time(0); // get time now + struct tm* now = localtime(&t); + + bool useDumpToFile = false; + + char buffer[255]; + strftime(buffer, 255, "test-%F-%H%M%S.txt", now); + + std::fstream fs; + + if (useDumpToFile) { + fs.open(buffer, std::fstream::out); + fs << extraInfo; + fs << "Value\tX\tY\tZ " << std::endl; + + // if (r23Meta->GetOptimizerType() == tOptimizerTypeEnum::EXHAUSTIVE) { + // ExhaustiveOptimizerObserver->set_stream(fs); + // } + } + + // Start the registration + // ~~~~~~~~~~~~~~~~~~~~~~ + + // Create a timer to record calculation time. + itk::TimeProbesCollectorBase timer; + + if (verbose) { + std::cout << "Starting the registration now..." << std::endl; + } + + try { + // timer.Start("Registration"); + // Start the registration. + registration->StartRegistration(); + // timer.Stop("Registration"); + } catch (itk::ExceptionObject& err) { + + registration->ResetPipeline(); + std::cout << "ExceptionObject caught !" << std::endl; + std::cout << err << std::endl; + return -1; + } + + fs.close(); + + + itk::Optimizer::ParametersType finalParameters = + this->GetCurrentPosition(); + std::cout<<" FinalPars: "<< finalParameters <GetOptimizerType()) { + + case tOptimizerTypeEnum::POWELL: + finalParameters = PowellOptimizer->GetCurrentPosition(); + m_OptmizerValue = PowellOptimizer->GetValue(); + break; + + case tOptimizerTypeEnum::AMOEBA: + finalParameters = AmoebaOptimizer->GetCurrentPosition(); + m_OptmizerValue = AmoebaOptimizer->GetValue(); + break; + + case tOptimizerTypeEnum::EXHAUSTIVE: + finalParameters = ExhaustiveOptimizer->GetCurrentPosition(); + break; + + default: + break; + + } + + return finalParameters; +} + +double itkReg23::GetCurrentMetricValue() +{ + + switch (m_r23Meta->GetMetricType()) { + + case tMetricTypeEnum::MI: + if(!MImetric){ + itkExceptionMacro(<< "MImetric not present"); + return -1.; + } else { + return MImetric->GetValue(); + } + + break; + + case tMetricTypeEnum::NCC: + if(!NCCmetric){ + itkExceptionMacro(<< "NCCmetric not present"); + return -1.; + } else { + return NCCmetric->GetValue(); + } + break; + + default: + break; + + } + + return -1.; + +} + + +//void itkReg23::SetFullROI(bool fullROI) +//{ +// m_UseFullROI = fullROI; +// // TODO: Remove this function when ROI functinalitz has been implemented. +//} + + +} diff --git a/reg23Topograms/itkDTRrecon/itkReg23.h b/reg23Topograms/itkDTRrecon/itkReg23.h new file mode 100644 index 0000000..0154672 --- /dev/null +++ b/reg23Topograms/itkDTRrecon/itkReg23.h @@ -0,0 +1,197 @@ +#ifndef ITKREG23_H +#define ITKREG23_h + +#include "itkCommand.h" + +#include "itkExhaustiveOptimizer.h" +#include "itkMutualInformationTwoImageToOneImageMetric.h" +#include "itkNormalizedCorrelationTwoImageToOneImageMetric.h" +#include "itkPowellOptimizer.h" +#include "itkTwoProjectionImageRegistrationMethod.h" +#include "itkAmoebaOptimizer.h" + +#include "itkCommand.h" +#include "itkObject.h" +#include "itkObjectFactory.h" +#include "itkSmartPointer.h" + +#include "itkImageProcessorHelpers.h" +#include "itkQtIterationUpdate.h" + + +namespace itk{ + +class ITK_EXPORT itkReg23 : public itk::Object +{ + +public: + + /** Standard "Self" typedef. */ + typedef itkReg23 Self; + /** Standard "Superclass" typedef. */ + typedef Object Superclass; + /** Smart pointer typedef support */ + typedef itk::SmartPointer Pointer; + typedef itk::SmartPointer ConstPointer; + /** Method of creation through the object factory. */ + itkNewMacro(Self); + /** Run-time type information (and related methods). */ + itkTypeMacro(itkReg23, Object); + + using ChangeInformationFilterType = itk::ChangeInformationImageFilter; + using RoiForRegistration = itk::ImageRegion; + using InterpolatorType = itk::gSiddonJacobsRayCastInterpolateImageFunction; + + /* ---- User provided */ + + itkSetMacro(OptimizerObserver, CommandIterationUpdate::Pointer); + itkGetMacro(OptimizerObserver, CommandIterationUpdate::Pointer); + + itkSetMacro(r23Meta, R23MetaInformation::Pointer); + itkGetMacro(r23Meta, R23MetaInformation::Pointer); + + itkSetMacro(Volume, InternalImageType::Pointer); + itkGetMacro(Volume, InternalImageType::Pointer); + + itkSetMacro(PA, InternalImageType::Pointer); + itkGetMacro(PA, InternalImageType::Pointer); + + itkSetMacro(LAT, InternalImageType::Pointer); + itkGetMacro(LAT, InternalImageType::Pointer); + + itkSetMacro(InternalTransf1, InternalTransformMetaInformation::Pointer); + itkGetMacro(InternalTransf1, InternalTransformMetaInformation::Pointer); + + itkSetMacro(InternalTransf2, InternalTransformMetaInformation::Pointer); + itkGetMacro(InternalTransf2, InternalTransformMetaInformation::Pointer); + + itkSetMacro(filter1, ChangeInformationFilterType::Pointer); + itkGetMacro(filter1, ChangeInformationFilterType::Pointer); + + itkSetMacro(filter2, ChangeInformationFilterType::Pointer); + itkGetMacro(filter2, ChangeInformationFilterType::Pointer); + + itkSetMacro(interpolator1, InterpolatorType::Pointer); + itkGetMacro(interpolator1, InterpolatorType::Pointer); + + itkSetMacro(interpolator2, InterpolatorType::Pointer); + itkGetMacro(interpolator2, InterpolatorType::Pointer); + + itkSetMacro(TransformMetaInfo, TransformMetaInformation::Pointer); + itkGetMacro(TransformMetaInfo, TransformMetaInformation::Pointer); + + /* ---- User provided END */ + itkSetMacro(roiAutoReg1, RoiForRegistration); + itkGetMacro(roiAutoReg1, RoiForRegistration); + + itkSetMacro(roiAutoReg2, RoiForRegistration); + itkGetMacro(roiAutoReg2, RoiForRegistration); + + + + /** Auto Reg23 methods */ + + /** Initialize the registration pipeline*/ + void InitializeRegistration(double stepLength, + double maxTranslation, + eDegreeOfFreedomType dof); + /** Start the registration process*/ + int StartRegistration(std::string extraInfo); + /** Get the current cost function value from the optimizer*/ + double GetOptimizerValue(); + + /** Get the cost function value for the current transform*/ + double GetCurrentMetricValue(); + + /** Get the cost function value for the current transform*/ + Optimizer::ParametersType GetCurrentPosition(); + + /** Auto Reg23 methods END */ + +protected: + itkReg23(); + virtual ~itkReg23(); + void PrintSelf(std::ostream& os, itk::Indent indent) const; + + +private: + itkReg23(const Self&); //purposely not implemented + void operator=(const Self&); //purposely not implemented + + /** Optimizer which tries to find the minimun (Powell Optimizer)*/ + using PowellOptimizerType = itk::PowellOptimizer; + /** Optimizer which tries to find the minimn (Powell Optimizer)*/ + using AmoebaOptimizerType = itk::AmoebaOptimizer; + /** Optimizer which samples the whol space */ + using ExhaustiveOptimizerType = itk::ExhaustiveOptimizer; + /** Metric to calculate similarites between images*/ + using MetricType = itk::NormalizedCorrelationTwoImageToOneImageMetric; + using MIMetricType = itk::MutualInformationTwoImageToOneImageMetric; + /** The thing which actuall does the image registration*/ + using RegistrationType = itk::TwoProjectionImageRegistrationMethod; + + + + RegistrationType::Pointer + registration; + MetricType::Pointer + NCCmetric; + MIMetricType::Pointer + MImetric; + PowellOptimizerType::Pointer + PowellOptimizer; + AmoebaOptimizerType::Pointer + AmoebaOptimizer; + ExhaustiveOptimizerType::Pointer + ExhaustiveOptimizer; + + /* ---- User provided */ + R23MetaInformation::Pointer + m_r23Meta; + + InternalImageType::Pointer + m_Volume, + m_PA, + m_LAT; + + InternalTransformMetaInformation::Pointer + m_InternalTransf1, + m_InternalTransf2; + + ChangeInformationFilterType::Pointer + m_filter1, + m_filter2; + + InterpolatorType::Pointer + m_interpolator1, + m_interpolator2; + + TransformMetaInformation::Pointer + m_TransformMetaInfo; + + CommandIterationUpdate::Pointer + m_OptimizerObserver; + + /* ---- User provided END */ + + + TransformType::Pointer + IsocTransform, + Transform1, + Transform2; + + RoiForRegistration + m_roiAutoReg1, + m_roiAutoReg2; + + bool m_UseDumptoFile; + + + double m_OptmizerValue; + + +}; + +} + +#endif From 47fe531aaea4f7aeb28f85c0ba7293cae877ac7b Mon Sep 17 00:00:00 2001 From: Proton local user Date: Fri, 19 May 2023 23:40:46 +0200 Subject: [PATCH 49/49] R23 ROI Fixed and initial on LUT - Fixed bug in ROI itkRegion definition, missing division by spacing - Consistent results using Small (1mm) or Large (2mm) FoV - Some initial work on LUT, to polish... --- ...zedCorrelationTwoImageToOneImageMetric.hxx | 14 +- .../autoreg/itkgTwoImageToOneImageMetric.hxx | 6 + .../itkDTRrecon/itkImageProcessor.cpp | 150 ++++++++---------- reg23Topograms/itkDTRrecon/itkReg23.cpp | 8 - 4 files changed, 76 insertions(+), 102 deletions(-) diff --git a/reg23Topograms/itkDTRrecon/autoreg/itkNormalizedCorrelationTwoImageToOneImageMetric.hxx b/reg23Topograms/itkDTRrecon/autoreg/itkNormalizedCorrelationTwoImageToOneImageMetric.hxx index cd14a02..f88d034 100644 --- a/reg23Topograms/itkDTRrecon/autoreg/itkNormalizedCorrelationTwoImageToOneImageMetric.hxx +++ b/reg23Topograms/itkDTRrecon/autoreg/itkNormalizedCorrelationTwoImageToOneImageMetric.hxx @@ -188,15 +188,6 @@ NormalizedCorrelationTwoImageToOneImageMetric::Calcul ++ti; } - // sfm = sfm - m_meanCurr_f * sm - m_meanCurr_m * sf + this->m_NumberOfPixelsCounted * m_meanCurr_m * m_meanCurr_f; - // const RealType denom = -1 * sqrt(m_varianceCurr_f * m_varianceCurr_m) * this->m_NumberOfPixelsCounted; - - // if (this->m_NumberOfPixelsCounted > 0 && denom != 0.0) { - // measure = sfm / denom; - // } else { - // measure = NumericTraits::ZeroValue(); - // } - if (this->m_SubtractMean && this->m_NumberOfPixelsCounted > 0) { sff -= (sf * sf / this->m_NumberOfPixelsCounted); smm -= (sm * sm / this->m_NumberOfPixelsCounted); @@ -273,6 +264,11 @@ NormalizedCorrelationTwoImageToOneImageMetric::GetVal // Calculate the measure value between fixed image 1 and the moving image auto oldprecision = std::cout.precision(); + +// std::cout<<"Region " <GetFixedImageRegion1() <GetFixedImage1()->GetBufferedRegion() <m_Filter1->GetOutput()->GetBufferedRegion() <::digits10 + 2); // std::cout << "Measure1: " << measure1 << " Counts: " << this->m_NumberOfPixelsCounted << std::endl; diff --git a/reg23Topograms/itkDTRrecon/autoreg/itkgTwoImageToOneImageMetric.hxx b/reg23Topograms/itkDTRrecon/autoreg/itkgTwoImageToOneImageMetric.hxx index 770ba54..46a0b0f 100644 --- a/reg23Topograms/itkDTRrecon/autoreg/itkgTwoImageToOneImageMetric.hxx +++ b/reg23Topograms/itkDTRrecon/autoreg/itkgTwoImageToOneImageMetric.hxx @@ -250,6 +250,12 @@ void gTwoImageToOneImageMetric::Initialize() m_FixedImage2->GetSource()->Update(); } + //std::cout<<"FixedImageRegion1 " <GetFixedImageRegion1() <m_FixedImage1->GetBufferedRegion() <m_Filter1->GetOutput()->GetBufferedRegion() <GetFixedImage1()->GetBufferedRegion() <m_Filter1->GetOutput()->GetBufferedRegion() <GetBufferedRegion())) { itkExceptionMacro(<< "FixedImageRegion1 does not overlap the fixed image buffered region"); diff --git a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp index 030e36d..35f6aad 100644 --- a/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp +++ b/reg23Topograms/itkDTRrecon/itkImageProcessor.cpp @@ -1968,44 +1968,45 @@ vtkImageData* itkImageProcessor::GetLocalizer1VTK() toVTKLocalizer1->SetInput(rescaler1->GetOutput()); toVTKLocalizer1->Update(); - if(false) { - using ImageRegionType3D = ImageType3D::RegionType; - using SizeType3D = ImageRegionType3D::SizeType; - using ImageDirectionType3D = ImageType3D::DirectionType; +// if(false) { +//// using ImageRegionType3D = ImageType3D::RegionType; +//// using SizeType3D = ImageRegionType3D::SizeType; +//// using ImageDirectionType3D = ImageType3D::DirectionType; - ImageRegionType3D region3D = rescaler1->GetOutput()->GetBufferedRegion(); - SizeType3D size3D = region3D.GetSize(); - ImageType3D::PointType origin3D = rescaler1->GetOutput()->GetOrigin(); - const itk::Vector resolution3D = rescaler1->GetOutput()->GetSpacing(); - ImageDirectionType3D imagDirection = rescaler1->GetOutput()->GetDirection(); +//// ImageRegionType3D region3D = rescaler1->GetOutput()->GetBufferedRegion(); +//// SizeType3D size3D = region3D.GetSize(); +//// //ImageType3D::PointType origin3D = rescaler1->GetOutput()->GetOrigin(); +//// const itk::Vector resolution3D = rescaler1->GetOutput()->GetSpacing(); +//// ImageDirectionType3D imagDirection = rescaler1->GetOutput()->GetDirection(); - /* calculate image size in 3D Space */ - using VectorType = itk::Vector; - VectorType Dest; - Dest[0]=(size3D[0]-1) * resolution3D[0]; - Dest[1]=(size3D[1]-1) * resolution3D[1]; - Dest[2]=(size3D[2]-1) * resolution3D[2]; +//// /* calculate image size in 3D Space */ +//// using VectorType = itk::Vector; +//// VectorType Dest; +//// Dest[0]=(size3D[0]-1) * resolution3D[0]; +//// Dest[1]=(size3D[1]-1) * resolution3D[1]; +//// Dest[2]=(size3D[2]-1) * resolution3D[2]; - ImageType3D::PointType LastVoxelPosition = - origin3D + (imagDirection * Dest); - // std::cout<<" -------- Localizer 1 ITK --------"<GetOutput()->GetBounds(); +// // double* dBounds = toVTKLocalizer1->GetOutput()->GetBounds(); - // std::cout<< "-------- Localizer 1 VTK --------" <GetOutput(); @@ -2030,42 +2031,42 @@ vtkImageData* itkImageProcessor::GetLocalizer2VTK() - if(true) { - using ImageRegionType3D = ImageType3D::RegionType; - using SizeType3D = ImageRegionType3D::SizeType; - using ImageDirectionType3D = ImageType3D::DirectionType; +// if(true) { +// using ImageRegionType3D = ImageType3D::RegionType; +// using SizeType3D = ImageRegionType3D::SizeType; +// using ImageDirectionType3D = ImageType3D::DirectionType; - ImageRegionType3D region3D = rescaler2->GetOutput()->GetBufferedRegion(); - SizeType3D size3D = region3D.GetSize(); - ImageType3D::PointType origin3D = rescaler2->GetOutput()->GetOrigin(); - const itk::Vector resolution3D = rescaler2->GetOutput()->GetSpacing(); - ImageDirectionType3D imagDirection = rescaler2->GetOutput()->GetDirection(); +// ImageRegionType3D region3D = rescaler2->GetOutput()->GetBufferedRegion(); +// SizeType3D size3D = region3D.GetSize(); +// ImageType3D::PointType origin3D = rescaler2->GetOutput()->GetOrigin(); +// const itk::Vector resolution3D = rescaler2->GetOutput()->GetSpacing(); +// ImageDirectionType3D imagDirection = rescaler2->GetOutput()->GetDirection(); - /* calculate image size in 3D Space */ - using VectorType = itk::Vector; - VectorType Dest; - Dest[0]=(size3D[0]-1) * resolution3D[0]; - Dest[1]=(size3D[1]-1) * resolution3D[1]; - Dest[2]=(size3D[2]-1) * resolution3D[2]; +// /* calculate image size in 3D Space */ +// using VectorType = itk::Vector; +// VectorType Dest; +// Dest[0]=(size3D[0]-1) * resolution3D[0]; +// Dest[1]=(size3D[1]-1) * resolution3D[1]; +// Dest[2]=(size3D[2]-1) * resolution3D[2]; - ImageType3D::PointType LastVoxelPosition = - origin3D + (imagDirection * Dest); +// ImageType3D::PointType LastVoxelPosition = +// origin3D + (imagDirection * Dest); - // std::cout<<" -------- Localizer 2 ITK --------"<GetOutput()->GetBounds(); - // std::cout<< "-------- Localizer 2 VTK --------" <GetOutput()->GetBounds(); +// // std::cout<< "-------- Localizer 2 VTK --------" <GetComposedTransform()->Print(std::cout); - // std::cout<< "Inverse " <GetInverseTransform()->Print(std::cout); - m_Projection1VTKTransform->Identity(); for(int iIdx = 0; iIdx<3 ; iIdx++){ @@ -2398,22 +2394,6 @@ itkImageProcessor::GetCompleteIsocentricTransform return nullptr; } -// std::cout<<" --- GetCompleteIsocentricTransform --- "<GetR()[0] <<" "<< -// m_TransformMetaInfo->GetR()[1] <<" "<< -// m_TransformMetaInfo->GetR()[2] <<" "<GetT()[0] <<" "<< -// m_TransformMetaInfo->GetT()[1] <<" "<< -// m_TransformMetaInfo->GetT()[2] <<" "<GetImportOffset()[0]<<" "<< -// m_CTMetaInfo->GetImportOffset()[1]<<" "<< -// m_CTMetaInfo->GetImportOffset()[2]<<" "<GetLPS2IECDirections() * m_RTMetaInfo->GetIsocenterLPS(); @@ -2465,8 +2445,8 @@ void itkImageProcessor::SetRegionFixed1( roiAutoReg1.SetIndex(index1); roiAutoReg1.SetSize(size1); - std::cout << "itkImageProcessor " << std::endl; - std::cout << roiAutoReg1 << std::endl; + //std::cout << "itkImageProcessor " << std::endl; + //std::cout << roiAutoReg1 << std::endl; this->m_R23->SetroiAutoReg1(roiAutoReg1); @@ -2490,8 +2470,8 @@ void itkImageProcessor::SetRegionFixed2( roiAutoReg2.SetIndex(index2); roiAutoReg2.SetSize(size2); - std::cout << "itkImageProcessor " << std::endl; - std::cout << roiAutoReg2 << std::endl; + //std::cout << "itkImageProcessor " << std::endl; + //std::cout << roiAutoReg2 << std::endl; this->m_R23->SetroiAutoReg2(roiAutoReg2); diff --git a/reg23Topograms/itkDTRrecon/itkReg23.cpp b/reg23Topograms/itkDTRrecon/itkReg23.cpp index 4f1c903..e599807 100644 --- a/reg23Topograms/itkDTRrecon/itkReg23.cpp +++ b/reg23Topograms/itkDTRrecon/itkReg23.cpp @@ -210,9 +210,6 @@ void itkReg23::InitializeRegistration( registration->SetFixedImageRegion1(m_roiAutoReg1); registration->SetFixedImageRegion2(m_roiAutoReg2); - std::cout<< "Using Region1:"<SetTransformMetaInfo(m_r23Meta); @@ -391,11 +388,6 @@ double itkReg23::GetCurrentMetricValue() } -//void itkReg23::SetFullROI(bool fullROI) -//{ -// m_UseFullROI = fullROI; -// // TODO: Remove this function when ROI functinalitz has been implemented. -//} }