ImageDev

- Getting Started
- ImageDev Python
- ImageDev C#
- ImageDev C++
- Licensing Information
- Redistributable Files
- Processing
- Image Manipulation
- - Synthetic Images
  - - RandomImage2d
    - RandomImage3d
    - RandomGaussianImage2d
    - RandomGaussianImage3d
    - RadialFunctionImage2d
    - RadialFunctionImage3d
    - OrientedLinesImage2d
    - OrientedLinesImage3d
    - RandomSphereImage3d
    - BoxGridImage2d
    - BoxGridImage3d
    - WedgeMaskImage3d
    - PointSpreadFunctionImage3d
  - Image Editing
  - - ConvertImage
    - ResetImage
    - CopyImage
    - PasteImage2d
    - PasteImage3d
    - CropImage2d
    - CropImage3d
    - SampleImage2d
    - SampleImage3d
    - InterlaceFrames2d
    - DeinterlaceFrames2d
  - Stack Operations
  - - SequenceConcatenation
    - SequenceToMultispectral
    - SequenceToVolume
    - VolumeToSequence
    - MultispectralToSequence
    - GetSliceFromVolume3d
    - SetSliceToVolume3d
    - GetObliqueSliceFromVolume3d
    - ImageStackProjection3d
    - VolumeProjection3d
- Geometry And Matching
- - Geometric Transforms
  - - Shearing3d
    - TranslateImage2d
    - TranslateImage3d
    - Flip2d
    - Flip3d
    - FlipImage2d
    - FlipImage3d
    - TransposeImage2d
    - TransposeImage3d
    - SwapQuadrants
    - Rotate2d
    - Rotate3d
    - RotationGenerator3d
    - Resize2d
    - Resize3d
    - RescaleByFactor
    - RescaleImageByFactor
    - ResampleAffine2d
    - ResampleAffine3d
    - ResampleElastic2d
    - SurfaceUnfolding3d
  - Pattern Recognition
  - - BinaryCorrelation2d
    - CrossCorrelation2d
    - CorrelationByDifference2d
    - CorrelationBySignChange2d
  - Registration
  - - ImagePrealignment3d
    - AffineRegistration
    - ElasticRegistration2d
- Arithmetic And Logic
- - Arithmetical Operations
  - - AbsoluteValue
    - AbsoluteMaximumWithImage
    - ArithmeticOperationWithImage
    - ArithmeticOperationWithValue
    - BlendWithImage
    - BlendWithValue
    - DirectionalBlending2d
    - CombineByMask
    - ImageFormula
    - EigenDecomposition2d
    - EigenDecomposition3d
  - Logical Operations
  - - MaskImage
    - LogicalOperationWithImage
    - LogicalOperationWithValue
    - LogicalNot
    - InvertImage
    - BitShift
- Image Filtering
- - Grayscale Transforms
  - - RescaleIntensity
    - StackRescaleIntensity
    - MatchContrast
    - HistogramEqualization
    - Clahe2d
    - Clahe3d
    - AdaptiveHistogramEqualization
    - ApplyGrayscaleLut
    - BackgroundImage2d
    - RadialBackgroundImage2d
    - ShadingCorrection
    - Exponential
    - Logarithm
    - Square
    - SquareRoot
    - RingArtifactRemoval3d
    - BeamHardeningCorrection3d
  - Color Transforms
  - - ColorToLightness
    - GetColorChannel
    - ColorToGrayscale
    - GrayscaleToColor
    - ColorSpaceConversion
    - ColorAntialiasing2d
    - BayerToRgb2d
    - DecorrelationStretch2d
    - BlendAlphaChannelWithImage
    - BlendAlphaChannelWithValue
  - Smoothing And Denoising
  - - BoxFilter2d
    - BoxFilter3d
    - MedianFilter2d
    - MedianFilter3d
    - GaussianFilter2d
    - GaussianFilter3d
    - ExponentialFilter2d
    - RecursiveExponentialFilter2d
    - RecursiveExponentialFilter3d
    - NonLocalMeansFilter2d
    - NonLocalMeansFilter3d
    - CurvatureDrivenDiffusion
    - BilateralFilter2d
    - BilateralFilter3d
    - MajorityFilter2d
    - MajorityFilter3d
    - SigmaFilter2d
    - SigmaFilter3d
    - Despeckle2d
    - Despeckle3d
    - NagaoFilter2d
    - NagaoFilter3d
    - SnnFilter2d
    - SnnFilter3d
    - FlowInpainting
  - Sharpening
  - - Deblurring2d
    - Delineate2d
    - Delineate3d
    - UnsharpMasking2d
    - UnsharpMasking3d
    - Shade2d
    - RichardsonLucyDeconvolution
  - Texture Filters
  - - MeanFilter2d
    - MeanFilter3d
    - VarianceFilter2d
    - VarianceFilter3d
    - SkewnessFilter2d
    - SkewnessFilter3d
    - KurtosisFilter2d
    - KurtosisFilter3d
    - ContrastFilter2d
    - ContrastFilter3d
    - VariationFilter2d
    - VariationFilter3d
    - EnergyFilter2d
    - EnergyFilter3d
    - EntropyFilter2d
    - EntropyFilter3d
    - AutocorrelationFilter
    - LocalAutocorrelationFilter2d
    - ImageCurvature2d
    - ImageCurvature3d
    - StructureEnhancementFilter2d
    - StructureEnhancementFilter3d
    - ScaleSpaceLogFilter2d
    - ScaleSpaceLogFilter3d
  - Frequency Domain
  - - ComplexFft
    - ComplexFftInverse
    - ComplexCenteredFft
    - ComplexCenteredFftInverse
    - CartesianToPolar2d
    - PolarToCartesian2d
    - ConvolutionWithImage
    - ConvolutionWithImage2d
    - RadialFrequencyFilter2d
    - GaborFiltering2d
