Skip to main content

Image statistics

Many applications need to obtain some type of image statistic to condense a frame of pixels into a smaller, more functional set of values for analysis. The statistic might be required to perform some subsequent operation and/or might be used to summarize the effect of some image operation. The Aurora Imaging Library Image Processing module offers a variety of functions to extract statistical information from an image. These functions allow you, for example, to:

Note: Note that, with the exception of MimHistogram, these functions are not available with Aurora Imaging Library Lite.

Generating a histogram

A histogram is the intensity distribution of pixel values in an image and is generated by counting the number of times each pixel intensity occurs. Histograms store this information in bins, each of which represents an intensity. For example, if a histogram has 100 bins, it can represent 100 intensities.

Information about the intensity distribution of pixel values in an image is useful for several applications. In particular, it is useful to help select a threshold level when binarizing an image (discussed later) and to change the image intensity distribution when trying to increase the image contrast.

You can generate an image histogram using MimHistogram, which takes an image buffer and stores the results in a previously allocated histogram result buffer. To allocate the result buffer, use MimAllocResult with M_HIST_LIST. Ensure that you specify enough histogram bins to store the required number of intensities in the result, using the NbEntries parameter. For example, if you are using an 8-bit unsigned source image, and you want to have one bin for every possible intensity value, you should specify 256 entries.

To read results, use MimGetResult. Once results have been read from the result structure, you can then release it, using MimFree.

If you require further control over the generated histogram, you can specify the number of values that a histogram bin can hold, using MimControl with M_HIST_BIN_SIZE_MODE, before calling MimHistogram. You can also apply a smoothing factor to the histogram with the M_HIST_SMOOTHING_ITERATIONS control. Since the smoothing is an integer-based averaging of the histogram, the resulting number of values might be different than the number of values in the source image. To retrieve this type of information, use MimGetResult with M_HIST_REAL_SIZE, M_HIST_VALUE_OFFSET, and M_HIST_VALUE_RANGE.

The MImHistogram.cpp example shows how to load an image, and calculate and draw its intensity histogram. To run/view this and other examples, use Aurora Imaging Example Launcher. You can also view this example here:

Code example: MImHistogram.cpp

You can use the Aurora Imaging Library graphics functions to plot the histogram results on a graph, as shown below. The graphics functions (Mgra...) are discussed later in this manual.

[Image: cellhst2.png]

Calculating general statistics

You can calculate various statistics for all pixels that satisfy a specified condition in an image, using MimStatCalculate. Setting the condition limits the number of pixels for which the statistics will be calculated. However, the condition can also be set to use all of the pixels in the image.

You can limit some of MimStatCalculate's results to a region of an image buffer using a region of interest (ROI) set using MbufSetRegion. The ROI must be defined in raster format (M_RASTER or M_VECTOR_AND_RASTER). An error is generated if the ROI is only in vector format (M_VECTOR). Note that not all statistics operations support ROIs; for a list of those that do, seeMimControl.

The types of statistics that can be calculated include the following:

  • Maximum pixel value.
  • Maximum absolute pixel value.
  • Mean pixel value.
  • Minimum pixel value.
  • Minimum absolute pixel value.
  • Number of pixels (that satisfy the condition).
  • Standard deviation value.
  • Sum of pixel values.
  • Sum of absolute pixel values.
  • Sum of squared pixel values.

Steps to calculate general statistics

The following steps provide a basic methodology for calculating general statistics:

  1. Optionally, allocate a statistics context, using MimAlloc with M_STATISTICS_CONTEXT.

    Note: Note that if you want to calculate a single statistic, you can call MimStatCalculate with a predefined statistics context, without having to allocate a statistics context beforehand.

  2. Allocate a statistics result buffer, using MimAllocResult with M_STATISTICS_RESULT.
  3. If you have allocated a statistics context, control its settings using MimControl. These settings determine which statistics to calculate. You cannot control the settings of a predefined statistics context.
  4. Call MimStatCalculate to calculate the statistics.
  5. Retrieve results from the statistics result buffer using MimGetResult.

Alternatively, you can use MimProjectionto calculate the maximum, minimum, mean, and median pixel value for each row or column of pixels in the image. This is typically more efficient than using MimStatCalculatewhen you need to calculate these statistics for regions of an image that are rows or columns of pixels, and calculate them for all rows or columns in that region. When you need to calculate statistics for regions of an image that are not rows or columns, or individual rows or columns, use MimStatCalculate. For more information on using MimProjectionto calculate the maximum, minimum, mean, and median pixel value for each row or column of pixels in the image, seeProjecting an image to one dimension.

