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

# Data Transfer

This example illustrates how to create a data buffer corresponding to a 3D image, and transfer it in an object connectable to an ImageDev algorithm, without duplicating the data.
To invoke an ImageDev algorithm, the data to process needs to be previously imported into an ImageView object of the IOLink library.
The two previous examples show how to create an ImageView from an existing buffer by copying the data. This way to proceed is safe and prevents conflicts of data ownership. However, when handling large data, it may be preferable to make the ImageView object directly point to the buffer without duplicating its content.
The first part of this example simply creates a buffer representing a 220x192x128 pixel image with a filled sphere drawn inside. This step is for demonstration purposes only. In practice, you should already have the content of the image to process in a buffer stored in the data model used by your application.
Then some IOLink instructions create a new ImageView object. The buffer previously created is set in this image with the fromBuffer method of the ImageViewFactory class. This method does not duplicate the data, thus optimizing the memory usage.
Two ImageDev algorithms are applied afterward to show that it is now possible to process this image with ImageDev.

- RandomGaussianImage3d generates a new image of the same dimensions, and initializes it with a random Gaussian noise.
- ArithmeticOperationWithImage is used to add this Gaussian noise to the synthetic sphere and give it a more realistic aspect.

Figure 1. The 3D volume generated by this example visualized with Open Inventor
Note:
The last operator adds the values of an 8-bit signed integer image to those of an 8-bit unsigned integer image. The result is a 16-bit signed integer image, as explained in the Basic Rule table of the Rules for Arithmetic Image Type section.

    #include <ImageDev/ImageDev.h>
    #include <ioformat/IOFormat.h>
    #include <iolink/view/ImageViewFactory.h>
    #include <iolink/view/ImageViewProvider.h>
    #include <string.h>

    using namespace imagedev;
    using namespace ioformat;
    using namespace iolink;

    int
    main( int argc, char* argv[] )
    {
        int status = 0;

        try
        {
            // ImageDev library initialization
            if ( imagedev::isInitialized() == false )
                imagedev::init();

            // Initialize an unsigned 8-bit array storing data of a 3D image
            const uint64_t rowCount = 220;
            const uint64_t colCount = 192;
            const uint64_t sliCount = 128;
            std::vector< uint8_t > imageData( rowCount * colCount * sliCount );

            // Define a synthetic sphere in this array
            const int squareRadius = ( sliCount / 2 - 10 ) * ( sliCount / 2 - 10 ); // Radius of the sphere to draw
            int distToCenter;

            // Loop on image slices
            for ( int k = 0; k < sliCount; ++k )
            {
                // Loop on image rows
                for ( int i = 0; i < rowCount; ++i )
                {
                    // Loop on image columns
                    for ( int j = 0; j < colCount; ++j )
                    {
                        distToCenter = ( i - rowCount / 2 ) * ( i - rowCount / 2 ) +
                                       ( j - colCount / 2 ) * ( j - colCount / 2 ) +
                                       ( k - sliCount / 2 ) * ( k - sliCount / 2 );
                        if ( distToCenter <= squareRadius )
                            imageData[k * rowCount * colCount + i * colCount + j] = 200; // Value inside the sphere
                        else
                            imageData[k * rowCount * colCount + i * colCount + j] = 0; // Background value
                    }
                }
            }

            // Create an image view of same dimensions directly from this buffer
            VectorXu64 imageShape{ colCount, rowCount, sliCount };
            auto image = ImageViewFactory::fromBuffer(
                imageShape, DataTypeId::UINT8, imageData.data(), rowCount * colCount * sliCount * sizeof( uint8_t ) );
            image->setAxesInterpretation( ImageTypeId::VOLUME );

            // This image can now be processed by any ImageDev algorithm, for instance to add a Gaussian noise inside
            auto imageNoise = randomGaussianImage3d(
                RandomGaussianImage3d::OutputType::SIGNED_INTEGER_8_BIT, colCount, rowCount, sliCount, 0.0f, 20.0f );
            auto imageOut =
                arithmeticOperationWithImage( image, imageNoise, ArithmeticOperationWithImage::ArithmeticOperator::ADD );

            // Save the created image with IOFormat
            writeView( imageOut, "T02_03_output.tif" );

            std::cout << "This example ran successfully." << std::endl;
        }
        catch ( const imagedev::Exception& error )
        {
            // Print potential exception in the standard output
            std::cerr << "ImageDev exception: " << error.what() << std::endl;
            status = -1;
        }

        // ImageDev library finalization
        imagedev::finish();

        // Check if we must ask for an enter key to close the program
        if ( !( ( argc == 2 ) && strcmp( argv[1], "--no-stop-at-end" ) == 0 ) )
            std::cout << "Press Enter key to close this window." << std::endl, getchar();

        return status;
    }

    ﻿using System;
    using ImageDev;
    using IOLink;
    using IOFormat;

    namespace T02_03_TransferData
    {
        class Program
        {
            static void Main(string[] args)
            {
                int status = 0;

                try
                {
                    // Initialize the ImageDev library if not done
                    if (Initialization.IsInitialized() == false)
                        Initialization.Init();

                    // Initialize an unsigned 8-bit array storing data of a 3D image
                    int rowCount = 220;
                    int colCount = 192;
                    int sliCount = 128;
                    byte[] imageData = new byte[rowCount * colCount * sliCount];

                    // Define a synthetic sphere in this array
                    int squareRadius = (sliCount / 2 - 10) * (sliCount / 2 - 10); // Radius of the sphere to draw
                    int distToCenter;

                    // Loop on image slices
                    for (int k = 0; k < sliCount; ++k)
                    {
                        // Loop on image rows
                        for (int i = 0; i < rowCount; ++i)
                        {
                            // Loop on image columns
                            for (int j = 0; j < colCount; ++j)
                            {
                                distToCenter = (i - rowCount / 2) * (i - rowCount / 2) +
                                               (j - colCount / 2) * (j - colCount / 2) +
                                               (k - sliCount / 2) * (k - sliCount / 2);
                                if (distToCenter <= squareRadius)
                                    imageData[k * rowCount * colCount + i * colCount + j] = 200; // Value inside the sphere
                                else
                                    imageData[k * rowCount * colCount + i * colCount + j] = 0; // Background value
                            }
                        }
                    }

                    // Create an image view of same dimensions
                    VectorXu64 imageShape = new VectorXu64((ulong)colCount, (ulong)rowCount, (ulong)sliCount);
                    ImageView image = ImageViewFactory.FromBuffer(
                        imageShape, DataTypeId.UINT8, imageData, (uint)(rowCount * colCount * sliCount * sizeof(byte)));
                    image.AxesInterpretation = ImageTypeId.VOLUME;

                    // This image can now be processed by any ImageDev algorithm, for instance to add a Gaussian noise inside
                    ImageView imageNoise = Processing.RandomGaussianImage3d(
                        RandomGaussianImage3d.OutputType.SIGNED_INTEGER_8_BIT, colCount, rowCount, sliCount, 0.0f, 20.0f);
                    ImageView imageOut = Processing.ArithmeticOperationWithImage(
                        image, imageNoise, ArithmeticOperationWithImage.ArithmeticOperator.ADD);

                    // Save the created image with IOFormat
                    ViewIO.WriteView(imageOut, "T02_03_output.tif");

                }
                catch (Exception error)
                {
                    // Print potential exception in the standard output
                    System.Console.WriteLine("HelloImageDev exception: " + error.ToString());
                    status = -1;
                }

                // ImageDev library finalization
                Initialization.Finish();

                // Check if we must ask for an enter key to close the program
                if (!((args.Length >= 1) && (args[0] == "--no-stop-at-end")))
                {
                    System.Console.WriteLine("Press Enter key to close this window.");
                    System.Console.ReadKey();
                }

                System.Environment.Exit(status);
            }
        }
    }

    import imagedev
    import iolink
    import ioformat
    import numpy

    # Initialize an unsigned 8-bit three-dimensional numpy array storing data of a 3D image
    row_count = 220
    col_count = 192
    sli_count = 128
    image_data = numpy.zeros((sli_count, row_count, col_count), numpy.uint8)

    # Define a synthetic sphere in this array
    # Define the sphere center and radius value
    center = (int(sli_count/2), int(row_count/2), int(col_count/2))
    radius = int(sli_count/2) - 10

    # Create a distance map image with origin the sphere center
    slice_grid, row_grid, col_grid = numpy.ogrid[:sli_count, :row_count, :col_count]
    dist_from_center = numpy.sqrt((slice_grid - center[0])**2 + (row_grid-center[1])**2 + (col_grid-center[2])**2)

    # Mask the distance map where values are greater than the radius value
    mask = dist_from_center <= radius
    image_data[mask] = 200

    # Transform the Numpy array into an ImageView of same dimensions and type
    image = iolink.NumpyInterop.from_numpy_array(image_data, iolink.ImageTypeId.VOLUME)

    # This image can now be processed by any ImageDev algorithm, for instance to add a Gaussian noise inside
    image_noise = imagedev.random_gaussian_image_3d(
      imagedev.RandomGaussianImage3d.OutputType.SIGNED_INTEGER_8_BIT, col_count, row_count, sli_count, 0.0, 20.0)
    image_out = imagedev.arithmetic_operation_with_image(
      image, image_noise, imagedev.ArithmeticOperationWithImage.ArithmeticOperator.ADD)

    # Save the created image with IOFormat
    ioformat.write_view(image_out, "T02_03_output.tif")

See also

- RandomGaussianImage3d
- ArithmeticOperationWithImage

© 2025 Thermo Fisher Scientific Inc. All rights reserved.