- Edge Detection
- - Gradient
  - - GradientOperator2d
    - GradientOperator3d
    - VectorToMagnitude2d
    - VectorToMagnitude3d
    - GradientVector2d
    - GradientVector3d
    - GradientMagnitude2d
    - GradientMagnitude3d
    - MorphologicalGradient2d
    - MorphologicalGradient3d
    - RadialGradientCentered2d
    - RadialGradientCentered3d
    - RadialGradientContour2d
    - RadialGradientContour3d
    - RadialGradientLabel2d
    - RadialGradientLabel3d
  - Laplacian
  - - DobFilter2d
    - DobFilter3d
    - MorphologicalLaplacian
    - RecursiveLaplacian2d
    - RecursiveLaplacian3d
  - Other Derivatives
  - - GaussianDerivative2d
    - GaussianDerivative3d
    - GaussianHessianMatrix2d
    - GaussianHessianMatrix3d
    - GaussianGradientTensor2d
    - GaussianGradientTensor3d
  - Edge Marking
  - - ImageLocalMaxima2d
    - ImageLocalMaxima3d
    - RidgeDetection
    - ZeroCrossings2d
    - DijkstraShortestPath2d
    - EigenvaluesToStructureness2d
    - EigenvaluesToStructureness3d
    - TensorVoting2d
    - CannyEdgeDetector2d
    - CannyEdgeDetector3d
- Image Segmentation
- - Binarization
  - - Thresholding
    - ThresholdingByCriterion
    - AutoThresholdingBright
    - AutoThresholdingDark
    - ColorThresholding
    - TopHat
    - FeatureAdaptiveThresholding
    - AdaptiveThresholding2d
    - AdaptiveThresholding3d
    - HysteresisThresholding
  - Labeling
  - - Labeling2d
    - Labeling3d
    - ReorderLabels
    - AssignLabel
    - AddObjectToLabel
    - GroupCloseLabelsl2d
  - Feature Selection
  - - KillBorder2d
    - KillBorder3d
    - RemoveSmallSpots
    - ObjectBoundaries
    - BinarySmoothing2d
    - BinarySmoothing3d
    - LabelInterfaces
  - Separating And Filling
  - - FillHoles2d
    - FillHoles3d
    - RemoveSmallHoles
    - FillImageBorder3d
    - ExpandLabelBoundaries
    - SeparateObjects
    - HExtremaWatershed
    - SeparateObjectsByBlock
    - HExtremaWatershedByBlock
    - ConvexHull2d
  - Region Growing
  - - MarkerBasedWatershed2d
    - MarkerBasedWatershed3d
    - MarkerBasedWatershedByBlock
    - MarkerBasedWatershedBasinsByBlock
    - ExpandLabelsOnBackground
    - FloodFillThreshold2d
    - FloodFillThreshold3d
    - Waterpixel
  - Computational Geometry
  - - PolylineResampler2d
    - PolylineResampler3d
    - PolylineExtrusion3d
    - SurfaceFitting3d