Considering pixel values as unit vectors and calculating angular statistics

If pixel values in your image represent angles instead of intensities, you can also choose to have Aurora Imaging Library treat the pixels as unit vectors, where the angular value of a pixel is considered to be the angle of a vector with a length of one. Treating the pixels as unit vectors allows Aurora Imaging Library to calculate directional statistics, which take into account the wrap-around characteristic of angles (so that, for example, the mean of 0 and 360 is either 0 or 360, not 180). This is useful, for example, when calculating color statistics of HSL images because the hue of an HSL image is measured on an angular scale, as opposed to a linear scale.

The angles are considered to have been scaled to the type of the image buffer. For unsigned buffers, the minimum pixel value is considered as an angle of 0, and one plus the maximum possible pixel value is considered an angle of 360. For example, an 8-bit buffer would have 0° mapped to a value of 0, while 360° would be mapped to a value of 256 (since the maximum pixel value is 255). For signed buffers, the minimum pixel value is considered as an angle of -180° while one plus the maximum pixel value is considered as an angle of 180°. Floating point buffers have intensity values anywhere between 0 and 1, and these values are linearly mapped between 0° and 360°.

Using MimStatCalculate, there are three main statistics that can be calculated when pixel values that satisfy a specified condition are considered as unit vectors:

  • The coherence of the unit vectors.
  • The dominant angle of the unit vectors.
  • The dominant orientation of the unit vectors.

Coherence

The coherence represents the directional trend of all the unit vectors in the image. It is a measure of how coherent or parallel the unit vectors are with respect to each other. To quantify this idea, MimControl with M_STAT_ANGULAR_DATA_COHERENCE enables a vector addition on all the unit vectors. This is performed when MimStatCalculate is called. The vector that results from this addition is known as the vector sum, and the length component of this vector sum is known as the norm. The function then calculates the ratio between the norm, or length, of the vector sum and its maximum possible length (which corresponds to the number of pixels considered, since each pixel is presumed to have a length of one). Numerically, this quantity lies between 0 and 1, where 0 represents absolutely no coherence (unit vectors pointing in random directions) and 1 is total coherence (unit vectors pointing in same direction). Below are images depicting three different coherences: perfect coherence, high coherence, and low coherence, respectively.

In the following image, the coherence of 4 unit vectors with the same angle is calculated. Since the ratio between the norm and the maximum possible length is equal to 1, there is total coherence between individual unit vectors, confirming all unit vectors are pointing in the same direction.

[Image: AngularStatsCoherence=1.png]

In the following image, the coherence of 4 unit vectors with differing angles is calculated. Since the ratio between the norm and the maximum possible length is equal to 0.905, there is high (but not total) coherence between individual unit vectors. Therefore, it can be concluded that the unit vectors are pointing in similar directions.

[Image: AngularStatsHighCoherence.png]

In the following image, the coherence of 4 unit vectors with differing angles is calculated. Since the ratio between the norm and the maximum possible length is equal to 0.105, there is very low coherence between the individual unit vectors. Therefore, it can be concluded that the unit vectors are pointing in seemingly opposite or random directions.

[Image: AngularStatsLowCoherence.png]

Dominant angle

In addition to calculating the coherence (M_STAT_ANGULAR_DATA_COHERENCE), by treating the pixels as unit vectors, you can also calculate the dominant angle in the data. To do so, use MimControl with M_STAT_ANGULAR_DATA_MEANbefore calling MimStatCalculate; this considers the angular component of the vector sum as the average angle. When the average angle is analyzed in context with the coherence of the unit vectors, it is much more representative of the average angle. For example, if your image has a coherence of 0.1 and an average angle of 65°, the average angle is not very meaningful because the unit vectors are pointing in random, incoherent directions. However, if your image has a coherence of 0.9 and an average angle of 65°, this indicates that the unit vectors are more or less pointing in the same direction, and their average value is around 65°.

Dominant orientation

