diff --git a/modules/imgproc/CMakeLists.txt b/modules/imgproc/CMakeLists.txt index 4ca31377c4..c0eb22023c 100644 --- a/modules/imgproc/CMakeLists.txt +++ b/modules/imgproc/CMakeLists.txt @@ -3,9 +3,9 @@ ocv_add_dispatched_file(accum SSE4_1 AVX AVX2) ocv_add_dispatched_file(bilateral_filter SSE2 AVX2 AVX512_SKX AVX512_ICL) ocv_add_dispatched_file(box_filter SSE2 SSE4_1 AVX2 AVX512_SKX) ocv_add_dispatched_file(filter SSE2 SSE4_1 AVX2) -ocv_add_dispatched_file(color_hsv SSE2 SSE4_1 AVX2) -ocv_add_dispatched_file(color_rgb SSE2 SSE4_1 AVX2) -ocv_add_dispatched_file(color_yuv SSE2 SSE4_1 AVX2) +ocv_add_dispatched_file(color_hsv SSE2 SSE4_1 AVX2 AVX512_SKX AVX512_ICL) +ocv_add_dispatched_file(color_rgb SSE2 SSE4_1 AVX2 AVX512_SKX AVX512_ICL) +ocv_add_dispatched_file(color_yuv SSE2 SSE4_1 AVX2 AVX512_SKX AVX512_ICL) ocv_add_dispatched_file(median_blur SSE2 SSE4_1 AVX2 AVX512_SKX AVX512_ICL) ocv_add_dispatched_file(morph SSE2 SSE4_1 AVX2) ocv_add_dispatched_file(smooth SSE2 SSE4_1 AVX2 AVX512_ICL) diff --git a/modules/imgproc/src/color_hsv.simd.hpp b/modules/imgproc/src/color_hsv.simd.hpp index 8ae663dff4..e4fbf413d7 100644 --- a/modules/imgproc/src/color_hsv.simd.hpp +++ b/modules/imgproc/src/color_hsv.simd.hpp @@ -100,9 +100,18 @@ struct RGB2HSV_b #if (CV_SIMD || CV_SIMD_SCALABLE) const int vsize = VTraits::vlanes(); - for ( ; i <= n - vsize; + for ( ; i < n; i += vsize, src += scn*vsize, dst += 3*vsize) { + if ( i > n - vsize ) { + if (i == 0 || src == dst) { + break; + } + int backup = i - (n - vsize); + i = n - vsize; + src -= backup * scn; + dst -= backup * 3; + } v_uint8 b, g, r; if(scn == 4) { @@ -310,8 +319,17 @@ struct RGB2HSV_f #if (CV_SIMD || CV_SIMD_SCALABLE) const int vsize = VTraits::vlanes(); - for ( ; i <= n - 3*vsize; i += 3*vsize, src += scn * vsize) + const float* const src0 = src; + for ( ; i < n; i += 3*vsize, src += scn * vsize) { + if ( i > n - 3*vsize ) { + if (i == 0 || src0 == dst) { + break; + } + int backup = (i - (n - 3*vsize)) / 3; + i = n - 3*vsize; + src -= backup * scn; + } v_float32 r, g, b, a; if(scn == 4) { @@ -476,8 +494,17 @@ struct HSV2RGB_f #if (CV_SIMD || CV_SIMD_SCALABLE) const int vsize = VTraits::vlanes(); v_float32 valpha = vx_setall_f32(alpha); - for (; i <= n - vsize*3; i += vsize*3, dst += dcn * vsize) + float* const dst0 = dst; + for (; i < n; i += vsize*3, dst += dcn * vsize) { + if ( i > n - vsize*3 ) { + if (i == 0 || src == dst0) { + break; + } + int backup = (i - (n - vsize*3)) / 3; + i = n - vsize*3; + dst -= backup * dcn; + } v_float32 h, s, v, b, g, r; v_load_deinterleave(src + i, h, s, v); @@ -722,9 +749,18 @@ struct RGB2HLS_f const int vsize = VTraits::vlanes(); v_float32 vhscale = vx_setall_f32(hscale); - for ( ; i <= n - vsize; + for ( ; i < n; i += vsize, src += scn * vsize, dst += 3 * vsize) { + if ( i > n - vsize ) { + if (i == 0 || src == dst) { + break; + } + int backup = i - (n - vsize); + i = n - vsize; + src -= backup * scn; + dst -= backup * 3; + } v_float32 r, g, b, h, l, s; if(scn == 4) @@ -1018,8 +1054,17 @@ struct HLS2RGB_f #if (CV_SIMD || CV_SIMD_SCALABLE) static const int vsize = VTraits::vlanes(); - for (; i <= n - vsize; i += vsize, src += 3*vsize, dst += dcn*vsize) + for (; i < n; i += vsize, src += 3*vsize, dst += dcn*vsize) { + if ( i > n - vsize ) { + if (i == 0 || src == dst) { + break; + } + int backup = i - (n - vsize); + i = n - vsize; + src -= backup * 3; + dst -= backup * dcn; + } v_float32 h, l, s, r, g, b; v_load_deinterleave(src, h, l, s); diff --git a/modules/imgproc/src/color_rgb.simd.hpp b/modules/imgproc/src/color_rgb.simd.hpp index 40e3854460..1013fc7a4c 100644 --- a/modules/imgproc/src/color_rgb.simd.hpp +++ b/modules/imgproc/src/color_rgb.simd.hpp @@ -125,9 +125,18 @@ struct RGB2RGB #if (CV_SIMD || CV_SIMD_SCALABLE) const int vsize = VTraits::vlanes(); - for(; i <= n-vsize; + for(; i < n; i += vsize, src += vsize*scn, dst += vsize*dcn) { + if ( i > n - vsize ) { + if (i == 0 || src == dst) { + break; + } + int backup = i - (n - vsize); + i = n - vsize; + src -= backup * scn; + dst -= backup * dcn; + } vt a, b, c, d; if(scn == 4) { @@ -193,9 +202,18 @@ struct RGB5x52RGB #if (CV_SIMD || CV_SIMD_SCALABLE) const int vsize = VTraits::vlanes(); v_uint8 vz = vx_setzero_u8(), vn0 = vx_setall_u8(255); - for(; i <= n-vsize; + for(; i < n; i += vsize, src += vsize*sizeof(ushort), dst += vsize*dcn) { + if ( i > n - vsize ) { + if (i == 0 || src == dst) { + break; + } + int backup = i - (n - vsize); + i = n - vsize; + src -= backup * sizeof(ushort); + dst -= backup * dcn; + } v_uint16 t0 = v_reinterpret_as_u16(vx_load(src)); v_uint16 t1 = v_reinterpret_as_u16(vx_load(src + sizeof(ushort)*VTraits::vlanes())); @@ -304,9 +322,18 @@ struct RGB2RGB5x5 v_uint16 vn7 = vx_setall_u16((ushort)(~7)); v_uint16 vz = vx_setzero_u16(); v_uint8 v7 = vx_setall_u8((uchar)(~7)); - for(; i <= n-vsize; + for(; i < n; i += vsize, src += vsize*scn, dst += vsize*sizeof(ushort)) { + if ( i > n - vsize ) { + if (i == 0 || src == dst) { + break; + } + int backup = i - (n - vsize); + i = n - vsize; + src -= backup * scn; + dst -= backup * sizeof(ushort); + } v_uint8 r, g, b, a; if(scn == 3) { @@ -399,9 +426,18 @@ struct Gray2RGB #if (CV_SIMD || CV_SIMD_SCALABLE) const int vsize = VTraits::vlanes(); vt valpha = v_set<_Tp>::set(alpha); - for(; i <= n-vsize; + for(; i < n; i += vsize, src += vsize, dst += vsize*dcn) { + if ( i > n - vsize ) { + if (i == 0 || src == dst) { + break; + } + int backup = i - (n - vsize); + i = n - vsize; + src -= backup; + dst -= backup * dcn; + } vt g = vx_load(src); if(dcn == 3) @@ -441,9 +477,18 @@ struct Gray2RGB5x5 #if (CV_SIMD || CV_SIMD_SCALABLE) const int vsize = VTraits::vlanes(); v_uint16 v3 = vx_setall_u16((ushort)(~3)); - for(; i <= n-vsize; + for(; i < n; i += vsize, src += vsize, dst += vsize*sizeof(ushort)) { + if ( i > n - vsize ) { + if (i == 0 || src == dst) { + break; + } + int backup = i - (n - vsize); + i = n - vsize; + src -= backup; + dst -= backup * sizeof(ushort); + } v_uint8 t8 = vx_load_low(src); v_uint16 t = v_expand_low(t8); @@ -512,9 +557,18 @@ struct RGB5x52Gray v_zip(vx_setall_s16(RY), vx_setall_s16( 1), r12y, dummy); v_int16 delta = vx_setall_s16(1 << (shift-1)); - for(; i <= n-vsize; + for(; i < n; i += vsize, src += vsize*sizeof(ushort), dst += vsize) { + if ( i > n - vsize ) { + if (i == 0 || src == dst) { + break; + } + int backup = i - (n - vsize); + i = n - vsize; + src -= backup * sizeof(ushort); + dst -= backup; + } v_uint16 t = vx_load((ushort*)src); v_uint16 r, g, b; @@ -628,9 +682,18 @@ struct RGB2Gray #if (CV_SIMD || CV_SIMD_SCALABLE) const int vsize = VTraits::vlanes(); v_float32 rv = vx_setall_f32(cr), gv = vx_setall_f32(cg), bv = vx_setall_f32(cb); - for(; i <= n-vsize; + for(; i < n; i += vsize, src += vsize*scn, dst += vsize) { + if ( i > n - vsize ) { + if (i == 0 || src == dst) { + break; + } + int backup = i - (n - vsize); + i = n - vsize; + src -= backup * scn; + dst -= backup; + } v_float32 r, g, b, a; if(scn == 3) { @@ -692,9 +755,18 @@ struct RGB2Gray v_zip(vx_setall_s16(cr), vx_setall_s16( 1), r12y, dummy); v_int16 delta = vx_setall_s16(1 << (shift-1)); - for( ; i <= n-vsize; + for( ; i < n; i += vsize, src += scn*vsize, dst += vsize) { + if ( i > n - vsize ) { + if (i == 0 || src == dst) { + break; + } + int backup = i - (n - vsize); + i = n - vsize; + src -= backup * scn; + dst -= backup; + } v_uint8 r, g, b, a; if(scn == 3) { @@ -792,9 +864,18 @@ struct RGB2Gray v_int16 delta = vx_setall_s16(1 << (shift-1)); - for( ; i <= n-vsize; + for( ; i < n; i += vsize, src += scn*vsize, dst += vsize) { + if ( i > n - vsize ) { + if (i == 0 || src == dst) { + break; + } + int backup = i - (n - vsize); + i = n - vsize; + src -= backup * scn; + dst -= backup; + } v_uint16 r, g, b, a; if(scn == 3) { @@ -888,9 +969,18 @@ struct RGBA2mRGBA // processing 4 registers per loop cycle is about 10% faster // than processing 1 register - for( ; i <= n-vsize; + for( ; i < n; i += vsize, src += 4*vsize, dst += 4*vsize) { + if ( i > n - vsize ) { + if (i == 0 || src == dst) { + break; + } + int backup = i - (n - vsize); + i = n - vsize; + src -= backup * 4; + dst -= backup * 4; + } v_uint8 v[4]; for(int j = 0; j < 4; j++) v[j] = vx_load(src + j*vsize); @@ -992,9 +1082,18 @@ struct mRGBA2RGBA v_uint8 amask = v_reinterpret_as_u8(vx_setall_u32(0xFF000000)); v_uint8 vmax = vx_setall_u8(max_val); - for( ; i <= n-vsize/4; + for( ; i < n; i += vsize/4, src += vsize, dst += vsize) { + if ( i > n - vsize/4 ) { + if (i == 0 || src == dst) { + break; + } + int backup = i - (n - vsize/4); + i = n - vsize/4; + src -= backup * 4; + dst -= backup * 4; + } v_uint8 s = vx_load(src + 0*vsize); // r0,g0,b0,a0,r1,g1,b1,a1 => 00,00,00,a0,00,00,00,a1 => diff --git a/modules/imgproc/src/color_yuv.simd.hpp b/modules/imgproc/src/color_yuv.simd.hpp index 44f38a3418..c6bba579a0 100644 --- a/modules/imgproc/src/color_yuv.simd.hpp +++ b/modules/imgproc/src/color_yuv.simd.hpp @@ -161,9 +161,18 @@ struct RGB2YCrCb_f v_float32 vc3 = vx_setall_f32(C3), vc4 = vx_setall_f32(C4); v_float32 vdelta = vx_setall_f32(delta); const int vsize = VTraits::vlanes(); - for( ; i <= n-vsize; + for( ; i < n; i += vsize, src += vsize*scn, dst += vsize*3) { + if ( i > n - vsize ) { + if (i == 0 || src == dst) { + break; + } + int backup = i - (n - vsize); + i = n - vsize; + src -= backup * scn; + dst -= backup * 3; + } v_float32 b, g, r, dummy; if(scn == 3) { @@ -299,9 +308,18 @@ struct RGB2YCrCb_i v_int32 vc4 = vx_setall_s32(C4); v_int32 vdd = vx_setall_s32(sdelta + descale); - for(; i <= n-vsize; + for(; i < n; i += vsize, src += vsize*scn, dst += vsize*3) { + if ( i > n - vsize ) { + if (i == 0 || src == dst) { + break; + } + int backup = i - (n - vsize); + i = n - vsize; + src -= backup * scn; + dst -= backup * 3; + } v_uint16 r, g, b, a; if(scn == 3) { @@ -437,9 +455,18 @@ struct RGB2YCrCb_i v_int16 vdescale = vx_setall_s16(descaleShift); - for( ; i <= n-vsize; + for( ; i < n; i += vsize, src += scn*vsize, dst += 3*vsize) { + if ( i > n - vsize ) { + if (i == 0 || src == dst) { + break; + } + int backup = i - (n - vsize); + i = n - vsize; + src -= backup * scn; + dst -= backup * 3; + } v_uint8 r, g, b, a; if(scn == 3) { @@ -642,9 +669,18 @@ struct YCrCb2RGB_f v_float32 vdelta = vx_setall_f32(delta); v_float32 valpha = vx_setall_f32(alpha); const int vsize = VTraits::vlanes(); - for( ; i <= n-vsize; + for( ; i < n; i += vsize, src += vsize*3, dst += vsize*dcn) { + if ( i > n - vsize ) { + if (i == 0 || src == dst) { + break; + } + int backup = i - (n - vsize); + i = n - vsize; + src -= backup * 3; + dst -= backup * dcn; + } v_float32 y, cr, cb; if(yuvOrder) v_load_deinterleave(src, y, cb, cr); @@ -771,9 +807,18 @@ struct YCrCb2RGB_i // to fit in short by short multiplication v_int16 vc3 = vx_setall_s16(yuvOrder ? (short)(C3-(1 << 15)) : (short)C3); - for( ; i <= n-vsize; + for( ; i < n; i += vsize, src += 3*vsize, dst += dcn*vsize) { + if ( i > n - vsize ) { + if (i == 0 || src == dst) { + break; + } + int backup = i - (n - vsize); + i = n - vsize; + src -= backup * 3; + dst -= backup * dcn; + } v_uint8 y, cr, cb; if(yuvOrder) { @@ -920,9 +965,18 @@ struct YCrCb2RGB_i // to fit in short by short multiplication v_int16 vc3 = vx_setall_s16(yuvOrder ? (short)(C3-(1 << 15)) : (short)C3); v_int32 vdescale = vx_setall_s32(descaleShift); - for(; i <= n-vsize; + for(; i < n; i += vsize, src += vsize*3, dst += vsize*dcn) { + if ( i > n - vsize ) { + if (i == 0 || src == dst) { + break; + } + int backup = i - (n - vsize); + i = n - vsize; + src -= backup * 3; + dst -= backup * dcn; + } v_uint16 y, cr, cb; if(yuvOrder) {