# Clarification on CALL\_HAL Usage in pyrDown and Handling of ROIs in OpenCV

**URL:** <https://forum.opencv.org/t/clarification-on-call-hal-usage-in-pyrdown-and-handling-of-rois-in-opencv/19265>\
**Category:** C++\
**Tags:** opencl, imgproc, core\
**Created:** [November 12, 2024, 10:52am UTC](https://forum.opencv.org/t/clarification-on-call-hal-usage-in-pyrdown-and-handling-of-rois-in-opencv/19265 "2024-11-12T10:52:51Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Shyama7004](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/shyama7004/32/10766_2.png) [@Shyama7004](https://forum.opencv.org/u/Shyama7004)\
**Post date:** [November 12, 2024, 10:52am UTC](https://forum.opencv.org/t/clarification-on-call-hal-usage-in-pyrdown-and-handling-of-rois-in-opencv/19265/1 "2024-11-12T10:52:51Z")

</div>

Hello OpenCV community,

I am working on understanding and potentially modifying the pyrDown function in OpenCV to ensure consistent behaviour when processing different regions of interest (ROIs). In particular, I’ve observed issues when pyrDown is applied to an ROI compared to when it’s applied to a full image and then cropped to the same ROI. This discrepancy appears when using certain border types and might relate to how the CALL\_HAL macro is utilised.

Here’s the snippet of the code: (Line 1348 to 1378 of pyramid.cpp)

void cv::pyrDown( InputArray \_src, OutputArray \_dst, const Size& \_dsz, int borderType )  
{  
CV\_INSTRUMENT\_REGION();

```
CV_Assert(borderType != BORDER_CONSTANT);

CV_OCL_RUN(_src.dims() <= 2 && _dst.isUMat(),
           ocl_pyrDown(_src, _dst, _dsz, borderType))

CV_OVX_RUN(_src.dims() <= 2,
           openvx_pyrDown(_src, _dst, _dsz, borderType))

Mat src = _src.getMat();
Size dsz = _dsz.empty() ? Size((src.cols + 1)/2, (src.rows + 1)/2) : _dsz;
_dst.create( dsz, src.type() );
Mat dst = _dst.getMat();
int depth = src.depth();

if(src.isSubmatrix() && !(borderType & BORDER_ISOLATED))
{
    Point ofs;
    Size wsz(src.cols, src.rows);
    src.locateROI( wsz, ofs );
    CALL_HAL(pyrDown, cv_hal_pyrdown_offset, src.data, src.step, src.cols, src.rows,
             dst.data, dst.step, dst.cols, dst.rows, depth, src.channels(),
             ofs.x, ofs.y, wsz.width - src.cols - ofs.x, wsz.height - src.rows - ofs.y, borderType & (~BORDER_ISOLATED));
}
else
{
    CALL_HAL(pyrDown, cv_hal_pyrdown, src.data, src.step, src.cols, src.rows, dst.data, dst.step, dst.cols, dst.rows, depth, src.channels(), borderType);
}

```

My questions are :

1. What role does CALL\_HAL play in pyrDown, and how does it impact border handling and ROI consistency?
2. Are there specific considerations when passing ROI offsets and image sizes to CALL\_HAL that might affect the outcome?
3. How do cv\_hal\_pyrdown and cv\_hal\_pyrdown\_offset differ in their handling of ROIs and borders, and what precautions should be taken to ensure consistent results between full-image and ROI-based processing?
4. Are there best practices or examples for modifying pyrDown or similar functions to ensure uniform results across various border types and ROIs?

Any guidance on this or related experiences would be greatly appreciated.

---

<div class="post-metadata">

**Author:** ![sturkmen](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/sturkmen/32/13_2.png) [@sturkmen](https://forum.opencv.org/u/sturkmen)\
**Post date:** [November 14, 2024, 7:21pm UTC](https://forum.opencv.org/t/clarification-on-call-hal-usage-in-pyrdown-and-handling-of-rois-in-opencv/19265/2 "2024-11-14T19:21:52Z")

</div>

here is the ChatGPT explanation 🙂

The `cv::pyrDown` function is designed to downscale an image by a factor of 2, reducing its resolution. It uses Gaussian smoothing to prevent aliasing and has a structure that handles various types of input, optimizations, and low-level operations. Here’s a breakdown of the code:

### Key Steps and Explanation

1. **Instrumentation for Performance Monitoring** :

2. **Asserting Border Type** :

3. **OpenCL Acceleration Check** :

4. **Defining Source and Destination Matrices** :

5. **Handling Submatrix Scenarios** :

6. **Standard Downsampling Call** :

7. **Selecting the Downsampling Function** :

8. **Applying the Downsampling Function** :

### Summary

This `pyrDown` function implementation supports both CPU and GPU acceleration (when using `UMat`), hardware abstraction optimizations via HAL, and data type handling for various depths. It achieves downsampling by combining Gaussian smoothing with rescaling, minimizing aliasing in the output.

---

<div class="post-metadata">

**Author:** ![sturkmen](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/sturkmen/32/13_2.png) [@sturkmen](https://forum.opencv.org/u/sturkmen)\
**Post date:** [November 14, 2024, 7:31pm UTC](https://forum.opencv.org/t/clarification-on-call-hal-usage-in-pyrdown-and-handling-of-rois-in-opencv/19265/3 "2024-11-14T19:31:04Z")

</div>

```auto
void cv::pyrDown( InputArray _src, OutputArray _dst, const Size& _dsz, int borderType )
{
    CV_INSTRUMENT_REGION();

    CV_Assert(borderType != BORDER_CONSTANT);

    CV_OCL_RUN(_src.dims() <= 2 && _dst.isUMat(),
               ocl_pyrDown(_src, _dst, _dsz, borderType))

    Mat src = _src.getMat();
    Size dsz = _dsz.empty() ? Size((src.cols + 1)/2, (src.rows + 1)/2) : _dsz;
    _dst.create( dsz, src.type() );
    Mat dst = _dst.getMat();
    int depth = src.depth();

    if(src.isSubmatrix() && !(borderType & BORDER_ISOLATED))
    {
        Point ofs;
        Size wsz(src.cols, src.rows);
        src.locateROI( wsz, ofs );
        CALL_HAL(pyrDown, cv_hal_pyrdown_offset, src.data, src.step, src.cols, src.rows,
                 dst.data, dst.step, dst.cols, dst.rows, depth, src.channels(),
                 ofs.x, ofs.y, wsz.width - src.cols - ofs.x, wsz.height - src.rows - ofs.y, borderType & (~BORDER_ISOLATED));
    }
    else
    {
        CALL_HAL(pyrDown, cv_hal_pyrdown, src.data, src.step, src.cols, src.rows, dst.data, dst.step, dst.cols, dst.rows, depth, src.channels(), borderType);
    }

    PyrFunc func = 0;
    if( depth == CV_8U )
        func = pyrDown_< FixPtCast<uchar, 8> >;
    else if( depth == CV_16S )
        func = pyrDown_< FixPtCast<short, 8> >;
    else if( depth == CV_16U )
        func = pyrDown_< FixPtCast<ushort, 8> >;
    else if( depth == CV_32F )
        func = pyrDown_< FltCast<float, 8> >;
    else if( depth == CV_64F )
        func = pyrDown_< FltCast<double, 8> >;
    else
        CV_Error( cv::Error::StsUnsupportedFormat, "" );

    func( src, dst, borderType );
}

```

actually `CALL_HAL` do nothing for now. because `cv_hal_pyrdown` and `cv_hal_pyrdown_offset` functions are not implemented yet.

```auto
inline int hal_ni_pyrdown(const uchar* src_data, size_t src_step, int src_width, int src_height, uchar* dst_data, size_t dst_step, int dst_width, int dst_height, int depth, int cn, int border_type) { return CV_HAL_ERROR_NOT_IMPLEMENTED; }

//! @cond IGNORED
#define cv_hal_pyrdown hal_ni_pyrdown
//! @endcond

```

```auto
inline int hal_ni_pyrdown_offset(const uchar* src_data, size_t src_step, int src_width, int src_height,
                                 uchar* dst_data, size_t dst_step, int dst_width, int dst_height,
                                 int depth, int cn, int margin_left, int margin_top, int margin_right, int margin_bottom, int border_type)
{ return CV_HAL_ERROR_NOT_IMPLEMENTED; }

//! @cond IGNORED
#define cv_hal_pyrdown_offset hal_ni_pyrdown_offset

```