If you are only interested in the dominant orientation of the unit vectors, you should enableMimControl with M_STAT_ORIENTATION_DATA_MEANbefore calling MimStatCalculate; this only takes into consideration the inclination of the unit vectors, without their direction, returning their dominant orientation within the image (for example, are they horizontal, vertical, diagonal). For unit vectors that are antipodal to each other (for example, 45° and 225°), the resulting orientation angle will be one of the original angles (for the previous example, 45°). Whereas for unit vectors that have an angular distance of 90° (for example, 0° and 90°), the vectors will cancel each other out. The orientation operation does not typically deal with only 2 unit vectors, but with all unit vectors within an image; as such, it is very unlikely that all the resulting unit vectors' orientations will cancel each other out. Furthermore, because the operation deals with the average orientation of all unit vectors in an image, the approximate, dominant orientation of the image is returned. For a more accurate orientation operation, use the MimFindOrientation function.

The following image illustrates the difference between taking the dominant angle (M_STAT_ANGULAR_DATA_MEAN) and the dominant orientation (M_STAT_ORIENTATION_DATA_MEAN). The calculation of M_STAT_ANGULAR_DATA_MEAN results in a dominant angle of 45 o. Whereas, the calculation of M_STAT_ORIENTATION_DATA_MEANresults in a dominant orientation of 90 o.

[Image: AngularOrientation.png]

Calculating statistics across multiple images

You can calculate statistics for each pixel location across multiple source images, passed upon iterative calls to MimStatCalculate. One value is calculated for every pixel in the source image, for each statistical operation specified to be performed. This function stores results in a result buffer that should have been previously allocated using MimAllocResult with M_STATISTICS_RESULT. The same result buffer should be specified for each call to MimStatCalculate.

Specify the statistics to perform using a cumulative statistics image processing context, allocated using MimAlloc with M_STATISTICS_CUMULATIVE_CONTEXT. Enable the type of statistics to calculate using MimControl with one or more of the statistics (for example, set M_STAT_MEAN to M_ENABLE).

Aurora Imaging Library can calculate one or more of the following types of statistics for each pixel position in the sequence of images:

  • Maximum pixel value at the position.
  • Maximum absolute pixel value at the position.
  • Mean pixel value at the position.
  • Minimum pixel value at the position.
  • Minimum absolute pixel value at the position.
  • Number of pixel values, at the position, that match the given condition.
  • Standard deviation value at the position.
  • Sum of pixel values at the position.
  • Sum of absolute pixel values at the position.
  • Sum of squared pixel values at the position.

When you are ready to calculate the statistics for the source images, you must preprocess the context and result buffer. The preprocessing stage uses the specified source image and result buffer (if specified) to determine how to optimally calculate the specified statistics. If the preprocessing operation was not done explicitly (using M_PREPROCESS) it will be done when MimStatCalculate is first called. Note that, if you do not provide a source image for the preprocessing operation, you must set M_SOURCE_SIZE_X and M_SOURCE_SIZE_Y to respective width and height of a typical image.

Finding the image extremes

You can find the minimum and maximum pixel values of your image with MimFindExtreme. Perhaps the most common use for finding the minimum and maximum image pixel values is to fine-tune the black and white reference levels of your frame grabber, ensuring full-range digitization. Another use for finding the maximum image pixel value is to find the number of objects in a labeled image. If all objects in an image are labeled with unique consecutive values, using MimLabel (discussed later in this chapter), the largest label value also corresponds to the number of objects in your image.

MimFindExtreme stores results in a result buffer that should have been previously allocated, using MimAllocResult with M_EXTREME_LIST. You can get the resulting values, using MimGetResult, and free the result buffer, using MimFree.

Locating events

Once you have established certain values of interest in an image, you can find the location of pixels that satisfy conditions based on these values, using MimLocateEvent. For example, you can use MimLocateEvent to find the location of all pixels in an image equal to the image's maximum pixel value.

Another use-case for MimLocateEvent is to find the local minima or maxima in an image which meet the specified condition. To do so, add the respective M_LOCAL_... combination value when specifying the condition under which pixel values are considered an event.

For example, you can use the M_LOCAL_MAX_NOT_STRICT or M_LOCAL_MAX_STRICT_MEDIUM combination value to find the local maxima in an image. A pixel is a local maximum if its value is greater than or equal to its surrounding pixels. Some combination values have stricter conditions for a pixel to be considered a local maximum. The following 3x3 neighborhood images illustrate the conditions under which a pixel is considered a local maximum for the respective combination value.

[Image: MimLocateEvent_neighborhoods_local_max.png]