- Mathematical Morphology
- - Erosion And Dilation
  - - Erosion2d
    - Erosion3d
    - Dilation2d
    - Dilation3d
    - ErosionDisk2d
    - ErosionDisk3d
    - ErosionBall3d
    - DilationDisk2d
    - DilationDisk3d
    - DilationBall3d
    - ErosionLine2d
    - ErosionLine3d
    - DilationLine2d
    - DilationLine3d
    - ErosionColor2d
    - DilationColor2d
    - SelectiveErosion2d
    - SelectiveErosion3d
    - SelectiveDilation2d
    - SelectiveDilation3d
  - Opening And Closing
  - - Opening2d
    - Opening3d
    - Closing2d
    - Closing3d
    - OpeningDisk2d
    - OpeningDisk3d
    - OpeningBall3d
    - ClosingDisk2d
    - ClosingDisk3d
    - ClosingBall3d
    - OpeningLine2d
    - OpeningLine3d
    - ClosingLine2d
    - ClosingLine3d
    - OpeningLineMaximum
    - ClosingLineMinimum
    - OpeningColor2d
    - ClosingColor2d
    - OpeningByReconstruction2d
    - OpeningByReconstruction3d
    - ClosingByReconstruction2d
    - ClosingByReconstruction3d
    - OpeningDiskByReconstruction2d
    - OpeningBallByReconstruction3d
    - ClosingDiskByReconstruction2d
    - ClosingBallByReconstruction3d
    - SelectiveOpening2d
    - SelectiveOpening3d
    - SelectiveClosing2d
    - SelectiveClosing3d
  - Hit Or Miss And Skeleton
  - - Skeleton
    - Centerline3d
    - InfluenceZones
    - Centroid2d
    - EndPoints2d
    - EndPoints3d
    - Pruning2d
    - Pruning3d
    - IsolatedPoints2d
    - IsolatedPoints3d
    - TriplePoints2d
    - InteriorPoints2d
    - ApplyMorphologicalLut2d
    - ApplyMorphologicalLut3d
  - Geodesic Transformations
  - - ReconstructionFromMarkers2d
    - ReconstructionFromMarkers3d
    - GrayscaleReconstruction2d
    - GrayscaleReconstruction3d
    - GrayscaleFillHoles2d
    - GrayscaleFillHoles3d
    - HExtrema2d
    - HExtrema3d
    - RegionalExtrema2d
    - RegionalExtrema3d
    - UltimateErosion
  - Distance Maps
  - - DistanceMap2d
    - DistanceMap3d
    - EuclideanDistanceMap3d
    - EuclideanDistanceMap2d
    - GeodesicDistanceMap
    - ClosestBoundaryPoints2d
    - ClosestBoundaryPoints3d
    - TimeMap
    - LocalThicknessMap3d
    - GeodesicPropagation2d
    - GeodesicMaxima
    - GeodesicMinima
- Image Analysis
- - Image Measurements
  - - BinaryAnalysis
    - Area2d
    - Area3d
    - IntensityIntegral2d
    - IntensityIntegral3d
    - ObjectCount
    - DistanceMean2d
    - EulerNumber2d
    - EulerNumber3d
    - FractalDimension
    - CurvatureIntegrals3d
  - Image Statistics
  - - IntensityExtrema
    - IntensityStatistics
    - IntensityMaskedStatistics
    - IntensityHistogram
    - IntensityBinHistogram
    - AutoThresholdingValue
    - CompareImage
    - CompareValue
    - SimilarityMetricValue
    - SsimValue2d
    - SsimValue3d
    - RegionSimilarity
    - RadialIntensityProfile2d
    - RadialIntensityProfile3d
    - CylindricalIntensityProfile3d
    - RadialAutocorrelationProfile
    - Cooccurrence2d
    - MeasureGaussianNoise
    - LocalMaxima2d
    - LocalMaxima3d
    - PeakExtractor
    - LocalDensityMap2d
    - LocalDensityMap3d
    - SegmentationMetrics
  - Individual Measurements
  - - VolumeFractionByLabel
    - LabelCountByRegion
    - VolumeFractionByRegion
    - LabelAnalysis
    - LabelFiltering
    - LabelFilteringAnalysis
    - FilterAnalysis
    - MeasurementToImage
    - FilterByMeasurement
    - SieveLabeling
  - Moments And Orientations
  - - MomentsOfInertia2d
    - MomentsOfInertia3d
    - InertiaMoment2d
    - Eccentricity2d
    - OrientationMapFourier3d
    - OrientationMatchingFourier3d
  - Morphometry
  - - ObjectVolume
    - TotalImageVolume
    - ObjectBoundaryArea
    - TotalImageBoundaryArea
    - AverageObjectAreaPerSlice3d
    - AverageObjectCountPerSlice3d
    - ObjectImageRatio
    - ObjectSpecificSurface
    - ObjectSurfaceDensity
    - PorosityPercentage3d
    - FragmentationIndex
    - StructureModelIndex3d
    - AverageObjectThickness3d
    - AverageSpaceThickness3d
    - ObjectLinearDensity3d
    - DegreeOfAnisotropy
  - Propagation
  - - AxisPropagationBinary3d
    - AxisPropagationBinaryWithSeeds3d
    - AxisPropagationLabel3d
    - AxisPropagationLabelWithSeeds3d
    - AxisPropagationDistance3d
    - EstimateShortestPath3d
    - PercolationThreshold3d
    - AxisConnectivity3d
    - CentroidPathTortuosity3d
