diff --git a/R/RcppExports.R b/R/RcppExports.R index 2358f99..63766a7 100644 --- a/R/RcppExports.R +++ b/R/RcppExports.R @@ -46,6 +46,10 @@ HausdorffDistanceR <- function(r_inputImage1, r_inputImage2) { .Call(`_ANTsRCore_HausdorffDistanceR`, r_inputImage1, r_inputImage2) } +hessianObjectnessR <- function(r_inputImage, r_objectDimension, r_isBrightObject, r_sigmaMin, r_sigmaMax, r_numberOfSigmaSteps, r_useSigmaLogarithmicSpacing, r_alpha, r_beta, r_gamma, r_setScaleObjectnessMeasure) { + .Call(`_ANTsRCore_hessianObjectnessR`, r_inputImage, r_objectDimension, r_isBrightObject, r_sigmaMin, r_sigmaMax, r_numberOfSigmaSteps, r_useSigmaLogarithmicSpacing, r_alpha, r_beta, r_gamma, r_setScaleObjectnessMeasure) +} + histogramMatchImageR <- function(r_sourceImage, r_referenceImage, r_numberOfHistogramBins, r_numberOfMatchPoints, r_useThresholdAtMeanIntensity) { .Call(`_ANTsRCore_histogramMatchImageR`, r_sourceImage, r_referenceImage, r_numberOfHistogramBins, r_numberOfMatchPoints, r_useThresholdAtMeanIntensity) } diff --git a/src/HessianObjectness.cpp b/src/HessianObjectness.cpp new file mode 100644 index 0000000..2a675f3 --- /dev/null +++ b/src/HessianObjectness.cpp @@ -0,0 +1,157 @@ +#include +#include +#include +#include +#include +#include "antsUtilities.h" +#include "ReadWriteData.h" + +#include "itkHessianToObjectnessMeasureImageFilter.h" +#include "itkMultiScaleHessianBasedMeasureImageFilter.h" +#include "itkSymmetricSecondRankTensor.h" +#include "itkNumericTraits.h" + +#include "RcppANTsR.h" + + +template +SEXP HessianObjectnessHelper( + SEXP r_inputImage, + SEXP r_outputImage, + unsigned int objectDimension, + bool isBrightObject, + float sigmaMin, + float sigmaMax, + unsigned int numberOfSigmaSteps, + bool useSigmaLogarithmicSpacing, + float alpha, + float beta, + float gamma, + bool setScaleObjectnessMeasure ) +{ + + using ImageType = itk::Image; + using ImagePointerType = typename ImageType::Pointer; + + typename ImageType::Pointer inputImage = Rcpp::as< ImagePointerType >( r_inputImage ); + typename ImageType::Pointer outputImage = Rcpp::as< ImagePointerType >( r_outputImage ); + + using PixelType = typename ImageType::PixelType; + const unsigned int ImageDimension = ImageType::ImageDimension; + using RealPixelType = typename itk::NumericTraits::RealType; + + using HessianPixelType = itk::SymmetricSecondRankTensor; + using HessianImageType = itk::Image; + using ObjectnessFilterType = itk::HessianToObjectnessMeasureImageFilter; + using MultiScaleEnhancementFilterType = itk::MultiScaleHessianBasedMeasureImageFilter; + + typename ObjectnessFilterType::Pointer objectnessFilter = ObjectnessFilterType::New(); + objectnessFilter->SetScaleObjectnessMeasure( setScaleObjectnessMeasure ); + objectnessFilter->SetBrightObject( isBrightObject ); + objectnessFilter->SetAlpha( alpha ); + objectnessFilter->SetBeta( beta ); + objectnessFilter->SetGamma( gamma ); + objectnessFilter->SetObjectDimension( objectDimension ); + + typename MultiScaleEnhancementFilterType::Pointer multiScaleEnhancementFilter = MultiScaleEnhancementFilterType::New(); + multiScaleEnhancementFilter->SetInput( inputImage ); + if( useSigmaLogarithmicSpacing ) + { + multiScaleEnhancementFilter->SetSigmaStepMethodToLogarithmic(); + } + else + { + multiScaleEnhancementFilter->SetSigmaStepMethodToEquispaced(); + } + multiScaleEnhancementFilter->SetSigmaMinimum( sigmaMin ); + multiScaleEnhancementFilter->SetSigmaMaximum( sigmaMax ); + multiScaleEnhancementFilter->SetNumberOfSigmaSteps( numberOfSigmaSteps ); + multiScaleEnhancementFilter->SetHessianToMeasureFilter( objectnessFilter ); + multiScaleEnhancementFilter->Update(); + + outputImage = multiScaleEnhancementFilter->GetOutput(); + outputImage->Update(); + outputImage->DisconnectPipeline(); + + r_outputImage = Rcpp::wrap( outputImage ); + return( r_outputImage ); +} + +// [[Rcpp::export]] +SEXP hessianObjectnessR( + SEXP r_inputImage, + SEXP r_objectDimension, + SEXP r_isBrightObject, + SEXP r_sigmaMin, + SEXP r_sigmaMax, + SEXP r_numberOfSigmaSteps, + SEXP r_useSigmaLogarithmicSpacing, + SEXP r_alpha, + SEXP r_beta, + SEXP r_gamma, + SEXP r_setScaleObjectnessMeasure ) +{ +try + { + Rcpp::S4 inputImage( r_inputImage ); + Rcpp::S4 s4_outputImage( r_inputImage ); + SEXP outputImage; + + unsigned int imageDimension = Rcpp::as( inputImage.slot( "dimension" ) ); + std::string pixelType = Rcpp::as( inputImage.slot( "pixeltype" ) ); + + unsigned int objectDimension = Rcpp::as( r_objectDimension ); + bool isBrightObject = Rcpp::as( r_isBrightObject ); + float sigmaMin = Rcpp::as( r_sigmaMin ); + float sigmaMax = Rcpp::as( r_sigmaMax ); + unsigned int numberOfSigmaSteps = Rcpp::as( r_numberOfSigmaSteps ); + bool useSigmaLogarithmicSpacing = Rcpp::as( r_useSigmaLogarithmicSpacing ); + float alpha = Rcpp::as( r_alpha ); + float beta = Rcpp::as( r_beta ); + float gamma = Rcpp::as( r_gamma ); + bool setScaleObjectnessMeasure = Rcpp::as( r_setScaleObjectnessMeasure ); + + if( pixelType.compare( "float" ) == 0 && imageDimension == 2 ) + { + typedef float PrecisionType; + const unsigned int ImageDimension = 2; + + outputImage = HessianObjectnessHelper( + inputImage, s4_outputImage, objectDimension, isBrightObject, sigmaMin, + sigmaMax, numberOfSigmaSteps, useSigmaLogarithmicSpacing, alpha, + beta, gamma, setScaleObjectnessMeasure ); + return( outputImage ); + } + else if( pixelType.compare( "float" ) == 0 && imageDimension == 3 ) + { + typedef float PrecisionType; + const unsigned int ImageDimension = 3; + + outputImage = HessianObjectnessHelper( + inputImage, s4_outputImage, objectDimension, isBrightObject, sigmaMin, + sigmaMax, numberOfSigmaSteps, useSigmaLogarithmicSpacing, alpha, + beta, gamma, setScaleObjectnessMeasure ); + } + else + { + Rcpp::stop( "Unsupported image dimension or pixeltype." ); + } + } + +catch( itk::ExceptionObject & err ) + { + Rcpp::Rcout << "ITK ExceptionObject caught!" << std::endl; + forward_exception_to_r( err ); + } +catch( const std::exception& exc ) + { + Rcpp::Rcout << "STD ExceptionObject caught!" << std::endl; + forward_exception_to_r( exc ); + } +catch( ... ) + { + Rcpp::stop( "C++ exception (unknown reason)" ); + } + +return Rcpp::wrap( NA_REAL ); // should not be reached +} diff --git a/src/RcppExports.cpp b/src/RcppExports.cpp index 2366197..9cf0a89 100644 --- a/src/RcppExports.cpp +++ b/src/RcppExports.cpp @@ -150,6 +150,27 @@ BEGIN_RCPP return rcpp_result_gen; END_RCPP } +// hessianObjectnessR +SEXP hessianObjectnessR(SEXP r_inputImage, SEXP r_objectDimension, SEXP r_isBrightObject, SEXP r_sigmaMin, SEXP r_sigmaMax, SEXP r_numberOfSigmaSteps, SEXP r_useSigmaLogarithmicSpacing, SEXP r_alpha, SEXP r_beta, SEXP r_gamma, SEXP r_setScaleObjectnessMeasure); +RcppExport SEXP _ANTsRCore_hessianObjectnessR(SEXP r_inputImageSEXP, SEXP r_objectDimensionSEXP, SEXP r_isBrightObjectSEXP, SEXP r_sigmaMinSEXP, SEXP r_sigmaMaxSEXP, SEXP r_numberOfSigmaStepsSEXP, SEXP r_useSigmaLogarithmicSpacingSEXP, SEXP r_alphaSEXP, SEXP r_betaSEXP, SEXP r_gammaSEXP, SEXP r_setScaleObjectnessMeasureSEXP) { +BEGIN_RCPP + Rcpp::RObject rcpp_result_gen; + Rcpp::RNGScope rcpp_rngScope_gen; + Rcpp::traits::input_parameter< SEXP >::type r_inputImage(r_inputImageSEXP); + Rcpp::traits::input_parameter< SEXP >::type r_objectDimension(r_objectDimensionSEXP); + Rcpp::traits::input_parameter< SEXP >::type r_isBrightObject(r_isBrightObjectSEXP); + Rcpp::traits::input_parameter< SEXP >::type r_sigmaMin(r_sigmaMinSEXP); + Rcpp::traits::input_parameter< SEXP >::type r_sigmaMax(r_sigmaMaxSEXP); + Rcpp::traits::input_parameter< SEXP >::type r_numberOfSigmaSteps(r_numberOfSigmaStepsSEXP); + Rcpp::traits::input_parameter< SEXP >::type r_useSigmaLogarithmicSpacing(r_useSigmaLogarithmicSpacingSEXP); + Rcpp::traits::input_parameter< SEXP >::type r_alpha(r_alphaSEXP); + Rcpp::traits::input_parameter< SEXP >::type r_beta(r_betaSEXP); + Rcpp::traits::input_parameter< SEXP >::type r_gamma(r_gammaSEXP); + Rcpp::traits::input_parameter< SEXP >::type r_setScaleObjectnessMeasure(r_setScaleObjectnessMeasureSEXP); + rcpp_result_gen = Rcpp::wrap(hessianObjectnessR(r_inputImage, r_objectDimension, r_isBrightObject, r_sigmaMin, r_sigmaMax, r_numberOfSigmaSteps, r_useSigmaLogarithmicSpacing, r_alpha, r_beta, r_gamma, r_setScaleObjectnessMeasure)); + return rcpp_result_gen; +END_RCPP +} // histogramMatchImageR SEXP histogramMatchImageR(SEXP r_sourceImage, SEXP r_referenceImage, SEXP r_numberOfHistogramBins, SEXP r_numberOfMatchPoints, SEXP r_useThresholdAtMeanIntensity); RcppExport SEXP _ANTsRCore_histogramMatchImageR(SEXP r_sourceImageSEXP, SEXP r_referenceImageSEXP, SEXP r_numberOfHistogramBinsSEXP, SEXP r_numberOfMatchPointsSEXP, SEXP r_useThresholdAtMeanIntensitySEXP) { @@ -1714,6 +1735,7 @@ static const R_CallMethodDef CallEntries[] = { {"_ANTsRCore_fitBsplineObjectToScatteredDataR", (DL_FUNC) &_ANTsRCore_fitBsplineObjectToScatteredDataR, 10}, {"_ANTsRCore_fitThinPlateSplineDisplacementFieldR", (DL_FUNC) &_ANTsRCore_fitThinPlateSplineDisplacementFieldR, 7}, {"_ANTsRCore_HausdorffDistanceR", (DL_FUNC) &_ANTsRCore_HausdorffDistanceR, 2}, + {"_ANTsRCore_hessianObjectnessR", (DL_FUNC) &_ANTsRCore_hessianObjectnessR, 11}, {"_ANTsRCore_histogramMatchImageR", (DL_FUNC) &_ANTsRCore_histogramMatchImageR, 5}, {"_ANTsRCore_integrateVelocityFieldR", (DL_FUNC) &_ANTsRCore_integrateVelocityFieldR, 5}, {"_ANTsRCore_invertDisplacementFieldR", (DL_FUNC) &_ANTsRCore_invertDisplacementFieldR, 7},