1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-29 07:13:02 +04:00

Merge pull request #28992 from amd:fast_convert

Improved color convert and AVX512 dispatch added #28992

### Pull Request Readiness Checklist

See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request

- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [ ] There is a reference to the original bug report and related work
- [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
      Patch to opencv_extra has the same branch name.
- [x] The feature is well documented and sample code can be built with the project CMake
This commit is contained in:
Madan mohan Manokar
2026-06-18 17:50:11 +05:30
committed by GitHub
parent bc18ec2ed3
commit d0925fa360
4 changed files with 223 additions and 25 deletions
+3 -3
View File
@@ -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)
+50 -5
View File
@@ -100,9 +100,18 @@ struct RGB2HSV_b
#if (CV_SIMD || CV_SIMD_SCALABLE)
const int vsize = VTraits<v_uint8>::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<v_float32>::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<v_float32>::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<v_float32>::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<v_float32>::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);
+110 -11
View File
@@ -125,9 +125,18 @@ struct RGB2RGB
#if (CV_SIMD || CV_SIMD_SCALABLE)
const int vsize = VTraits<vt>::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<v_uint8>::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<v_uint16>::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<vt>::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<v_uint16>::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<float>
#if (CV_SIMD || CV_SIMD_SCALABLE)
const int vsize = VTraits<v_float32>::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<uchar>
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<ushort>
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<uchar>
// 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<uchar>
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 =>
+60 -6
View File
@@ -161,9 +161,18 @@ struct RGB2YCrCb_f<float>
v_float32 vc3 = vx_setall_f32(C3), vc4 = vx_setall_f32(C4);
v_float32 vdelta = vx_setall_f32(delta);
const int vsize = VTraits<v_float32>::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<ushort>
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<uchar>
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<float>
v_float32 vdelta = vx_setall_f32(delta);
v_float32 valpha = vx_setall_f32(alpha);
const int vsize = VTraits<v_float32>::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<uchar>
// 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<ushort>
// 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)
{