File:
/src/image.hppLines 2173–2217 /**
* @brief Applies a filter to the input tensor.
*
* @details
* This function applies a filter defined by `qWeights` on the input tensor (`InputImage`).
* The result is stored in the output OCM tensor (`ocmOutputImage`).
*
* For a 3×3 filter, the weights are indexed as follows
* ```math
\begin{bmatrix}
*
* 0 & 1 & 2 \\
* 3 & 4 & 5 \\
* 6 & 7 & 8
*
*
\end{bmatrix}
*
* For a 5×5 filter, the weights are indexed as follows
* ```math
\begin{bmatrix} * * 0 & 1 & 2 & 3 & 4 \ * 5 & 6 & 7 & 8 & 9 \ * 10 & 11 & 12 & 13 & 14 \ * 15 & 16 & 17 & 18 & 19 \ * 20 & 21 & 22 & 23 & 24 * * \end{bmatrix}
*
* > Note: Currently only 3×3 and 5×5 filters are supported.
*
* @tparam ImageShape The data type of the output OCM image.
* @tparam OcmAllocatorType The type of OCM memory allocator. Defaults to `MemAllocator`.
* @tparam NDArray The type of weight array, expected to be a `chimera::container::NDArray`.
*
* @param InputImage The input image that the filter will be applied to.
* @param[out] OutputImage The output image that will store the result.
* @param[in] qWeights The filter weights, defined as a NDArray.
* @param ocmMemAlloc The OCM memory allocator.
*
*/
// clang-format on
template <typename ImageShape, typename OcmAllocatorType = MemAllocator, typename NDArray>
INLINE void applyFilter(ImageShape& InputImage,
ImageShape& OutputImage,
const NDArray& qWeights,
OcmAllocatorType&& ocmMemAlloc = OcmAllocatorType()) {
Dilation & Erosion
File:
/src/image.hppLines 202–229 /**
* @brief Erodes an image by using a specific structuring element of 3x3, 5x5.
*
* @tparam morphologyMethod Type of a morphological operation. Note: this template only support erosion 3x3, 5x5.
* @tparam filterDim The size of the filter.
* @tparam height Input image height.
* @tparam width Input image width.
* @tparam elemType Input data type.
* @param qIn The input on which the dilation is applied.
* @param structuredElement The structuring element used for dilation.
* @param widthOffset Width offset of the current tile data w.r.t the original image.
* @param tileNum Current tile number, in order to calculate boundaries.
* @param borderValue The border value.
* @return eroded_value Image that has had erosion filter applied.
*/
template <MorphologyMethod morphologyMethod,
std::int32_t filterDim,
std::int32_t height,
std::int32_t width,
typename elemType,
typename std::enable_if_t<(morphologyMethod == MorphologyMethod::EROSION), std::int32_t> = 0>
INLINE qVar_t<elemType> applyMorphology(
qVar_t<elemType> qIn,
const container::NDArray<qVar_t<std::uint8_t>,
roundUpToNearestMultiple(filterDim* filterDim, core_array::coreDim)>& structuredElement,
std::int32_t widthOffset,
std::int32_t tileNum,
elemType borderValue) {
File:
/src/image.hppLines 166–193 /**
* @brief Dilates an image by using a specific structuring element of 3x3, 5x5.
*
* @tparam morphologyMethod Type of a morphological operation. Note: this template only support dilation 3x3, 5x5.
* @tparam filterDim The size of the filter.
* @tparam height Input image height.
* @tparam width Input image width.
* @tparam elemType Input data type.
* @param qIn The input on which the dilation is applied.
* @param structuredElement The structuring element used for dilation.
* @param widthOffset Width offset of the current tile data w.r.t the original image.
* @param tileNum Current tile number, in order to calculate boundaries.
* @param borderValue The border value.
* @return dilated_image Image with dilation filter applied.
*/
template <MorphologyMethod morphologyMethod,
std::int32_t filterDim,
std::int32_t height,
std::int32_t width,
typename elemType,
typename std::enable_if_t<(morphologyMethod == MorphologyMethod::DILATION), std::int32_t> = 0>
INLINE qVar_t<elemType> applyMorphology(
qVar_t<elemType> qIn,
const container::NDArray<qVar_t<std::uint8_t>,
roundUpToNearestMultiple(filterDim* filterDim, core_array::coreDim)>& structuredElement,
std::int32_t widthOffset,
std::int32_t tileNum,
elemType borderValue) {
Sobel
File:
/src/image.hppLines 1015–1084 /**
* @brief Applies a 3x3 or 5x5 sobel filter.
*
* This function calculates the gradient magnitude (`mG`) and angle group (`aG`) of the pixel using Sobel kernels.
*
* Sobel operator has two sets of kernel weights, horizontal weights (`wH`) and vertical weights (`wV`).
* By applying these two weights separately, two gradient magnitudes (`qFH` and `qFV`) can be calculated.
*
* ```
* qFH = applyFilter(input, wH)
* qFV = applyFilter(input, wV)
* ```
*
* The resultant gradient (mG) can be calculated as follows:
*
* ```
* mG = sqrt((qFH ^ 2) + (qFV ^ 2)) ---> mG ≈ |qFH| + |qFV|
* ```
*
* To calculate the angle group of the gradient, ratio between qFV and qFH (rG) needs to be calculated:
*
* ```
* rG = qFV / qFH
* ```
*
* Then the angle group (aG) can be determined as shown in below:
*
* ```
* | angleGroup = 0
* |angleGroup = 3 ▲ angleGroup = 1
* | __ lim1 | lim4 __
* | |\_ : │ : _/| θ = π/8
* | \_ : │ : _/
* | \_ : │ : _/ lim1 = tan(5θ) = -2.41421356237309500
* | \_ : θ │ θ : _/ lim2 = tan(7θ) = -0.41421356237309503
* | lim2 '-_ \_ θ : │ : θ _/ _-' lim3 lim3 = tan(θ) = 0.41421356237309503
* | '-_ \_ : │ : _/ _-' lim4 = tan(3θ) = 2.41421356237309500
* | '-_ θ \_ : │ : _/ θ _-'
* | '-_ \_:│:_/ _-'
* | θ '-__ \│/ __-' θ
* |angleGroup = 2 ◄─────────────────┼─────────────────► angleGroup = 2
* |
* | ┌─ 3 if (lim1 < rG <= lim2)
* | │
* | ├─ 2 if (lim2 < rG <= lim3)
* | aG = ─┤
* | ├─ 1 if (lim3 < rG <= lim4)
* | │
* | └─ 0 if (lim4 < rG <= lim1)
* ```
*
* (Please see the @ref `populateSobelWeights` function for weight values)
*
* @tparam T Data type of the input values.
* @tparam GradOutType Data type of the gradient output values.
* @tparam filterSize Filter size of the sobel operation. Filter sizes of 3 and 5 are supported.
* @tparam calculateAngle When set to true, both quantized angle and the magnitude of the gradient are calculated. Otherwise, only magnitude is calculated.
* @tparam useScharr When set to true; uses a set of weights that can generate more accurate gradients. Please check `populateSobelWeights` for more details.
* @param qFrameIn The input data.
* @param qGradOut The variable that needs to store the calculated gradient output.
* @param qAngleGroupOut The variable that needs to store the calculated angle output.
*/
// clang-format on
template <typename T,
typename GradOutType = std::int16_t,
std::uint32_t filterSize = 3,
bool calculateAngle = true,
bool useScharr = false,
typename std::enable_if_t<calculateAngle, std::int32_t> = 0>
INLINE void sobel(qVar_t<T> qFrameIn, qVar_t<GradOutType>& qGradOut, qVar_t<std::int8_t>& qAngleGroupOut) {
Canny
File:
/src/image.hppLines 1595–1611 /**
* @brief This function detects the edges of a given image using Canny edge detection algorithm.
* The output image represents the edge pixels with value 255 and non-edge pixels with value 0.
*
* @tparam lowThreshold Low threshold value.
* @tparam highThreshold High threshold value.
* @tparam OcmInputImageShape Tensor shape of the input OCM image.
* @tparam OcmOutputImageShape Tensor shape of the output OCM image.
*
* @param ocmInput Input OCM image.
* @param ocmOutput Output OCM image.
*/
template <std::uint16_t lowThreshold,
std::uint16_t highThreshold,
typename OcmInputImageShape,
typename OcmOutputImageShape>
INLINE void cannyKernel(OcmInputImageShape& ocmInput, OcmOutputImageShape& ocmOutput) {
Gaussian Blur
File:
/src/image.hppLines 2255–2288 /**
* @brief Applies a Gaussian blur filter to an input image using a specified sigma value for blurring intensity.
* This function operates on images represented in fixed-point arithmetic,
*
* The Gaussian blur is achieved by convolving the input image with a Gaussian kernel of a specified width and
* sigma. The width of the Gaussian kernel can only be 3 or 5, which constrains the extent of the blur effect. The
* sigma parameter controls the spread of the blur; larger values produce a more pronounced blur effect.
*
*
* @tparam DdrInOutTensorShape Shape of image.
* @tparam numFracBits Number of fractional bits in fixed-point representation.
* @tparam filterWidth Size of filter.
* @param[in] ddrInputImage Image to which gaussian blur will be applied.
* @param sigma Sigma value to indicate intensity of blur.
* @param[out] ddrOutputImage Image with gaussian blur applied.
*
* Limitations:
* - Only `filterWidth` values of 3 and 5 are supported. Attempting to use other values will result in a
* compile-time error.
* - The input and output images must be represented in fixed-point format with the number of fractional bits
* specified by `numFracBits`. This requires careful consideration when choosing `numFracBits` to balance between
* precision and range.
*
* Example Usage:
* ```
* FixedPoint32<numFracBits> sigma = ...; // Define sigma
* image::gaussianBlur<DdrImageShape, numFracBits, filterSize>(ddrInputImage, sigma, ddrOutputImage);
* ```
*
*/
template <typename DdrInOutTensorShape, FracRepType numFracBits, std::size_t filterWidth = 3>
INLINE void gaussianBlur(DdrInOutTensorShape& ddrInputImage,
FixedPoint32<numFracBits> sigma,
DdrInOutTensorShape& ddrOutputImage) {
Median Blur
File:
/src/image.hppLines 3386–3408 /**
* @brief Applies a median blur on the input image.
*
* When the template parameter borderReplicate is set to true, the image borders will be replicated
* so that the output will be equivelent to the openCV median blur output. Otherwise, the borders will be
* padded with zeros. Due to this, the border elements of the output image will not be equivelent to the
* openCV median blur output.
*
* @tparam OcmInputImageShape The shape of the input image
* @tparam OcmOutputImageShape The shape of the output image
* @tparam filterSize The size of the filter to apply. (Only filter sizes of 3, 5 and 7 are supported for now.)
* @tparam borderReplicate Enables or disables the border replication that happens in OpenCV median blur
* implementation. (Not available for filterSize 7)
*
* @param ocmInput The input image tensor
* @param ocmOut The output image tensor
*/
template <std::uint8_t filterSize = 3,
bool borderReplicate = false,
typename OcmInputImageShape,
typename OcmOutputImageShape,
typename std::enable_if_t<filterSize == 7 && !borderReplicate, std::int32_t> = 0>
INLINE void medianBlur(OcmInputImageShape& ocmInput, OcmOutputImageShape& ocmOut) {
Tone Curve
File:
/src/image.hppLines 2958–2999 /**
* @brief This function is used for tuning the colors of images.
*
* The basic operation of this function is similar to a simple look-up table (LUT).
*
* Since the operation is done only on RGB images, both input and LUT values must be in range 0 to 255.
* This function can handle multiple LUTs for multi channel input images.
*
* If the LUT DDR tensor `ddrLut` has only one channel, all the channels of the input image will use this single
* LUT. Otherwise, `ddrLut` must have the same number of channels that the input image has. Then, each input
* channel has its own LUT.
*
* ```
* Output value (0 to 255)
* ▲
* │ ..
* │ . .
* │ . .
* │ . .
* │ .
* │. .
* │ . .
* │ ..
* └─────────────────►
* Input value (0 to 255)
* ```
*
* @tparam DdrImageShape Shape of input and output DDR tensor.
* @tparam DdrLutShape Shape of the LUT DDR tensor.
* @tparam OcmAllocatorType Type of OCM memory allocator.
*
* @param ddrIn Input DDR tensor.
* @param ddrOut Output DDR tensor.
* @param ddrLut LUT DDR tensor.
* @param ocmMemAlloc OCM memory allocator.
*/
// clang-format on
template <typename DdrImageShape, typename DdrLutShape, typename OcmAllocatorType>
INLINE void toneCurve(DdrImageShape& ddrIn,
DdrImageShape& ddrOut,
DdrLutShape& ddrLut,
OcmAllocatorType& ocmMemAlloc) {