- Machine Learning
- - Classification
  - - AutoSegmentation3Phases
    - AutoIntensityClassification
    - SupervisedTextureClassification2d
    - SupervisedTextureClassification3d
    - TextureClassificationCreate
    - TextureClassificationTrain
    - TextureClassificationApply
  - Deep learning
  - - OnnxPredictionFiltering2d
    - OnnxPredictionFiltering3d
    - OnnxPredictionSegmentation2d
    - OnnxPredictionSegmentation3d
    - OnnxPredictionTwoOutputs2d
    - OnnxPredictionTwoOutputs3d
- Business Application
- - Dental
  - - DentalWallSegmentation3d
    - DentalMeshExtraction3d
    - DentalUnfolding3d
- IO
- - Image Data
  - - ReadVipImage
    - WriteVipImage
  - Algebraic Data
  - - ReadArrayXd
    - ReadArrayXi64
    - WriteArrayXd
    - WriteArrayXi64
  - Model
  - - ReadOnnxModel
- CUDA
- - Geometry And Matching
  - - CudaCrossCorrelation2d
    - CudaTemplateMatching3d
  - Image Filtering
  - - CudaBoxFilter2d
    - CudaMedianFilter2d
    - CudaGaussianFilter3d
    - CudaAdaptiveManifoldNlmFilter
  - Mathematical Morphology
  - - CudaErosion2d
    - CudaDilation2d
    - CudaOpening2d
    - CudaClosing2d
- Utilities
- Initialization
- Processing
- Syntax Check
- Visualization
- Data Object
- Image Data
- Kernels
- - MorphologicalKernel2d
  - MorphologicalKernel3d
  - MorphologicalLut2d
  - MorphologicalLut3d
- Model
- - TextureClassificationModel
  - OnnxModel
- Global Measurements
- - Image Measurements
  - - Area2dMsr
    - Area3dMsr
    - IntensityIntegral2dMsr
    - IntensityIntegral3dMsr
    - ObjectCountMsr
    - DistanceMeanMsr
    - Euler2dMsr
    - Euler3dMsr
    - FractalMsr
    - CurvatureIntegralsMsr
  - Image Statistics
  - - IntensityExtremaMsr
    - StatisticsMsr
    - IntensityHistogramMsr
    - IntensityBinHistogramMsr
    - CompareMsr
    - SimilarityMetricValueMsr
    - SsimValueMsr
    - RegionSimilarityMsr
    - SegmentationMetricsObjectMsr
    - SegmentationMetricsImageMsr
    - CylindricalIntensityProfileMsr
    - RadialIntensityProfileMsr
    - CorrelationMsr
    - CoocurrrenceMsr
    - GaussianNoiseMsr
    - LocalMaximaMsr
    - PeakExtractorMsr
  - Individual Measurements
  - - VolumeFractionByLabelMsr
    - LabelCountByRegionMsr
    - VolumeFractionByRegionMsr
  - Moments And Orientations
  - - MomentsOfInertia2dMsr
    - MomentsOfInertia3dMsr
    - MeanInertiaMomentMsr
    - Eccentricity2dMsr
    - LocalOrientation3dMsr
  - Morphometry
  - - ObjectVolumeMsr
    - ImageVolumeMsr
    - ObjectBoundaryAreaMsr
    - ImageBoundaryAreaMsr
    - AverageObjectAreaPerSliceMsr
    - AverageObjectCountPerSliceMsr
    - ObjectImageRatioMsr
    - ObjectSpecificSurfaceMsr
    - ObjectSurfaceDensityMsr
    - PorosityPercentageMsr
    - FragmentationMsr
    - StructureModelIndexMsr
    - AverageObjectThicknessMsr
    - AverageSpaceThicknessMsr
    - ObjectLinearDensityMsr
    - AnisotropyDegreeMsr
  - Propagation
  - - AxisPropagationBinary3dMsr
    - AxisPropagationLabel3dMsr
    - AxisPropagationDistance3dMsr
    - PercolationThreshold3dMsr
    - CentroidTortuosity3dMsr
  - Geometry And Matching
  - - CrossCorrelation2dMsr
  - Edge Detection
  - - CannyEdgeDetectorMsr
  - Image Segmentation
  - - AutoThresholdingMsr
    - AutoSegmentation3PhasesMsr
  - Mathematical Morphology
  - - ApplyMorphologicalLutMsr
- Analysis Measurements
- - AnalysisMsr
  - Measurement
  - Native Measurements
  - - Geometry
    - Feret
    - Intensity
    - Histogram
    - Inertia
    - Locate
    - Segment
    - Cooccurrence
  - CustomMeasurement
  - MeasurementAttributes
  - - Quantile
    - Histogram
    - Feret2d
    - Feret3d
    - NeighborCount
    - Cooccurrence
    - Breadth3d
  - MeasurementGroup
