Skip to content

Commit

Permalink
Merge pull request #171 from ANTsX/HessianObjectness
Browse files Browse the repository at this point in the history
WIP:  Add hessian objectness interface to itk filter.
  • Loading branch information
ntustison authored Jul 14, 2024
2 parents c60cc89 + 17d95cc commit 9d6a762
Show file tree
Hide file tree
Showing 3 changed files with 183 additions and 0 deletions.
4 changes: 4 additions & 0 deletions R/RcppExports.R
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down
157 changes: 157 additions & 0 deletions src/HessianObjectness.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
#include <exception>
#include <vector>
#include <string>
#include <algorithm>
#include <ants.h>
#include "antsUtilities.h"
#include "ReadWriteData.h"

#include "itkHessianToObjectnessMeasureImageFilter.h"
#include "itkMultiScaleHessianBasedMeasureImageFilter.h"
#include "itkSymmetricSecondRankTensor.h"
#include "itkNumericTraits.h"

#include "RcppANTsR.h"


template<class PrecisionType, unsigned int Dimension>
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<PrecisionType, Dimension>;
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<PixelType>::RealType;

using HessianPixelType = itk::SymmetricSecondRankTensor<RealPixelType, ImageDimension>;
using HessianImageType = itk::Image<HessianPixelType, ImageDimension>;
using ObjectnessFilterType = itk::HessianToObjectnessMeasureImageFilter<HessianImageType, ImageType>;
using MultiScaleEnhancementFilterType = itk::MultiScaleHessianBasedMeasureImageFilter<ImageType, HessianImageType, ImageType>;

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<int>( inputImage.slot( "dimension" ) );
std::string pixelType = Rcpp::as<std::string>( inputImage.slot( "pixeltype" ) );

unsigned int objectDimension = Rcpp::as<int>( r_objectDimension );
bool isBrightObject = Rcpp::as<bool>( r_isBrightObject );
float sigmaMin = Rcpp::as<float>( r_sigmaMin );
float sigmaMax = Rcpp::as<float>( r_sigmaMax );
unsigned int numberOfSigmaSteps = Rcpp::as<int>( r_numberOfSigmaSteps );
bool useSigmaLogarithmicSpacing = Rcpp::as<bool>( r_useSigmaLogarithmicSpacing );
float alpha = Rcpp::as<float>( r_alpha );
float beta = Rcpp::as<float>( r_beta );
float gamma = Rcpp::as<float>( r_gamma );
bool setScaleObjectnessMeasure = Rcpp::as<bool>( r_setScaleObjectnessMeasure );

if( pixelType.compare( "float" ) == 0 && imageDimension == 2 )
{
typedef float PrecisionType;
const unsigned int ImageDimension = 2;

outputImage = HessianObjectnessHelper<PrecisionType, ImageDimension>(
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<PrecisionType, ImageDimension>(
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
}
22 changes: 22 additions & 0 deletions src/RcppExports.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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},
Expand Down

0 comments on commit 9d6a762

Please sign in to comment.