diff --git a/hal/ipp/include/ipp_hal_imgproc.hpp b/hal/ipp/include/ipp_hal_imgproc.hpp index aebe085795b8..65e8ee50a9c0 100644 --- a/hal/ipp/include/ipp_hal_imgproc.hpp +++ b/hal/ipp/include/ipp_hal_imgproc.hpp @@ -20,10 +20,8 @@ #if defined(HAVE_IPP_IW) int ipp_hal_warpAffine(int src_type, 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, const double M[6], int interpolation, int borderType, const double borderValue[4]); - -// Does not pass tests in 5.x branch -//#undef cv_hal_warpAffine -//#define cv_hal_warpAffine ipp_hal_warpAffine +#undef cv_hal_warpAffine +#define cv_hal_warpAffine ipp_hal_warpAffine int ipp_hal_sobel(const uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, int width, int height, int src_depth, int dst_depth, int cn, @@ -45,10 +43,8 @@ int ipp_hal_scharr(const uchar* src_data, size_t src_step, uchar* dst_data, size int ipp_hal_warpPerspective(int src_type, 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, const double M[9], int interpolation, int borderType, const double borderValue[4]); - -// Does not pass tests in 5.x branch -//#undef cv_hal_warpPerspective -//#define cv_hal_warpPerspective ipp_hal_warpPerspective +#undef cv_hal_warpPerspective +#define cv_hal_warpPerspective ipp_hal_warpPerspective #endif // IPP_VERSION_X100 >= 202600 diff --git a/hal/ipp/src/warp_ipp.cpp b/hal/ipp/src/warp_ipp.cpp index 1eea3228ff60..2f1cf87b7395 100644 --- a/hal/ipp/src/warp_ipp.cpp +++ b/hal/ipp/src/warp_ipp.cpp @@ -89,6 +89,12 @@ int ipp_hal_warpAffine(int src_type, const uchar *src_data, size_t src_step, int if((int)ippInter < 0 || interpolation > 2) return CV_HAL_ERROR_NOT_IMPLEMENTED; +#if !defined(IPP_CALLS_ENFORCED) + // ippBorderTransp does not reproduce cv::BORDER_TRANSPARENT for warping + if (borderType == cv::BORDER_TRANSPARENT) + return CV_HAL_ERROR_NOT_IMPLEMENTED; +#endif + #if defined(IPP_CALLS_ENFORCED) /* C1 C2 C3 C4 */ char impl[CV_DEPTH_MAX][4][3]={{{1, 1, 0}, {0, 0, 0}, {1, 1, 0}, {1, 1, 0}}, //8U @@ -99,14 +105,22 @@ int ipp_hal_warpAffine(int src_type, const uchar *src_data, size_t src_step, int {{1, 1, 0}, {0, 0, 0}, {1, 1, 0}, {1, 1, 0}}, //32F {{1, 1, 0}, {0, 0, 0}, {1, 1, 0}, {1, 1, 0}}}; //64F #else // IPP_CALLS_ENFORCED is not defined, results are strictly aligned to OpenCV implementation + // Zeroed entries diverge: + // 16S, 64F - LINEAR differs on 94-99% of pixels (maxdiff 77..106) and NEAREST + // differs on ~0.1% of pixels (maxdiff ~3900): IPP has no 16S/64F + // warp of its own, so IW falls back to a different code path. + // C2 - not implemented by IPP IW yet. + // 8S, 32S - not supported by cv::warpAffine itself. + // CUBIC - never reaches the HAL: genericWarp() in imgwarp.cpp handles + // INTER_CUBIC before hal::warpAffine() is called. /* C1 C2 C3 C4 */ - char impl[CV_DEPTH_MAX][4][3]={{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, //8U + char impl[CV_DEPTH_MAX][4][3]={{{1, 1, 0}, {0, 0, 0}, {1, 1, 0}, {1, 1, 0}}, //8U {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, //8S - {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {1, 0, 0}}, //16U - {{1, 0, 0}, {0, 0, 0}, {1, 0, 0}, {1, 0, 0}}, //16S + {{1, 1, 0}, {0, 0, 0}, {1, 1, 0}, {1, 1, 0}}, //16U + {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, //16S {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, //32S - {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, //32F - {{1, 0, 0}, {0, 0, 0}, {1, 0, 0}, {1, 0, 0}}}; //64F + {{1, 1, 0}, {0, 0, 0}, {1, 1, 0}, {1, 1, 0}}, //32F + {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}}; //64F #endif if(impl[CV_TYPE(src_type)][CV_MAT_CN(src_type)-1][interpolation] == 0) @@ -210,6 +224,13 @@ int ipp_hal_warpPerspective(int src_type, const uchar *src_data, size_t src_step return CV_HAL_ERROR_NOT_IMPLEMENTED; } +#if !defined(IPP_CALLS_ENFORCED) + if (borderType == cv::BORDER_TRANSPARENT) + { + return CV_HAL_ERROR_NOT_IMPLEMENTED; + } +#endif + // Unsupported source type if (src_type != CV_8UC1 && src_type != CV_8UC3 && src_type != CV_8UC4 && src_type != CV_16UC1 && src_type != CV_16UC3 && src_type != CV_16UC4 && @@ -229,13 +250,20 @@ int ipp_hal_warpPerspective(int src_type, const uchar *src_data, size_t src_step {{1, 1}, {0, 0}, {1, 1}, {1, 1}}, //32F {{0, 0}, {0, 0}, {0, 0}, {0, 0}}}; //64F #else // IPP_CALLS_ENFORCED is not defined, results are strictly aligned to OpenCV implementation + // Zeroed entries diverge: + // NEAREST for 8U/16U/32F - differs on a handful of pixels (1 per channel) where + // the sample coordinate lands exactly on a .5 boundary and IPP rounds + // the opposite way from cvRound(); maxdiff is a full pixel value. + // LINEAR for 16S - differs on 90-97% of pixels (maxdiff 92..100). + // C2 - not implemented by IPP IW, always declines. + // 8S, 32S, 64F - unsupported: rejected by the src_type check above. /* C1 C2 C3 C4 */ - char impl[CV_DEPTH_MAX][4][2]={{{0, 0}, {0, 0}, {0, 0}, {0, 0}}, //8U + char impl[CV_DEPTH_MAX][4][2]={{{0, 1}, {0, 0}, {0, 1}, {0, 1}}, //8U {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, //8S - {{0, 0}, {0, 0}, {0, 0}, {0, 1}}, //16U - {{1, 1}, {0, 0}, {1, 0}, {1, 1}}, //16S - {{1, 1}, {0, 0}, {1, 0}, {1, 1}}, //32S - {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, //32F + {{0, 1}, {0, 0}, {0, 1}, {0, 1}}, //16U + {{1, 0}, {0, 0}, {1, 0}, {1, 0}}, //16S + {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, //32S + {{0, 1}, {0, 0}, {0, 1}, {0, 1}}, //32F {{0, 0}, {0, 0}, {0, 0}, {0, 0}}}; //64F #endif