The image below shows two buffers, each with a multi-pixel peak. The not-strict mode returns the positions of all pixels in the peak, whereas the strict mode typically returns a single pixel position for a narrow peak but can return multiple pixel positions for wider peaks. Note that M_LOCAL_MAX_NOT_STRICT and M_LOCAL_MAX_STRICT_MEDIUM are intended for use when peaks are narrow. Otherwise, multiple strict peaks are possible.

[Image: MimLocateEvent_local_max.png]

Similarly, you can use the M_LOCAL_MIN_NOT_STRICT and M_LOCAL_MIN_STRICT_MEDIUM combination values to find the local minima in an image.

Note that MimLocateEvent stores results in a result buffer that should have been previously allocated, using MimAllocResult with M_EVENT_LIST.

Note: Note, for ease of use, in cases when you only need to know if an event is present and not the location, you can use MimDetectEvent.

Counting image differences

You can find the number of differences between two images, using MimCountDifference. MimCountDifference stores results in a result buffer that should have been previously allocated, using MimAllocResult with M_COUNT_LIST. You can get the resulting values, using MimGetResult, and free the result buffer, using MimFree.

Locating image differences

You can find the location of differences between two images with some tolerance, using MimLocateDifference. MimLocateDifference stores results in a result buffer that should have been previously allocated, using MimAllocResult with M_LOCATE_DIFFERENCE_RESULT.

To obtain results of an MimLocateDifference operation, use MimGetResult or MimGetResult1d. For example, you can retrieve the X and Y-coordinates of the differences between the source buffers using M_POSITION_X and M_POSITION_Y respectively. You can also retrieve the number of differences between the source image buffers using M_NUMBER.

The following code snippet show how to locate the difference between the two source images:

Code example: userguide.image_processing.locate_difference

Projecting an image to one dimension

The MimProjection function projects an image onto one dimension, based on a specified projection axis angle and operation. The projection operates on all pixel values along each lane of pixels in the image, perpendicular to the specified axis angle (for example, a 90° angle projects each row onto the Y-axis).

You can use MimProjectionto calculate the maximum, minimum, mean, or median pixel value for each lane of pixels in the image. Although you can calculate the maximum and minimum pixel values for a lane using MimStatCalculate, it is more efficient to use MimProjection when you need to get these values for all lanes in an image. In this case, use MimProjectionwith M_MAX, M_MIN, M_MEAN, or M_MEDIAN.

You can also useMimProjection to find the pixel value with the specified rank for each lane of pixels in the image. The pixels in a lane are ranked in ascending order based on pixel value. You can specify the rank explicitly using MimProjection with M_RANK. Alternatively, you can specify the rank as a percentage of the total lane length using MimProjection with M_RANK_PERCENTILE (for example, if you specify 0.5 with M_RANK_PERCENTILE, the median pixel value is selected in each lane).

Another operation that MimProjectionsupports is summation (M_SUM). In this case, it sums all pixel values in each lane. This projection is referred to as the pixel value density of each lane of pixels. The 90° projection of the image is known as the row profile, and the 0° projection is known as the column profile.

The MimProjection function can perform both grayscale and binary image summation projections. On simple binary images, the projection is useful to detect object locations. The following image demonstrates the row and column profiles for a binary image, as calculated using MimProjection with M_SUM.

[Image: projection.png]

You can use MimProjectionwith a destination image buffer, or you can use a result buffer allocated using MimAllocResult with M_PROJ_LIST. Writing results to a projection image processing result buffer allows you to manipulate results using an array once you have retrieved the results using MimGetResultor MimGetResult1d. You should define a result buffer with as many locations as there are lanes of pixels in the image, perpendicular to the specified axis angle.

When using a region of interest in the source image of your projection, lanes of pixels that fall outside the specified region of interest will be marked as invalid in the result buffer. You can retrieve the validity of projection data for each lane using MimGetResult or MimGetResult1dwithM_VALID. Note that for an M_SUMprojection operation, if a lane of pixels does not contain valid projection data, a neutral pixel value of 0 is used for that lane. In this case, M_VALIDwill indicate valid projection data for all lanes of pixels in the image.

Calculating the integral of an image

You can calculate the integral of an image, using MimArith. Each pixel of the integral image contains the cumulative sum of the source image pixels until that location. Calculating the integral of the image allows you to analyze regions of an image more efficiently. For more information on calculating the integral of an image, see Computing the integral of an image.

Copyright © 2026 Zebra Technologies.