- Measurement Information
- - FieldInformation
  - CustomMeasurementInfo
- CUDA
- - CudaContext
- User Guide
- First Steps
- - Hello ImageDev
  - Initialize ImageDev
- Image Management
- - Create 2D Image
  - Create 3D Image
  - Data Transfer
- Standard Processing
- - Denoising
  - Thresholding
- Image Analysis
- - Global Analysis
  - Label Analysis
  - Measurement Browsing
  - Measurement Group
  - Custom Analysis
- Advanced Processing
- - Algorithm Tracking
- Typical Use Cases
- - Particle Analysis
  - Pore Analysis

# Processing

This section introduces processing interaction functions.
Most of ImageDev algorithms frequently send messages to:

- Check if an algorithm needs to be interrupted before being completed.
- Indicate its current progression status.
- Notify a message indicating a relevant information (more rarely implemented).
- Notify data indicating a relevant information (more rarely implemented).

See related example

- AlgorithmTracking

Note: This example mainly shows how to use the verbose mode and how to intercept algorithm progression and messages. Other functions are illustrated at the end of this page.

## Syntax

Method | Description
--- | ---
void setVerbose(bool enable) | Sets default callbacks that print the name of which algorithm is starting and its execution time. enable: Enables callbacks if true, disables them otherwise.
bool getVerbose() | Returns True if the verbose mode is enabled, False otherwise.
void setCpuNumber(int cpuNumber) | Activates a user-defined number of logical processors to be used by ImageDev algorithms. Most of the ImageDev algorithms are CPU parallelized. However, if the computation time scales well with the CPU clock speed, it does not with the number of threads. Generally, using more than 8 threads is useless. For instance, a system with a 3.2 GHz, 8 threads processor configuration can run ImageDev algorithms faster than a system with 2.7 GHz and 32 threads. This phenomenon is easy to explain. When processing an image in parallel, each selected logical processor computes a result for an image block. Once two contiguous blocks are processed, a fusion step is necessary to merge the results of these blocks. This step may be more or less complex depending on several parameters, such as: The nature of the algorithm (point-wise operators require less fusion than fixed window filters, which require less fusion than propagation-based algorithms). The number of logical processors used (the higher it is, the longer the fusion step takes). The size of the blocks (this parameter is automatically managed by ImageDev). On systems having more than 8 logical processors, it may be interesting to monitor the influence of the number of logical processors used on the execution time of a given recipe. cpuNumber: The number of logical processors to be used. All processors are used if this value is lower than or equal to zero.
int getCpuNumber() | Returns the user-defined number of logical processors to be used by ImageDev algorithms. If the returned value is lower than or equal to zero, all processors are used.
void cudaInit() | Initialize the CUDA library to avoid wasting time at the first run of a CUDA algo. User can call this init when starting the application if he wants to propose CUDA features.
bool isCudaGpuAvailable() | Returns true if a CUDA GPU is available, false otherwise. Can be used in an application to set a trigger between a CUDA implementation and a CPU implementation.
void setProgressRatioCallback( ProgressRatioCallback progressRatioCallback ) | Sets the ratio callback used to track the progression of algorithms. progressRatioCallback: The progression ratio callback used to track the progression of algorithms. It must have two arguments: A GenericAlgorithm object, which represents the algorithm being executed. A float value representing the progression ratio between 0 and 1.
ProgressRatioCallback getProgressRatioCallback() | Returns a pointer or a reference to the ratio callback function if it has been defined, null or none otherwise.
void setProgressMessageCallback( ProgressMessageCallback progressMessageCallback ) | Sets the message callback used to be notified about generic messages sent by algorithms. progressMessageCallback: The progression message callback used to notify algorithm information. It must have two arguments: A GenericAlgorithm object, which represents the algorithm being executed. A string value representing the message sent by the algorithm.
ProgressMessageCallback getProgressMessageCallback() | Returns a pointer or a reference to the message callback function if it has been defined, null or none otherwise.
void setProgressDataCallback( ProgressDataCallback progressDataCallback ) | Sets the data callback used to be notified about formatted messages sent by algorithms. progressDataCallback: The progression data callback used to notify algorithm information. It must have two arguments: A GenericAlgorithm object, which represents the algorithm being executed. A string value representing data sent by the algorithm. A string value representing the encoding of data sent by the algorithm.
ProgressDataCallback getProgressDataCallback() | Returns a pointer or a reference to the data callback function if it has been defined, null or none otherwise.
void setCancellationCallback( CancellationCallback cancellationCallback ) | Sets the cancellation callback that can be used to interrupt an algorithm before being completed. CancellationCallback: The cancellation callback used to notify algorithm cancellation. It has one argument, a GenericAlgorithm object, which represents the algorithm being executed. This function has to return True when the algorithm must be stopped, False when it can continue its execution.
CancellationCallback getCancellationCallback() | Returns a pointer or a reference to the cancellation callback function if it has been defined, null or none otherwise.

    float progress = 0.f;

    // change the number of core used by imagedev. 0 means the maximum number of core.
    if ( imagedev::getCpuNumber() > 0 )
      imagedev::setCpuNumber( 0 );

    // Initialize the progress, cancellation, message and data callbacks
    auto ratioCallback = [&]( const GenericAlgorithm&, float ratio ) {
      std::cout << "progress " << ratio << std::endl;
      progress = ratio;
    };
    auto dataCallback = []( const GenericAlgorithm&, const std::string& data, const std::string& encoding ) {
      std::cout << "new data (" << encoding << "): " << data << std::endl;
    };
    auto cancellationCallback = [&]( const GenericAlgorithm& ) {
      if ( progress > 0.5f )
      {
        std::cout << "Algorithm cancelled" << std::endl;
        return true;
      }
      return false;
    };
    imagedev::setProgressRatioCallback( ratioCallback );
    imagedev::setProgressDataCallback( dataCallback );
    imagedev::setCancellationCallback( cancellationCallback );

    // Launch the elasticRegistration algorithm to see its progression
    boost::filesystem::path autorad = getBaseImagePath( "autorad.tif" );
    boost::filesystem::path autoradDist = getBaseImagePath( "autorad.distorted.tif" );

    std::shared_ptr < iolink::ImageView > fixedImage = ioformat::readImage( autorad.string() );
    std::shared_ptr < iolink::ImageView > movingImage = ioformat::readImage( autoradDist.string() );

    imagedev::ElasticRegistration2d elasticRegistration2dAlgo;
    elasticRegistration2dAlgo.setInputFixedImage( fixedImage );
    elasticRegistration2dAlgo.setInputMovingImage( movingImage );
    elasticRegistration2dAlgo.setMetricType(
        imagedev::ElasticRegistration2d::MetricType::MEAN_SQUARE_DIFFERENCE );
    elasticRegistration2dAlgo.setTolerance( 0.025 );
    elasticRegistration2dAlgo.setPyramidLevels( { 2, 0 } );
    elasticRegistration2dAlgo.setElasticStandardDeviation( { 10.0, 10.0 } );
    elasticRegistration2dAlgo.setFluidStandardDeviation( { 10.0, 10.0 } );

    try
    {
        elasticRegistration2dAlgo.execute();
    }
    catch ( imagedev::Exception& )
    {
        std::cout << "The ElasticRegistration2d algorithm was cancelled." << std::endl;
    }

    // disable callbacks
    imagedev::setProgressRatioCallback( nullptr );
    imagedev::setProgressDataCallback( nullptr );
    imagedev::setCancellationCallback( nullptr );

Method | Description
--- | ---
set_verbose(enable) | Sets default callbacks that print the name of which algorithm is starting, its progression, its execution time and manage cancellation. enable: Enables callbacks if true, disables them otherwise.
get_verbose() | Returns True if the verbose mode is enabled, False otherwise.
set_cpu_number(cpu_number) | Activates a user-defined number of logical processors to be used by ImageDev algorithms. Most of the ImageDev algorithms are CPU parallelized. However, if the computation time scales well with the CPU clock speed, it does not with the number of threads. Generally, using more than 8 threads is useless. For instance, a system with a 3.2 GHz, 8 threads processor configuration can run ImageDev algorithms faster than a system with 2.7 GHz and 32 threads. This phenomenon is easy to explain. When processing an image in parallel, each selected logical processor computes a result for an image block. Once two contiguous blocks are processed, a fusion step is necessary to merge the results of these blocks. This step may be more or less complex depending on several parameters, such as: The nature of the algorithm (point-wise operators require less fusion than fixed window filters, which require less fusion than propagation-based algorithms). The number of logical processors used (the higher it is, the longer the fusion step takes). The size of the blocks (this parameter is automatically managed by ImageDev). On systems having more than 8 logical processors, it may be interesting to monitor the influence of the number of logical processors used on the execution time of a given recipe. cpuNumber: The number of logical processors to be used. All processors are used if this value is lower than or equal to zero.
get_cpu_number() | Returns the user-defined number of logical processors to be used by ImageDev algorithms. If the returned value is lower than or equal to zero, all processors are used.
cuda_init() | Initialize the CUDA library to avoid wasting time at the first run of a CUDA algo. User can call this init when starting the application if he wants to propose CUDA features.
is_cuda_gpu_available() | Returns true if a CUDA GPU is available, false otherwise. Can be used in an application to set a trigger between a CUDA implementation and a CPU implementation.
set_progress_ratio_callback(progress_ratio_callback) | Sets the ratio callback used to track the progression of algorithms. progressRatioCallback: The progression ratio callback used to track the progression of algorithms. It must have two arguments: A GenericAlgorithm object, which represents the algorithm being executed. A float value representing the progression ratio between 0 and 1.
get_progress_ratio_callback() | Returns a pointer or a reference to the ratio callback function if it has been defined, null or none otherwise.
set_progress_message_callback(progress_message_callback) | Sets the message callback used to be notified about generic messages sent by algorithms. progressMessageCallback: The progression message callback used to notify algorithm information. It must have two arguments: A GenericAlgorithm object, which represents the algorithm being executed. A string value representing the message sent by the algorithm.
get_progress_message_callback() | Returns a pointer or a reference to the message callback function if it has been defined, null or none otherwise.
set_progress_data_callback(progress_data_callback) | Sets the data callback used to be notified about formatted messages sent by algorithms. progressDataCallback: The progression data callback used to notify algorithm information. It must have two arguments: A GenericAlgorithm object, which represents the algorithm being executed. A string value representing data sent by the algorithm. A string value representing the encoding of data sent by the algorithm.
get_progress_data_callback() | Returns a pointer or a reference to the data callback function if it has been defined, null or none otherwise.
set_cancellation_callback(cancellation_callback) | Sets the cancellation callback that can be used to interrupt an algorithm before being completed. CancellationCallback: The cancellation callback used to notify algorithm cancellation. It has one argument, a GenericAlgorithm object, which represents the algorithm being executed. This function has to return True when the algorithm must be stopped, False when it can continue its execution.
get_cancellation_callback() | Returns a pointer or a reference to the cancellation callback function if it has been defined, null or none otherwise.

    progress = 0
    def progress_callback(algo, ratio):
      progress = ratio
      print("Progress:" + str(ratio))

    def data_callback(algo, data, encoding):
      print("Data (" + encoding + "):" + data)

    def cancellation_callback(algo):
      if(progress > 0.5):
          print("Algorithm cancelled.")
          return True
      return False

    # change the number of core used by imagedev. 0 means the maximum number of core.
    if( imagedev.get_cpu_number() > 0 ):
      imagedev::setCpuNumber( 0 )

    # Initialize the progress, cancellation, message and data callbacks
    imagedev.set_progress_ratio_callback(progress_callback)
    imagedev.set_progress_data_callback(data_callback)
    imagedev.set_cancellation_callback(cancellation_callback)

    # Launch the elasticRegistration algorithm to see its progression
    fixedImage = ioformat.read_image(getBaseImagePath("autorad.tif"))
    movingImage = ioformat.read_image(getBaseImagePath("autorad.distorted.tif"))

    try:
      imagedev.elastic_registration_2d(input_fixed_image=fixedImage,
        input_moving_image=movingImage,
        metric_type=imagedev.ElasticRegistration2d.MetricType.MEAN_SQUARE_DIFFERENCE,
        tolerance=0.025,
        pyramid_levels=[2, 0],
        elastic_standard_deviation=[10.0, 10.0],
        fluid_standard_deviation=[10.0, 10.0])
    except Exception as e:
        print("The ElasticRegistration2d algorithm was cancelled.")

    # Disable callbacks
    imagedev.set_progress_ratio_callback(None)
    imagedev.set_progress_data_callback(None)
    imagedev.set_cancellation_callback(None)

Method | Description
--- | ---
public void SetVerbose(bool enable) | Sets default callbacks that print the name of which algorithm is starting and its execution time. enable: Enables callbacks if true, disables them otherwise.
public bool GetVerbose() | Returns True if the verbose mode is enabled, False otherwise.
public void SetCpuNumber(int cpuNumber) | Activates a user-defined number of logical processors to be used by ImageDev algorithms. Most of the ImageDev algorithms are CPU parallelized. However, if the computation time scales well with the CPU clock speed, it does not with the number of threads. Generally, using more than 8 threads is useless. For instance, a system with a 3.2 GHz, 8 threads processor configuration can run ImageDev algorithms faster than a system with 2.7 GHz and 32 threads. This phenomenon is easy to explain. When processing an image in parallel, each selected logical processor computes a result for an image block. Once two contiguous blocks are processed, a fusion step is necessary to merge the results of these blocks. This step may be more or less complex depending on several parameters, such as: The nature of the algorithm (point-wise operators require less fusion than fixed window filters, which require less fusion than propagation-based algorithms). The number of logical processors used (the higher it is, the longer the fusion step takes). The size of the blocks (this parameter is automatically managed by ImageDev). On systems having more than 8 logical processors, it may be interesting to monitor the influence of the number of logical processors used on the execution time of a given recipe. cpuNumber: The number of logical processors to be used. All processors are used if this value is lower than or equal to zero.
public int GetCpuNumber() | Returns the user-defined number of logical processors to be used by ImageDev algorithms. If the returned value is lower than or equal to zero, all processors are used.
public CudaInit() | Initialize the CUDA library to avoid wasting time at the first run of a CUDA algo. User can call this init when starting the application if he wants to propose CUDA features.
public IsCudaGpuAvailable() | Returns true if a CUDA GPU is available, false otherwise. Can be used in an application to set a trigger between a CUDA implementation and a CPU implementation.
public static void SetProgressRatioCallback(ProgressRatioCallback progressRatioCallback) | Sets the ratio callback used to track the progression of algorithms. progressRatioCallback: The progression ratio callback used to track the progression of algorithms. It must have two arguments: A GenericAlgorithm object, which represents the algorithm being executed. A float value representing the progression ratio between 0 and 1.
public static ProgressRatioCallback GetProgressRatioCallback() | Returns a pointer or a reference to the ratio callback function if it has been defined, null or none otherwise.
public static void SetProgressMessageCallback(ProgressMessageCallback progressMessageCallback) | Sets the message callback used to be notified about generic messages sent by algorithms. progressMessageCallback: The progression message callback used to notify algorithm information. It must have two arguments: A GenericAlgorithm object, which represents the algorithm being executed. A string value representing the message sent by the algorithm.
public static ProgressMessageCallback GetProgressMessageCallback() | Returns a pointer or a reference to the message callback function if it has been defined, null or none otherwise.
public static void SetProgressDataCallback(ProgressDataCallback progressDataCallback) | Sets the data callback used to be notified about formatted messages sent by algorithms. progressDataCallback: The progression data callback used to notify algorithm information. It must have two arguments: A GenericAlgorithm object, which represents the algorithm being executed. A string value representing data sent by the algorithm. A string value representing the encoding of data sent by the algorithm.
public static ProgressDataCallback GetProgressDataCallback() | Returns a pointer or a reference to the data callback function if it has been defined, null or none otherwise.
public static void SetCancellationCallback(CancellationCallback cancellationCallback) | Sets the cancellation callback that can be used to interrupt an algorithm before being completed. CancellationCallback: The cancellation callback used to notify algorithm cancellation. It has one argument, a GenericAlgorithm object, which represents the algorithm being executed. This function has to return True when the algorithm must be stopped, False when it can continue its execution.
public static CancellationCallback GetCancellationCallback() | Returns a pointer or a reference to the cancellation callback function if it has been defined, null or none otherwise.

    float progress = 0;

    // change the number of core used by imagedev. 0 means the maximum number of core.
    if (ImageDev.Processing.GetCpuNumber() > 0)
      ImageDev.Processing.SetCpuNumber(0);

    // Initialize the progress, cancellation, message and data callbacks
    Processing.SetProgressRatioCallback(
      (algo, ratio) =>
      {
        Utilities.WriteInfoMsg("Progress: " + ratio);
        progress = ratio;
      }
    );

    Processing.SetCancellationCallback(
        (algo) =>
        {
            if (progress > 0.5f)
            {
                Console.WriteLine("Algorithm cancelled.");
                return true;
            }
            return false;
        }
    );

    // Check that callback are set
    if (Processing.GetProgressRatioCallback() != null)
    {
      Utilities.WriteInfoMsg("Progression callback is set.");
    }

    if (Processing.GetCancellationCallback() != null)
    {
      Utilities.WriteInfoMsg("Cancellation callback is set.");
    }

    // Launch the elasticRegistration algorithm to see its progression
    var fixedImage = IOFormat.ViewIO.ReadImage(GetBaseImagePath("autorad.tif")) as ImageView;
    var movingImage = IOFormat.ViewIO.ReadImage(GetBaseImagePath("autorad.distorted.tif")) as ImageView;

    ElasticRegistration2d elasticRegistration2dAlgo = new ElasticRegistration2d
    {
      inputFixedImage = fixedImage,
      inputMovingImage = movingImage,
      metricType = ElasticRegistration2d.MetricType.MEAN_SQUARE_DIFFERENCE,
      tolerance = 0.025,
      pyramidLevels = new uint[] { 2, 0 },
      elasticStandardDeviation = new double[] { 10.0, 10.0 },
      fluidStandardDeviation = new double[] { 10.0, 10.0 }
    };

    try
    {
        elasticRegistration2dAlgo.Execute();
    }
    catch
    {
        Console.WriteLine("The ElasticRegistration2d algorithm was cancelled.");
    }

    // Disable callbacks
    Processing.SetProgressRatioCallback(null);
    Processing.SetCancellationCallback(null);

© 2025 Thermo Fisher Scientific Inc. All rights reserved.