mirror of
https://github.com/opencv/opencv.git
synced 2025-06-08 01:53:19 +08:00
imgproc: dispatch color*
Lab/XYZ modes have been postponed (color_lab.cpp): - need to split code for tables initialization and for pixels processing first - no significant performance improvements for switching between SSE42 / AVX2 code generation
This commit is contained in:
parent
39783a6584
commit
8b541e450b
@ -124,6 +124,10 @@
|
|||||||
|
|
||||||
#if defined CV_CPU_COMPILE_AVX && !defined CV_CPU_BASELINE_COMPILE_AVX
|
#if defined CV_CPU_COMPILE_AVX && !defined CV_CPU_BASELINE_COMPILE_AVX
|
||||||
struct VZeroUpperGuard {
|
struct VZeroUpperGuard {
|
||||||
|
#ifdef __GNUC__
|
||||||
|
__attribute__((always_inline))
|
||||||
|
#endif
|
||||||
|
inline VZeroUpperGuard() { _mm256_zeroupper(); }
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
__attribute__((always_inline))
|
__attribute__((always_inline))
|
||||||
#endif
|
#endif
|
||||||
|
@ -796,9 +796,9 @@ CV_EXPORTS InstrNode* getCurrentNode();
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __CV_AVX_GUARD
|
#ifdef __CV_AVX_GUARD
|
||||||
#define CV_INSTRUMENT_REGION(); __CV_AVX_GUARD CV_INSTRUMENT_REGION_();
|
#define CV_INSTRUMENT_REGION() __CV_AVX_GUARD CV_INSTRUMENT_REGION_();
|
||||||
#else
|
#else
|
||||||
#define CV_INSTRUMENT_REGION(); CV_INSTRUMENT_REGION_();
|
#define CV_INSTRUMENT_REGION() CV_INSTRUMENT_REGION_();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace cv {
|
namespace cv {
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
set(the_description "Image Processing")
|
set(the_description "Image Processing")
|
||||||
ocv_add_dispatched_file(accum SSE4_1 AVX AVX2)
|
ocv_add_dispatched_file(accum SSE4_1 AVX 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_define_module(imgproc opencv_core WRAP java python js)
|
ocv_define_module(imgproc opencv_core WRAP java python js)
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
// of this distribution and at http://opencv.org/license.html
|
// of this distribution and at http://opencv.org/license.html
|
||||||
|
|
||||||
#include "precomp.hpp"
|
#include "precomp.hpp"
|
||||||
|
#include "opencl_kernels_imgproc.hpp"
|
||||||
#include "color.hpp"
|
#include "color.hpp"
|
||||||
|
|
||||||
namespace cv
|
namespace cv
|
||||||
|
@ -3,59 +3,17 @@
|
|||||||
// of this distribution and at http://opencv.org/license.html
|
// of this distribution and at http://opencv.org/license.html
|
||||||
|
|
||||||
#include "opencv2/imgproc.hpp"
|
#include "opencv2/imgproc.hpp"
|
||||||
#include "opencv2/core/utility.hpp"
|
|
||||||
#include <limits>
|
|
||||||
#include "opencl_kernels_imgproc.hpp"
|
|
||||||
#include "hal_replacement.hpp"
|
#include "hal_replacement.hpp"
|
||||||
#include "opencv2/core/hal/intrin.hpp"
|
|
||||||
#include "opencv2/core/softfloat.hpp"
|
|
||||||
|
|
||||||
#define CV_DESCALE(x,n) (((x) + (1 << ((n)-1))) >> (n))
|
namespace cv {
|
||||||
|
|
||||||
namespace cv
|
|
||||||
{
|
|
||||||
|
|
||||||
//constants for conversion from/to RGB and Gray, YUV, YCrCb according to BT.601
|
|
||||||
const float B2YF = 0.114f;
|
|
||||||
const float G2YF = 0.587f;
|
|
||||||
const float R2YF = 0.299f;
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
yuv_shift = 14,
|
|
||||||
xyz_shift = 12,
|
|
||||||
R2Y = 4899, // == R2YF*16384
|
|
||||||
G2Y = 9617, // == G2YF*16384
|
|
||||||
B2Y = 1868, // == B2YF*16384
|
|
||||||
BLOCK_SIZE = 256
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename _Tp> struct ColorChannel
|
|
||||||
{
|
|
||||||
typedef float worktype_f;
|
|
||||||
static _Tp max() { return std::numeric_limits<_Tp>::max(); }
|
|
||||||
static _Tp half() { return (_Tp)(max()/2 + 1); }
|
|
||||||
};
|
|
||||||
|
|
||||||
template<> struct ColorChannel<float>
|
|
||||||
{
|
|
||||||
typedef float worktype_f;
|
|
||||||
static float max() { return 1.f; }
|
|
||||||
static float half() { return 0.5f; }
|
|
||||||
};
|
|
||||||
|
|
||||||
/*template<> struct ColorChannel<double>
|
|
||||||
{
|
|
||||||
typedef double worktype_f;
|
|
||||||
static double max() { return 1.; }
|
|
||||||
static double half() { return 0.5; }
|
|
||||||
};*/
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Helper functions
|
// Helper functions
|
||||||
//
|
//
|
||||||
|
|
||||||
namespace {
|
namespace impl {
|
||||||
|
|
||||||
|
#include "color.simd_helpers.hpp"
|
||||||
|
|
||||||
inline bool isHSV(int code)
|
inline bool isHSV(int code)
|
||||||
{
|
{
|
||||||
@ -209,40 +167,9 @@ inline int uIndex(int code)
|
|||||||
}
|
}
|
||||||
|
|
||||||
} // namespace::
|
} // namespace::
|
||||||
|
using namespace impl;
|
||||||
|
|
||||||
template<int i0, int i1 = -1, int i2 = -1>
|
/*template< typename VScn, typename VDcn, typename VDepth, SizePolicy sizePolicy = NONE >
|
||||||
struct Set
|
|
||||||
{
|
|
||||||
static bool contains(int i)
|
|
||||||
{
|
|
||||||
return (i == i0 || i == i1 || i == i2);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<int i0, int i1>
|
|
||||||
struct Set<i0, i1, -1>
|
|
||||||
{
|
|
||||||
static bool contains(int i)
|
|
||||||
{
|
|
||||||
return (i == i0 || i == i1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<int i0>
|
|
||||||
struct Set<i0, -1, -1>
|
|
||||||
{
|
|
||||||
static bool contains(int i)
|
|
||||||
{
|
|
||||||
return (i == i0);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
enum SizePolicy
|
|
||||||
{
|
|
||||||
TO_YUV, FROM_YUV, NONE
|
|
||||||
};
|
|
||||||
|
|
||||||
template< typename VScn, typename VDcn, typename VDepth, SizePolicy sizePolicy = NONE >
|
|
||||||
struct CvtHelper
|
struct CvtHelper
|
||||||
{
|
{
|
||||||
CvtHelper(InputArray _src, OutputArray _dst, int dcn)
|
CvtHelper(InputArray _src, OutputArray _dst, int dcn)
|
||||||
@ -282,7 +209,7 @@ struct CvtHelper
|
|||||||
Mat src, dst;
|
Mat src, dst;
|
||||||
int depth, scn;
|
int depth, scn;
|
||||||
Size dstSz;
|
Size dstSz;
|
||||||
};
|
};*/
|
||||||
|
|
||||||
#ifdef HAVE_OPENCL
|
#ifdef HAVE_OPENCL
|
||||||
|
|
||||||
@ -380,49 +307,7 @@ struct OclHelper
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
///////////////////////////// Top-level template function ////////////////////////////////
|
|
||||||
|
|
||||||
template <typename Cvt>
|
|
||||||
class CvtColorLoop_Invoker : public ParallelLoopBody
|
|
||||||
{
|
|
||||||
typedef typename Cvt::channel_type _Tp;
|
|
||||||
public:
|
|
||||||
|
|
||||||
CvtColorLoop_Invoker(const uchar * src_data_, size_t src_step_, uchar * dst_data_, size_t dst_step_, int width_, const Cvt& _cvt) :
|
|
||||||
ParallelLoopBody(), src_data(src_data_), src_step(src_step_), dst_data(dst_data_), dst_step(dst_step_),
|
|
||||||
width(width_), cvt(_cvt)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void operator()(const Range& range) const CV_OVERRIDE
|
|
||||||
{
|
|
||||||
CV_TRACE_FUNCTION();
|
|
||||||
|
|
||||||
const uchar* yS = src_data + static_cast<size_t>(range.start) * src_step;
|
|
||||||
uchar* yD = dst_data + static_cast<size_t>(range.start) * dst_step;
|
|
||||||
|
|
||||||
for( int i = range.start; i < range.end; ++i, yS += src_step, yD += dst_step )
|
|
||||||
cvt(reinterpret_cast<const _Tp*>(yS), reinterpret_cast<_Tp*>(yD), width);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
const uchar * src_data;
|
|
||||||
const size_t src_step;
|
|
||||||
uchar * dst_data;
|
|
||||||
const size_t dst_step;
|
|
||||||
const int width;
|
|
||||||
const Cvt& cvt;
|
|
||||||
|
|
||||||
const CvtColorLoop_Invoker& operator= (const CvtColorLoop_Invoker&);
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename Cvt>
|
|
||||||
void CvtColorLoop(const uchar * src_data, size_t src_step, uchar * dst_data, size_t dst_step, int width, int height, const Cvt& cvt)
|
|
||||||
{
|
|
||||||
parallel_for_(Range(0, height),
|
|
||||||
CvtColorLoop_Invoker<Cvt>(src_data, src_step, dst_data, dst_step, width, cvt),
|
|
||||||
(width * height) / static_cast<double>(1<<16));
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined (HAVE_IPP) && (IPP_VERSION_X100 >= 700)
|
#if defined (HAVE_IPP) && (IPP_VERSION_X100 >= 700)
|
||||||
# define NEED_IPP 1
|
# define NEED_IPP 1
|
||||||
|
@ -2,23 +2,14 @@
|
|||||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||||
// of this distribution and at http://opencv.org/license.html
|
// of this distribution and at http://opencv.org/license.html
|
||||||
|
|
||||||
#include "opencv2/imgproc.hpp"
|
|
||||||
#include "opencv2/core/utility.hpp"
|
|
||||||
#include <limits>
|
|
||||||
#include "opencl_kernels_imgproc.hpp"
|
|
||||||
#include "hal_replacement.hpp"
|
|
||||||
#include "opencv2/core/hal/intrin.hpp"
|
|
||||||
#include "opencv2/core/softfloat.hpp"
|
|
||||||
|
|
||||||
#define CV_DESCALE(x,n) (((x) + (1 << ((n)-1))) >> (n))
|
#define CV_DESCALE(x,n) (((x) + (1 << ((n)-1))) >> (n))
|
||||||
|
|
||||||
namespace cv
|
namespace {
|
||||||
{
|
|
||||||
|
|
||||||
//constants for conversion from/to RGB and Gray, YUV, YCrCb according to BT.601
|
//constants for conversion from/to RGB and Gray, YUV, YCrCb according to BT.601
|
||||||
const float B2YF = 0.114f;
|
static const float B2YF = 0.114f;
|
||||||
const float G2YF = 0.587f;
|
static const float G2YF = 0.587f;
|
||||||
const float R2YF = 0.299f;
|
static const float R2YF = 0.299f;
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
@ -33,15 +24,15 @@ enum
|
|||||||
template<typename _Tp> struct ColorChannel
|
template<typename _Tp> struct ColorChannel
|
||||||
{
|
{
|
||||||
typedef float worktype_f;
|
typedef float worktype_f;
|
||||||
static _Tp max() { return std::numeric_limits<_Tp>::max(); }
|
static inline _Tp max() { return std::numeric_limits<_Tp>::max(); }
|
||||||
static _Tp half() { return (_Tp)(max()/2 + 1); }
|
static inline _Tp half() { return (_Tp)(max()/2 + 1); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<> struct ColorChannel<float>
|
template<> struct ColorChannel<float>
|
||||||
{
|
{
|
||||||
typedef float worktype_f;
|
typedef float worktype_f;
|
||||||
static float max() { return 1.f; }
|
static inline float max() { return 1.f; }
|
||||||
static float half() { return 0.5f; }
|
static inline float half() { return 0.5f; }
|
||||||
};
|
};
|
||||||
|
|
||||||
/*template<> struct ColorChannel<double>
|
/*template<> struct ColorChannel<double>
|
||||||
@ -51,169 +42,11 @@ template<> struct ColorChannel<float>
|
|||||||
static double half() { return 0.5; }
|
static double half() { return 0.5; }
|
||||||
};*/
|
};*/
|
||||||
|
|
||||||
//
|
|
||||||
// Helper functions
|
|
||||||
//
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
inline bool isHSV(int code)
|
|
||||||
{
|
|
||||||
switch(code)
|
|
||||||
{
|
|
||||||
case COLOR_HSV2BGR: case COLOR_HSV2RGB: case COLOR_HSV2BGR_FULL: case COLOR_HSV2RGB_FULL:
|
|
||||||
case COLOR_BGR2HSV: case COLOR_RGB2HSV: case COLOR_BGR2HSV_FULL: case COLOR_RGB2HSV_FULL:
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool isLab(int code)
|
|
||||||
{
|
|
||||||
switch (code)
|
|
||||||
{
|
|
||||||
case COLOR_Lab2BGR: case COLOR_Lab2RGB: case COLOR_Lab2LBGR: case COLOR_Lab2LRGB:
|
|
||||||
case COLOR_BGR2Lab: case COLOR_RGB2Lab: case COLOR_LBGR2Lab: case COLOR_LRGB2Lab:
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool is_sRGB(int code)
|
|
||||||
{
|
|
||||||
switch (code)
|
|
||||||
{
|
|
||||||
case COLOR_BGR2Lab: case COLOR_RGB2Lab: case COLOR_BGR2Luv: case COLOR_RGB2Luv:
|
|
||||||
case COLOR_Lab2BGR: case COLOR_Lab2RGB: case COLOR_Luv2BGR: case COLOR_Luv2RGB:
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool swapBlue(int code)
|
|
||||||
{
|
|
||||||
switch (code)
|
|
||||||
{
|
|
||||||
case COLOR_BGR2BGRA: case COLOR_BGRA2BGR:
|
|
||||||
case COLOR_BGR2BGR565: case COLOR_BGR2BGR555: case COLOR_BGRA2BGR565: case COLOR_BGRA2BGR555:
|
|
||||||
case COLOR_BGR5652BGR: case COLOR_BGR5552BGR: case COLOR_BGR5652BGRA: case COLOR_BGR5552BGRA:
|
|
||||||
case COLOR_BGR2GRAY: case COLOR_BGRA2GRAY:
|
|
||||||
case COLOR_BGR2YCrCb: case COLOR_BGR2YUV:
|
|
||||||
case COLOR_YCrCb2BGR: case COLOR_YUV2BGR:
|
|
||||||
case COLOR_BGR2XYZ: case COLOR_XYZ2BGR:
|
|
||||||
case COLOR_BGR2HSV: case COLOR_BGR2HLS: case COLOR_BGR2HSV_FULL: case COLOR_BGR2HLS_FULL:
|
|
||||||
case COLOR_YUV2BGR_YV12: case COLOR_YUV2BGRA_YV12: case COLOR_YUV2BGR_IYUV: case COLOR_YUV2BGRA_IYUV:
|
|
||||||
case COLOR_YUV2BGR_NV21: case COLOR_YUV2BGRA_NV21: case COLOR_YUV2BGR_NV12: case COLOR_YUV2BGRA_NV12:
|
|
||||||
case COLOR_Lab2BGR: case COLOR_Luv2BGR: case COLOR_Lab2LBGR: case COLOR_Luv2LBGR:
|
|
||||||
case COLOR_BGR2Lab: case COLOR_BGR2Luv: case COLOR_LBGR2Lab: case COLOR_LBGR2Luv:
|
|
||||||
case COLOR_HSV2BGR: case COLOR_HLS2BGR: case COLOR_HSV2BGR_FULL: case COLOR_HLS2BGR_FULL:
|
|
||||||
case COLOR_YUV2BGR_UYVY: case COLOR_YUV2BGRA_UYVY: case COLOR_YUV2BGR_YUY2:
|
|
||||||
case COLOR_YUV2BGRA_YUY2: case COLOR_YUV2BGR_YVYU: case COLOR_YUV2BGRA_YVYU:
|
|
||||||
case COLOR_BGR2YUV_IYUV: case COLOR_BGRA2YUV_IYUV: case COLOR_BGR2YUV_YV12: case COLOR_BGRA2YUV_YV12:
|
|
||||||
return false;
|
|
||||||
default:
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool isFullRangeHSV(int code)
|
|
||||||
{
|
|
||||||
switch (code)
|
|
||||||
{
|
|
||||||
case COLOR_BGR2HSV_FULL: case COLOR_RGB2HSV_FULL: case COLOR_BGR2HLS_FULL: case COLOR_RGB2HLS_FULL:
|
|
||||||
case COLOR_HSV2BGR_FULL: case COLOR_HSV2RGB_FULL: case COLOR_HLS2BGR_FULL: case COLOR_HLS2RGB_FULL:
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int dstChannels(int code)
|
|
||||||
{
|
|
||||||
switch( code )
|
|
||||||
{
|
|
||||||
case COLOR_BGR2BGRA: case COLOR_RGB2BGRA: case COLOR_BGRA2RGBA:
|
|
||||||
case COLOR_BGR5652BGRA: case COLOR_BGR5552BGRA: case COLOR_BGR5652RGBA: case COLOR_BGR5552RGBA:
|
|
||||||
case COLOR_GRAY2BGRA:
|
|
||||||
case COLOR_YUV2BGRA_NV21: case COLOR_YUV2RGBA_NV21: case COLOR_YUV2BGRA_NV12: case COLOR_YUV2RGBA_NV12:
|
|
||||||
case COLOR_YUV2BGRA_YV12: case COLOR_YUV2RGBA_YV12: case COLOR_YUV2BGRA_IYUV: case COLOR_YUV2RGBA_IYUV:
|
|
||||||
case COLOR_YUV2RGBA_UYVY: case COLOR_YUV2BGRA_UYVY: case COLOR_YUV2RGBA_YVYU: case COLOR_YUV2BGRA_YVYU:
|
|
||||||
case COLOR_YUV2RGBA_YUY2: case COLOR_YUV2BGRA_YUY2:
|
|
||||||
|
|
||||||
return 4;
|
|
||||||
|
|
||||||
case COLOR_BGRA2BGR: case COLOR_RGBA2BGR: case COLOR_RGB2BGR:
|
|
||||||
case COLOR_BGR5652BGR: case COLOR_BGR5552BGR: case COLOR_BGR5652RGB: case COLOR_BGR5552RGB:
|
|
||||||
case COLOR_GRAY2BGR:
|
|
||||||
case COLOR_YUV2BGR_NV21: case COLOR_YUV2RGB_NV21: case COLOR_YUV2BGR_NV12: case COLOR_YUV2RGB_NV12:
|
|
||||||
case COLOR_YUV2BGR_YV12: case COLOR_YUV2RGB_YV12: case COLOR_YUV2BGR_IYUV: case COLOR_YUV2RGB_IYUV:
|
|
||||||
case COLOR_YUV2RGB_UYVY: case COLOR_YUV2BGR_UYVY: case COLOR_YUV2RGB_YVYU: case COLOR_YUV2BGR_YVYU:
|
|
||||||
case COLOR_YUV2RGB_YUY2: case COLOR_YUV2BGR_YUY2:
|
|
||||||
|
|
||||||
return 3;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int greenBits(int code)
|
|
||||||
{
|
|
||||||
switch( code )
|
|
||||||
{
|
|
||||||
case COLOR_BGR2BGR565: case COLOR_RGB2BGR565: case COLOR_BGRA2BGR565: case COLOR_RGBA2BGR565:
|
|
||||||
case COLOR_BGR5652BGR: case COLOR_BGR5652RGB: case COLOR_BGR5652BGRA: case COLOR_BGR5652RGBA:
|
|
||||||
case COLOR_BGR5652GRAY: case COLOR_GRAY2BGR565:
|
|
||||||
|
|
||||||
return 6;
|
|
||||||
|
|
||||||
case COLOR_BGR2BGR555: case COLOR_RGB2BGR555: case COLOR_BGRA2BGR555: case COLOR_RGBA2BGR555:
|
|
||||||
case COLOR_BGR5552BGR: case COLOR_BGR5552RGB: case COLOR_BGR5552BGRA: case COLOR_BGR5552RGBA:
|
|
||||||
case COLOR_BGR5552GRAY: case COLOR_GRAY2BGR555:
|
|
||||||
|
|
||||||
return 5;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int uIndex(int code)
|
|
||||||
{
|
|
||||||
switch( code )
|
|
||||||
{
|
|
||||||
case COLOR_RGB2YUV_YV12: case COLOR_BGR2YUV_YV12: case COLOR_RGBA2YUV_YV12: case COLOR_BGRA2YUV_YV12:
|
|
||||||
|
|
||||||
return 2;
|
|
||||||
|
|
||||||
case COLOR_YUV2RGB_YVYU: case COLOR_YUV2BGR_YVYU: case COLOR_YUV2RGBA_YVYU: case COLOR_YUV2BGRA_YVYU:
|
|
||||||
case COLOR_RGB2YUV_IYUV: case COLOR_BGR2YUV_IYUV: case COLOR_RGBA2YUV_IYUV: case COLOR_BGRA2YUV_IYUV:
|
|
||||||
case COLOR_YUV2BGR_NV21: case COLOR_YUV2RGB_NV21: case COLOR_YUV2BGRA_NV21: case COLOR_YUV2RGBA_NV21:
|
|
||||||
case COLOR_YUV2BGR_YV12: case COLOR_YUV2RGB_YV12: case COLOR_YUV2BGRA_YV12: case COLOR_YUV2RGBA_YV12:
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
case COLOR_YUV2BGR_NV12: case COLOR_YUV2RGB_NV12: case COLOR_YUV2BGRA_NV12: case COLOR_YUV2RGBA_NV12:
|
|
||||||
case COLOR_YUV2BGR_IYUV: case COLOR_YUV2RGB_IYUV: case COLOR_YUV2BGRA_IYUV: case COLOR_YUV2RGBA_IYUV:
|
|
||||||
case COLOR_YUV2RGB_UYVY: case COLOR_YUV2BGR_UYVY: case COLOR_YUV2RGBA_UYVY: case COLOR_YUV2BGRA_UYVY:
|
|
||||||
case COLOR_YUV2RGB_YUY2: case COLOR_YUV2BGR_YUY2: case COLOR_YUV2RGBA_YUY2: case COLOR_YUV2BGRA_YUY2:
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace::
|
|
||||||
|
|
||||||
template<int i0, int i1 = -1, int i2 = -1>
|
template<int i0, int i1 = -1, int i2 = -1>
|
||||||
struct Set
|
struct Set
|
||||||
{
|
{
|
||||||
static bool contains(int i)
|
static inline bool contains(int i)
|
||||||
{
|
{
|
||||||
return (i == i0 || i == i1 || i == i2);
|
return (i == i0 || i == i1 || i == i2);
|
||||||
}
|
}
|
||||||
@ -222,7 +55,7 @@ struct Set
|
|||||||
template<int i0, int i1>
|
template<int i0, int i1>
|
||||||
struct Set<i0, i1, -1>
|
struct Set<i0, i1, -1>
|
||||||
{
|
{
|
||||||
static bool contains(int i)
|
static inline bool contains(int i)
|
||||||
{
|
{
|
||||||
return (i == i0 || i == i1);
|
return (i == i0 || i == i1);
|
||||||
}
|
}
|
||||||
@ -231,7 +64,7 @@ struct Set<i0, i1, -1>
|
|||||||
template<int i0>
|
template<int i0>
|
||||||
struct Set<i0, -1, -1>
|
struct Set<i0, -1, -1>
|
||||||
{
|
{
|
||||||
static bool contains(int i)
|
static inline bool contains(int i)
|
||||||
{
|
{
|
||||||
return (i == i0);
|
return (i == i0);
|
||||||
}
|
}
|
||||||
@ -284,101 +117,6 @@ struct CvtHelper
|
|||||||
Size dstSz;
|
Size dstSz;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef HAVE_OPENCL
|
|
||||||
|
|
||||||
template< typename VScn, typename VDcn, typename VDepth, SizePolicy sizePolicy = NONE >
|
|
||||||
struct OclHelper
|
|
||||||
{
|
|
||||||
OclHelper( InputArray _src, OutputArray _dst, int dcn) :
|
|
||||||
nArgs(0)
|
|
||||||
{
|
|
||||||
src = _src.getUMat();
|
|
||||||
Size sz = src.size(), dstSz;
|
|
||||||
int scn = src.channels();
|
|
||||||
int depth = src.depth();
|
|
||||||
|
|
||||||
CV_Assert( VScn::contains(scn) && VDcn::contains(dcn) && VDepth::contains(depth) );
|
|
||||||
switch (sizePolicy)
|
|
||||||
{
|
|
||||||
case TO_YUV:
|
|
||||||
CV_Assert( sz.width % 2 == 0 && sz.height % 2 == 0 );
|
|
||||||
dstSz = Size(sz.width, sz.height / 2 * 3);
|
|
||||||
break;
|
|
||||||
case FROM_YUV:
|
|
||||||
CV_Assert( sz.width % 2 == 0 && sz.height % 3 == 0 );
|
|
||||||
dstSz = Size(sz.width, sz.height * 2 / 3);
|
|
||||||
break;
|
|
||||||
case NONE:
|
|
||||||
default:
|
|
||||||
dstSz = sz;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
_dst.create(dstSz, CV_MAKETYPE(depth, dcn));
|
|
||||||
dst = _dst.getUMat();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool createKernel(cv::String name, ocl::ProgramSource& source, cv::String options)
|
|
||||||
{
|
|
||||||
ocl::Device dev = ocl::Device::getDefault();
|
|
||||||
int pxPerWIy = dev.isIntel() && (dev.type() & ocl::Device::TYPE_GPU) ? 4 : 1;
|
|
||||||
int pxPerWIx = 1;
|
|
||||||
|
|
||||||
cv::String baseOptions = format("-D depth=%d -D scn=%d -D PIX_PER_WI_Y=%d ",
|
|
||||||
src.depth(), src.channels(), pxPerWIy);
|
|
||||||
|
|
||||||
switch (sizePolicy)
|
|
||||||
{
|
|
||||||
case TO_YUV:
|
|
||||||
if (dev.isIntel() &&
|
|
||||||
src.cols % 4 == 0 && src.step % 4 == 0 && src.offset % 4 == 0 &&
|
|
||||||
dst.step % 4 == 0 && dst.offset % 4 == 0)
|
|
||||||
{
|
|
||||||
pxPerWIx = 2;
|
|
||||||
}
|
|
||||||
globalSize[0] = (size_t)dst.cols/(2*pxPerWIx);
|
|
||||||
globalSize[1] = ((size_t)dst.rows/3 + pxPerWIy - 1) / pxPerWIy;
|
|
||||||
baseOptions += format("-D PIX_PER_WI_X=%d ", pxPerWIx);
|
|
||||||
break;
|
|
||||||
case FROM_YUV:
|
|
||||||
globalSize[0] = (size_t)dst.cols/2;
|
|
||||||
globalSize[1] = ((size_t)dst.rows/2 + pxPerWIy - 1) / pxPerWIy;
|
|
||||||
break;
|
|
||||||
case NONE:
|
|
||||||
default:
|
|
||||||
globalSize[0] = (size_t)src.cols;
|
|
||||||
globalSize[1] = ((size_t)src.rows + pxPerWIy - 1) / pxPerWIy;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
k.create(name.c_str(), source, baseOptions + options);
|
|
||||||
|
|
||||||
if(k.empty())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
nArgs = k.set(0, ocl::KernelArg::ReadOnlyNoSize(src));
|
|
||||||
nArgs = k.set(nArgs, ocl::KernelArg::WriteOnly(dst));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool run()
|
|
||||||
{
|
|
||||||
return k.run(2, globalSize, NULL, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
void setArg(const T& arg)
|
|
||||||
{
|
|
||||||
nArgs = k.set(nArgs, arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
UMat src, dst;
|
|
||||||
ocl::Kernel k;
|
|
||||||
size_t globalSize[2];
|
|
||||||
int nArgs;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
///////////////////////////// Top-level template function ////////////////////////////////
|
///////////////////////////// Top-level template function ////////////////////////////////
|
||||||
|
|
||||||
@ -413,261 +151,17 @@ private:
|
|||||||
const int width;
|
const int width;
|
||||||
const Cvt& cvt;
|
const Cvt& cvt;
|
||||||
|
|
||||||
const CvtColorLoop_Invoker& operator= (const CvtColorLoop_Invoker&);
|
CvtColorLoop_Invoker(const CvtColorLoop_Invoker&); // = delete;
|
||||||
|
const CvtColorLoop_Invoker& operator= (const CvtColorLoop_Invoker&); // = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Cvt>
|
template <typename Cvt> static inline
|
||||||
void CvtColorLoop(const uchar * src_data, size_t src_step, uchar * dst_data, size_t dst_step, int width, int height, const Cvt& cvt)
|
void CvtColorLoop(const uchar * src_data, size_t src_step, uchar * dst_data, size_t dst_step, int width, int height, const Cvt& cvt)
|
||||||
{
|
{
|
||||||
|
CV_AVX_GUARD
|
||||||
parallel_for_(Range(0, height),
|
parallel_for_(Range(0, height),
|
||||||
CvtColorLoop_Invoker<Cvt>(src_data, src_step, dst_data, dst_step, width, cvt),
|
CvtColorLoop_Invoker<Cvt>(src_data, src_step, dst_data, dst_step, width, cvt),
|
||||||
(width * height) / static_cast<double>(1<<16));
|
(width * height) / static_cast<double>(1<<16));
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined (HAVE_IPP) && (IPP_VERSION_X100 >= 700)
|
} //namespace
|
||||||
# define NEED_IPP 1
|
|
||||||
#else
|
|
||||||
# define NEED_IPP 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if NEED_IPP
|
|
||||||
|
|
||||||
#define MAX_IPP8u 255
|
|
||||||
#define MAX_IPP16u 65535
|
|
||||||
#define MAX_IPP32f 1.0
|
|
||||||
|
|
||||||
typedef IppStatus (CV_STDCALL* ippiReorderFunc)(const void *, int, void *, int, IppiSize, const int *);
|
|
||||||
typedef IppStatus (CV_STDCALL* ippiGeneralFunc)(const void *, int, void *, int, IppiSize);
|
|
||||||
typedef IppStatus (CV_STDCALL* ippiColor2GrayFunc)(const void *, int, void *, int, IppiSize, const Ipp32f *);
|
|
||||||
|
|
||||||
template <typename Cvt>
|
|
||||||
class CvtColorIPPLoop_Invoker :
|
|
||||||
public ParallelLoopBody
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
CvtColorIPPLoop_Invoker(const uchar * src_data_, size_t src_step_, uchar * dst_data_, size_t dst_step_, int width_, const Cvt& _cvt, bool *_ok) :
|
|
||||||
ParallelLoopBody(), src_data(src_data_), src_step(src_step_), dst_data(dst_data_), dst_step(dst_step_), width(width_), cvt(_cvt), ok(_ok)
|
|
||||||
{
|
|
||||||
*ok = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void operator()(const Range& range) const CV_OVERRIDE
|
|
||||||
{
|
|
||||||
const void *yS = src_data + src_step * range.start;
|
|
||||||
void *yD = dst_data + dst_step * range.start;
|
|
||||||
if( !cvt(yS, static_cast<int>(src_step), yD, static_cast<int>(dst_step), width, range.end - range.start) )
|
|
||||||
*ok = false;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
const uchar * src_data;
|
|
||||||
const size_t src_step;
|
|
||||||
uchar * dst_data;
|
|
||||||
const size_t dst_step;
|
|
||||||
const int width;
|
|
||||||
const Cvt& cvt;
|
|
||||||
bool *ok;
|
|
||||||
|
|
||||||
const CvtColorIPPLoop_Invoker& operator= (const CvtColorIPPLoop_Invoker&);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template <typename Cvt>
|
|
||||||
bool CvtColorIPPLoop(const uchar * src_data, size_t src_step, uchar * dst_data, size_t dst_step, int width, int height, const Cvt& cvt)
|
|
||||||
{
|
|
||||||
bool ok;
|
|
||||||
parallel_for_(Range(0, height), CvtColorIPPLoop_Invoker<Cvt>(src_data, src_step, dst_data, dst_step, width, cvt, &ok), (width * height)/(double)(1<<16) );
|
|
||||||
return ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <typename Cvt>
|
|
||||||
bool CvtColorIPPLoopCopy(const uchar * src_data, size_t src_step, int src_type, uchar * dst_data, size_t dst_step, int width, int height, const Cvt& cvt)
|
|
||||||
{
|
|
||||||
Mat temp;
|
|
||||||
Mat src(Size(width, height), src_type, const_cast<uchar*>(src_data), src_step);
|
|
||||||
Mat source = src;
|
|
||||||
if( src_data == dst_data )
|
|
||||||
{
|
|
||||||
src.copyTo(temp);
|
|
||||||
source = temp;
|
|
||||||
}
|
|
||||||
bool ok;
|
|
||||||
parallel_for_(Range(0, source.rows),
|
|
||||||
CvtColorIPPLoop_Invoker<Cvt>(source.data, source.step, dst_data, dst_step,
|
|
||||||
source.cols, cvt, &ok),
|
|
||||||
source.total()/(double)(1<<16) );
|
|
||||||
return ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
struct IPPGeneralFunctor
|
|
||||||
{
|
|
||||||
IPPGeneralFunctor(ippiGeneralFunc _func) : ippiColorConvertGeneral(_func){}
|
|
||||||
bool operator()(const void *src, int srcStep, void *dst, int dstStep, int cols, int rows) const
|
|
||||||
{
|
|
||||||
return ippiColorConvertGeneral ? CV_INSTRUMENT_FUN_IPP(ippiColorConvertGeneral, src, srcStep, dst, dstStep, ippiSize(cols, rows)) >= 0 : false;
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
ippiGeneralFunc ippiColorConvertGeneral;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct IPPReorderFunctor
|
|
||||||
{
|
|
||||||
IPPReorderFunctor(ippiReorderFunc _func, int _order0, int _order1, int _order2) : ippiColorConvertReorder(_func)
|
|
||||||
{
|
|
||||||
order[0] = _order0;
|
|
||||||
order[1] = _order1;
|
|
||||||
order[2] = _order2;
|
|
||||||
order[3] = 3;
|
|
||||||
}
|
|
||||||
bool operator()(const void *src, int srcStep, void *dst, int dstStep, int cols, int rows) const
|
|
||||||
{
|
|
||||||
return ippiColorConvertReorder ? CV_INSTRUMENT_FUN_IPP(ippiColorConvertReorder, src, srcStep, dst, dstStep, ippiSize(cols, rows), order) >= 0 : false;
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
ippiReorderFunc ippiColorConvertReorder;
|
|
||||||
int order[4];
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct IPPReorderGeneralFunctor
|
|
||||||
{
|
|
||||||
IPPReorderGeneralFunctor(ippiReorderFunc _func1, ippiGeneralFunc _func2, int _order0, int _order1, int _order2, int _depth) :
|
|
||||||
ippiColorConvertReorder(_func1), ippiColorConvertGeneral(_func2), depth(_depth)
|
|
||||||
{
|
|
||||||
order[0] = _order0;
|
|
||||||
order[1] = _order1;
|
|
||||||
order[2] = _order2;
|
|
||||||
order[3] = 3;
|
|
||||||
}
|
|
||||||
bool operator()(const void *src, int srcStep, void *dst, int dstStep, int cols, int rows) const
|
|
||||||
{
|
|
||||||
if (ippiColorConvertReorder == 0 || ippiColorConvertGeneral == 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
Mat temp;
|
|
||||||
temp.create(rows, cols, CV_MAKETYPE(depth, 3));
|
|
||||||
if(CV_INSTRUMENT_FUN_IPP(ippiColorConvertReorder, src, srcStep, temp.ptr(), (int)temp.step[0], ippiSize(cols, rows), order) < 0)
|
|
||||||
return false;
|
|
||||||
return CV_INSTRUMENT_FUN_IPP(ippiColorConvertGeneral, temp.ptr(), (int)temp.step[0], dst, dstStep, ippiSize(cols, rows)) >= 0;
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
ippiReorderFunc ippiColorConvertReorder;
|
|
||||||
ippiGeneralFunc ippiColorConvertGeneral;
|
|
||||||
int order[4];
|
|
||||||
int depth;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct IPPGeneralReorderFunctor
|
|
||||||
{
|
|
||||||
IPPGeneralReorderFunctor(ippiGeneralFunc _func1, ippiReorderFunc _func2, int _order0, int _order1, int _order2, int _depth) :
|
|
||||||
ippiColorConvertGeneral(_func1), ippiColorConvertReorder(_func2), depth(_depth)
|
|
||||||
{
|
|
||||||
order[0] = _order0;
|
|
||||||
order[1] = _order1;
|
|
||||||
order[2] = _order2;
|
|
||||||
order[3] = 3;
|
|
||||||
}
|
|
||||||
bool operator()(const void *src, int srcStep, void *dst, int dstStep, int cols, int rows) const
|
|
||||||
{
|
|
||||||
if (ippiColorConvertGeneral == 0 || ippiColorConvertReorder == 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
Mat temp;
|
|
||||||
temp.create(rows, cols, CV_MAKETYPE(depth, 3));
|
|
||||||
if(CV_INSTRUMENT_FUN_IPP(ippiColorConvertGeneral, src, srcStep, temp.ptr(), (int)temp.step[0], ippiSize(cols, rows)) < 0)
|
|
||||||
return false;
|
|
||||||
return CV_INSTRUMENT_FUN_IPP(ippiColorConvertReorder, temp.ptr(), (int)temp.step[0], dst, dstStep, ippiSize(cols, rows), order) >= 0;
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
ippiGeneralFunc ippiColorConvertGeneral;
|
|
||||||
ippiReorderFunc ippiColorConvertReorder;
|
|
||||||
int order[4];
|
|
||||||
int depth;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern ippiReorderFunc ippiSwapChannelsC3C4RTab[8];
|
|
||||||
extern ippiReorderFunc ippiSwapChannelsC4C3RTab[8];
|
|
||||||
extern ippiReorderFunc ippiSwapChannelsC3RTab[8];
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_OPENCL
|
|
||||||
|
|
||||||
bool oclCvtColorBGR2Luv( InputArray _src, OutputArray _dst, int bidx, bool srgb );
|
|
||||||
bool oclCvtColorBGR2Lab( InputArray _src, OutputArray _dst, int bidx, bool srgb );
|
|
||||||
bool oclCvtColorLab2BGR( InputArray _src, OutputArray _dst, int dcn, int bidx, bool srgb);
|
|
||||||
bool oclCvtColorLuv2BGR( InputArray _src, OutputArray _dst, int dcn, int bidx, bool srgb);
|
|
||||||
bool oclCvtColorBGR2XYZ( InputArray _src, OutputArray _dst, int bidx );
|
|
||||||
bool oclCvtColorXYZ2BGR( InputArray _src, OutputArray _dst, int dcn, int bidx );
|
|
||||||
|
|
||||||
bool oclCvtColorHSV2BGR( InputArray _src, OutputArray _dst, int dcn, int bidx, bool full );
|
|
||||||
bool oclCvtColorHLS2BGR( InputArray _src, OutputArray _dst, int dcn, int bidx, bool full );
|
|
||||||
bool oclCvtColorBGR2HLS( InputArray _src, OutputArray _dst, int bidx, bool full );
|
|
||||||
bool oclCvtColorBGR2HSV( InputArray _src, OutputArray _dst, int bidx, bool full );
|
|
||||||
|
|
||||||
bool oclCvtColorBGR2BGR( InputArray _src, OutputArray _dst, int dcn, bool reverse );
|
|
||||||
bool oclCvtColorBGR25x5( InputArray _src, OutputArray _dst, int bidx, int gbits );
|
|
||||||
bool oclCvtColor5x52BGR( InputArray _src, OutputArray _dst, int dcn, int bidx, int gbits );
|
|
||||||
bool oclCvtColor5x52Gray( InputArray _src, OutputArray _dst, int gbits );
|
|
||||||
bool oclCvtColorGray25x5( InputArray _src, OutputArray _dst, int gbits );
|
|
||||||
bool oclCvtColorBGR2Gray( InputArray _src, OutputArray _dst, int bidx );
|
|
||||||
bool oclCvtColorGray2BGR( InputArray _src, OutputArray _dst, int dcn );
|
|
||||||
bool oclCvtColorRGBA2mRGBA( InputArray _src, OutputArray _dst );
|
|
||||||
bool oclCvtColormRGBA2RGBA( InputArray _src, OutputArray _dst );
|
|
||||||
|
|
||||||
bool oclCvtColorBGR2YCrCb( InputArray _src, OutputArray _dst, int bidx);
|
|
||||||
bool oclCvtcolorYCrCb2BGR( InputArray _src, OutputArray _dst, int dcn, int bidx);
|
|
||||||
bool oclCvtColorBGR2YUV( InputArray _src, OutputArray _dst, int bidx );
|
|
||||||
bool oclCvtColorYUV2BGR( InputArray _src, OutputArray _dst, int dcn, int bidx );
|
|
||||||
|
|
||||||
bool oclCvtColorOnePlaneYUV2BGR( InputArray _src, OutputArray _dst, int dcn, int bidx, int uidx, int yidx );
|
|
||||||
bool oclCvtColorTwoPlaneYUV2BGR( InputArray _src, OutputArray _dst, int dcn, int bidx, int uidx );
|
|
||||||
bool oclCvtColorThreePlaneYUV2BGR( InputArray _src, OutputArray _dst, int dcn, int bidx, int uidx );
|
|
||||||
bool oclCvtColorBGR2ThreePlaneYUV( InputArray _src, OutputArray _dst, int bidx, int uidx );
|
|
||||||
bool oclCvtColorYUV2Gray_420( InputArray _src, OutputArray _dst );
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void cvtColorBGR2Lab( InputArray _src, OutputArray _dst, bool swapb, bool srgb);
|
|
||||||
void cvtColorBGR2Luv( InputArray _src, OutputArray _dst, bool swapb, bool srgb);
|
|
||||||
void cvtColorLab2BGR( InputArray _src, OutputArray _dst, int dcn, bool swapb, bool srgb );
|
|
||||||
void cvtColorLuv2BGR( InputArray _src, OutputArray _dst, int dcn, bool swapb, bool srgb );
|
|
||||||
void cvtColorBGR2XYZ( InputArray _src, OutputArray _dst, bool swapb );
|
|
||||||
void cvtColorXYZ2BGR( InputArray _src, OutputArray _dst, int dcn, bool swapb );
|
|
||||||
|
|
||||||
void cvtColorBGR2YUV( InputArray _src, OutputArray _dst, bool swapb, bool crcb);
|
|
||||||
void cvtColorYUV2BGR( InputArray _src, OutputArray _dst, int dcn, bool swapb, bool crcb);
|
|
||||||
|
|
||||||
void cvtColorOnePlaneYUV2BGR( InputArray _src, OutputArray _dst, int dcn, bool swapb, int uidx, int ycn);
|
|
||||||
void cvtColorTwoPlaneYUV2BGR( InputArray _src, OutputArray _dst, int dcn, bool swapb, int uidx );
|
|
||||||
void cvtColorTwoPlaneYUV2BGRpair( InputArray _ysrc, InputArray _uvsrc, OutputArray _dst, int dcn, bool swapb, int uidx );
|
|
||||||
void cvtColorThreePlaneYUV2BGR( InputArray _src, OutputArray _dst, int dcn, bool swapb, int uidx );
|
|
||||||
void cvtColorBGR2ThreePlaneYUV( InputArray _src, OutputArray _dst, bool swapb, int uidx);
|
|
||||||
void cvtColorYUV2Gray_420( InputArray _src, OutputArray _dst );
|
|
||||||
void cvtColorYUV2Gray_ch( InputArray _src, OutputArray _dst, int coi );
|
|
||||||
|
|
||||||
void cvtColorBGR2HLS( InputArray _src, OutputArray _dst, bool swapb, bool fullRange );
|
|
||||||
void cvtColorBGR2HSV( InputArray _src, OutputArray _dst, bool swapb, bool fullRange );
|
|
||||||
void cvtColorHLS2BGR( InputArray _src, OutputArray _dst, int dcn, bool swapb, bool fullRange);
|
|
||||||
void cvtColorHSV2BGR( InputArray _src, OutputArray _dst, int dcn, bool swapb, bool fullRange);
|
|
||||||
|
|
||||||
void cvtColorBGR2BGR( InputArray _src, OutputArray _dst, int dcn, bool swapb);
|
|
||||||
void cvtColorBGR25x5( InputArray _src, OutputArray _dst, bool swapb, int gbits);
|
|
||||||
void cvtColor5x52BGR( InputArray _src, OutputArray _dst, int dcn, bool swapb, int gbits);
|
|
||||||
void cvtColorBGR2Gray( InputArray _src, OutputArray _dst, bool swapb);
|
|
||||||
void cvtColorGray2BGR( InputArray _src, OutputArray _dst, int dcn);
|
|
||||||
void cvtColor5x52Gray( InputArray _src, OutputArray _dst, int gbits);
|
|
||||||
void cvtColorGray25x5( InputArray _src, OutputArray _dst, int gbits);
|
|
||||||
void cvtColorRGBA2mRGBA(InputArray _src, OutputArray _dst);
|
|
||||||
void cvtColormRGBA2RGBA(InputArray _src, OutputArray _dst);
|
|
||||||
|
|
||||||
} //namespace cv
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -3,11 +3,31 @@
|
|||||||
// of this distribution and at http://opencv.org/license.html
|
// of this distribution and at http://opencv.org/license.html
|
||||||
|
|
||||||
#include "precomp.hpp"
|
#include "precomp.hpp"
|
||||||
#include "color.hpp"
|
#include "opencv2/core/hal/intrin.hpp"
|
||||||
|
|
||||||
namespace cv
|
namespace cv {
|
||||||
{
|
namespace hal {
|
||||||
|
CV_CPU_OPTIMIZATION_NAMESPACE_BEGIN
|
||||||
|
// forward declarations
|
||||||
|
|
||||||
|
void cvtBGRtoHSV(const uchar * src_data, size_t src_step,
|
||||||
|
uchar * dst_data, size_t dst_step,
|
||||||
|
int width, int height,
|
||||||
|
int depth, int scn, bool swapBlue, bool isFullRange, bool isHSV);
|
||||||
|
void cvtHSVtoBGR(const uchar * src_data, size_t src_step,
|
||||||
|
uchar * dst_data, size_t dst_step,
|
||||||
|
int width, int height,
|
||||||
|
int depth, int dcn, bool swapBlue, bool isFullRange, bool isHSV);
|
||||||
|
|
||||||
|
#ifndef CV_CPU_OPTIMIZATION_DECLARATIONS_ONLY
|
||||||
|
|
||||||
|
#if defined(CV_CPU_BASELINE_MODE)
|
||||||
|
// included in color.hpp
|
||||||
|
#else
|
||||||
|
#include "color.simd_helpers.hpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace {
|
||||||
////////////////////////////////////// RGB <-> HSV ///////////////////////////////////////
|
////////////////////////////////////// RGB <-> HSV ///////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
@ -1192,46 +1212,7 @@ struct HLS2RGB_b
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
} // namespace anon
|
||||||
// IPP functions
|
|
||||||
//
|
|
||||||
|
|
||||||
#if NEED_IPP
|
|
||||||
|
|
||||||
#if !IPP_DISABLE_RGB_HSV
|
|
||||||
static ippiGeneralFunc ippiRGB2HSVTab[] =
|
|
||||||
{
|
|
||||||
(ippiGeneralFunc)ippiRGBToHSV_8u_C3R, 0, (ippiGeneralFunc)ippiRGBToHSV_16u_C3R, 0,
|
|
||||||
0, 0, 0, 0
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static ippiGeneralFunc ippiHSV2RGBTab[] =
|
|
||||||
{
|
|
||||||
(ippiGeneralFunc)ippiHSVToRGB_8u_C3R, 0, (ippiGeneralFunc)ippiHSVToRGB_16u_C3R, 0,
|
|
||||||
0, 0, 0, 0
|
|
||||||
};
|
|
||||||
|
|
||||||
static ippiGeneralFunc ippiRGB2HLSTab[] =
|
|
||||||
{
|
|
||||||
(ippiGeneralFunc)ippiRGBToHLS_8u_C3R, 0, (ippiGeneralFunc)ippiRGBToHLS_16u_C3R, 0,
|
|
||||||
0, (ippiGeneralFunc)ippiRGBToHLS_32f_C3R, 0, 0
|
|
||||||
};
|
|
||||||
|
|
||||||
static ippiGeneralFunc ippiHLS2RGBTab[] =
|
|
||||||
{
|
|
||||||
(ippiGeneralFunc)ippiHLSToRGB_8u_C3R, 0, (ippiGeneralFunc)ippiHLSToRGB_16u_C3R, 0,
|
|
||||||
0, (ippiGeneralFunc)ippiHLSToRGB_32f_C3R, 0, 0
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//
|
|
||||||
// HAL functions
|
|
||||||
//
|
|
||||||
|
|
||||||
namespace hal
|
|
||||||
{
|
|
||||||
|
|
||||||
// 8u, 32f
|
// 8u, 32f
|
||||||
void cvtBGRtoHSV(const uchar * src_data, size_t src_step,
|
void cvtBGRtoHSV(const uchar * src_data, size_t src_step,
|
||||||
@ -1241,67 +1222,6 @@ void cvtBGRtoHSV(const uchar * src_data, size_t src_step,
|
|||||||
{
|
{
|
||||||
CV_INSTRUMENT_REGION();
|
CV_INSTRUMENT_REGION();
|
||||||
|
|
||||||
CALL_HAL(cvtBGRtoHSV, cv_hal_cvtBGRtoHSV, src_data, src_step, dst_data, dst_step, width, height, depth, scn, swapBlue, isFullRange, isHSV);
|
|
||||||
|
|
||||||
#if defined(HAVE_IPP) && IPP_VERSION_X100 >= 700
|
|
||||||
CV_IPP_CHECK()
|
|
||||||
{
|
|
||||||
if(depth == CV_8U && isFullRange)
|
|
||||||
{
|
|
||||||
if (isHSV)
|
|
||||||
{
|
|
||||||
#if !IPP_DISABLE_RGB_HSV // breaks OCL accuracy tests
|
|
||||||
if(scn == 3 && !swapBlue)
|
|
||||||
{
|
|
||||||
if( CvtColorIPPLoopCopy(src_data, src_step, CV_MAKE_TYPE(depth, scn), dst_data, dst_step, width, height,
|
|
||||||
IPPReorderGeneralFunctor(ippiSwapChannelsC3RTab[depth], ippiRGB2HSVTab[depth], 2, 1, 0, depth)) )
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if(scn == 4 && !swapBlue)
|
|
||||||
{
|
|
||||||
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
|
|
||||||
IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], ippiRGB2HSVTab[depth], 2, 1, 0, depth)) )
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if(scn == 4 && swapBlue)
|
|
||||||
{
|
|
||||||
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
|
|
||||||
IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], ippiRGB2HSVTab[depth], 0, 1, 2, depth)) )
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(scn == 3 && !swapBlue)
|
|
||||||
{
|
|
||||||
if( CvtColorIPPLoopCopy(src_data, src_step, CV_MAKE_TYPE(depth, scn), dst_data, dst_step, width, height,
|
|
||||||
IPPReorderGeneralFunctor(ippiSwapChannelsC3RTab[depth], ippiRGB2HLSTab[depth], 2, 1, 0, depth)) )
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if(scn == 4 && !swapBlue)
|
|
||||||
{
|
|
||||||
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
|
|
||||||
IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], ippiRGB2HLSTab[depth], 2, 1, 0, depth)) )
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if(scn == 3 && swapBlue)
|
|
||||||
{
|
|
||||||
if( CvtColorIPPLoopCopy(src_data, src_step, CV_MAKE_TYPE(depth, scn), dst_data, dst_step, width, height,
|
|
||||||
IPPGeneralFunctor(ippiRGB2HLSTab[depth])) )
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if(scn == 4 && swapBlue)
|
|
||||||
{
|
|
||||||
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
|
|
||||||
IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], ippiRGB2HLSTab[depth], 0, 1, 2, depth)) )
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int hrange = depth == CV_32F ? 360 : isFullRange ? 256 : 180;
|
int hrange = depth == CV_32F ? 360 : isFullRange ? 256 : 180;
|
||||||
int blueIdx = swapBlue ? 2 : 0;
|
int blueIdx = swapBlue ? 2 : 0;
|
||||||
if(isHSV)
|
if(isHSV)
|
||||||
@ -1322,77 +1242,12 @@ void cvtBGRtoHSV(const uchar * src_data, size_t src_step,
|
|||||||
|
|
||||||
// 8u, 32f
|
// 8u, 32f
|
||||||
void cvtHSVtoBGR(const uchar * src_data, size_t src_step,
|
void cvtHSVtoBGR(const uchar * src_data, size_t src_step,
|
||||||
uchar * dst_data, size_t dst_step,
|
uchar * dst_data, size_t dst_step,
|
||||||
int width, int height,
|
int width, int height,
|
||||||
int depth, int dcn, bool swapBlue, bool isFullRange, bool isHSV)
|
int depth, int dcn, bool swapBlue, bool isFullRange, bool isHSV)
|
||||||
{
|
{
|
||||||
CV_INSTRUMENT_REGION();
|
CV_INSTRUMENT_REGION();
|
||||||
|
|
||||||
CALL_HAL(cvtHSVtoBGR, cv_hal_cvtHSVtoBGR, src_data, src_step, dst_data, dst_step, width, height, depth, dcn, swapBlue, isFullRange, isHSV);
|
|
||||||
|
|
||||||
#if defined(HAVE_IPP) && IPP_VERSION_X100 >= 700
|
|
||||||
CV_IPP_CHECK()
|
|
||||||
{
|
|
||||||
if (depth == CV_8U && isFullRange)
|
|
||||||
{
|
|
||||||
if (isHSV)
|
|
||||||
{
|
|
||||||
if(dcn == 3 && !swapBlue)
|
|
||||||
{
|
|
||||||
if( CvtColorIPPLoopCopy(src_data, src_step, CV_MAKETYPE(depth, 3), dst_data, dst_step, width, height,
|
|
||||||
IPPGeneralReorderFunctor(ippiHSV2RGBTab[depth], ippiSwapChannelsC3RTab[depth], 2, 1, 0, depth)) )
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if(dcn == 4 && !swapBlue)
|
|
||||||
{
|
|
||||||
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
|
|
||||||
IPPGeneralReorderFunctor(ippiHSV2RGBTab[depth], ippiSwapChannelsC3C4RTab[depth], 2, 1, 0, depth)) )
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if(dcn == 3 && swapBlue)
|
|
||||||
{
|
|
||||||
if( CvtColorIPPLoopCopy(src_data, src_step, CV_MAKETYPE(depth, 3), dst_data, dst_step, width, height,
|
|
||||||
IPPGeneralFunctor(ippiHSV2RGBTab[depth])) )
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if(dcn == 4 && swapBlue)
|
|
||||||
{
|
|
||||||
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
|
|
||||||
IPPGeneralReorderFunctor(ippiHSV2RGBTab[depth], ippiSwapChannelsC3C4RTab[depth], 0, 1, 2, depth)) )
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(dcn == 3 && !swapBlue)
|
|
||||||
{
|
|
||||||
if( CvtColorIPPLoopCopy(src_data, src_step, CV_MAKETYPE(depth, 3), dst_data, dst_step, width, height,
|
|
||||||
IPPGeneralReorderFunctor(ippiHLS2RGBTab[depth], ippiSwapChannelsC3RTab[depth], 2, 1, 0, depth)) )
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if(dcn == 4 && !swapBlue)
|
|
||||||
{
|
|
||||||
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
|
|
||||||
IPPGeneralReorderFunctor(ippiHLS2RGBTab[depth], ippiSwapChannelsC3C4RTab[depth], 2, 1, 0, depth)) )
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if(dcn == 3 && swapBlue)
|
|
||||||
{
|
|
||||||
if( CvtColorIPPLoopCopy(src_data, src_step, CV_MAKETYPE(depth, 3), dst_data, dst_step, width, height,
|
|
||||||
IPPGeneralFunctor(ippiHLS2RGBTab[depth])) )
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if(dcn == 4 && swapBlue)
|
|
||||||
{
|
|
||||||
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
|
|
||||||
IPPGeneralReorderFunctor(ippiHLS2RGBTab[depth], ippiSwapChannelsC3C4RTab[depth], 0, 1, 2, depth)) )
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int hrange = depth == CV_32F ? 360 : isFullRange ? 255 : 180;
|
int hrange = depth == CV_32F ? 360 : isFullRange ? 255 : 180;
|
||||||
int blueIdx = swapBlue ? 2 : 0;
|
int blueIdx = swapBlue ? 2 : 0;
|
||||||
if(isHSV)
|
if(isHSV)
|
||||||
@ -1411,155 +1266,6 @@ void cvtHSVtoBGR(const uchar * src_data, size_t src_step,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace hal
|
|
||||||
|
|
||||||
//
|
|
||||||
// OCL calls
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifdef HAVE_OPENCL
|
|
||||||
|
|
||||||
bool oclCvtColorHSV2BGR( InputArray _src, OutputArray _dst, int dcn, int bidx, bool full )
|
|
||||||
{
|
|
||||||
OclHelper< Set<3>, Set<3, 4>, Set<CV_8U, CV_32F> > h(_src, _dst, dcn);
|
|
||||||
|
|
||||||
int hrange = _src.depth() == CV_32F ? 360 : (!full ? 180 : 255);
|
|
||||||
|
|
||||||
if(!h.createKernel("HSV2RGB", ocl::imgproc::color_hsv_oclsrc,
|
|
||||||
format("-D dcn=%d -D bidx=%d -D hrange=%d -D hscale=%ff", dcn, bidx, hrange, 6.f/hrange)))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return h.run();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool oclCvtColorHLS2BGR( InputArray _src, OutputArray _dst, int dcn, int bidx, bool full )
|
|
||||||
{
|
|
||||||
OclHelper< Set<3>, Set<3, 4>, Set<CV_8U, CV_32F> > h(_src, _dst, dcn);
|
|
||||||
|
|
||||||
int hrange = _src.depth() == CV_32F ? 360 : (!full ? 180 : 255);
|
|
||||||
|
|
||||||
if(!h.createKernel("HLS2RGB", ocl::imgproc::color_hsv_oclsrc,
|
|
||||||
format("-D dcn=%d -D bidx=%d -D hrange=%d -D hscale=%ff", dcn, bidx, hrange, 6.f/hrange)))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return h.run();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool oclCvtColorBGR2HLS( InputArray _src, OutputArray _dst, int bidx, bool full )
|
|
||||||
{
|
|
||||||
OclHelper< Set<3, 4>, Set<3>, Set<CV_8U, CV_32F> > h(_src, _dst, 3);
|
|
||||||
|
|
||||||
float hscale = (_src.depth() == CV_32F ? 360.f : (!full ? 180.f : 256.f))/360.f;
|
|
||||||
|
|
||||||
if(!h.createKernel("RGB2HLS", ocl::imgproc::color_hsv_oclsrc,
|
|
||||||
format("-D hscale=%ff -D bidx=%d -D dcn=3", hscale, bidx)))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return h.run();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool oclCvtColorBGR2HSV( InputArray _src, OutputArray _dst, int bidx, bool full )
|
|
||||||
{
|
|
||||||
OclHelper< Set<3, 4>, Set<3>, Set<CV_8U, CV_32F> > h(_src, _dst, 3);
|
|
||||||
|
|
||||||
int hrange = _src.depth() == CV_32F ? 360 : (!full ? 180 : 256);
|
|
||||||
|
|
||||||
cv::String options = (_src.depth() == CV_8U ?
|
|
||||||
format("-D hrange=%d -D bidx=%d -D dcn=3", hrange, bidx) :
|
|
||||||
format("-D hscale=%ff -D bidx=%d -D dcn=3", hrange*(1.f/360.f), bidx));
|
|
||||||
|
|
||||||
if(!h.createKernel("RGB2HSV", ocl::imgproc::color_hsv_oclsrc, options))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(_src.depth() == CV_8U)
|
|
||||||
{
|
|
||||||
static UMat sdiv_data;
|
|
||||||
static UMat hdiv_data180;
|
|
||||||
static UMat hdiv_data256;
|
|
||||||
static int sdiv_table[256];
|
|
||||||
static int hdiv_table180[256];
|
|
||||||
static int hdiv_table256[256];
|
|
||||||
static volatile bool initialized180 = false, initialized256 = false;
|
|
||||||
volatile bool & initialized = hrange == 180 ? initialized180 : initialized256;
|
|
||||||
|
|
||||||
if (!initialized)
|
|
||||||
{
|
|
||||||
int * const hdiv_table = hrange == 180 ? hdiv_table180 : hdiv_table256, hsv_shift = 12;
|
|
||||||
UMat & hdiv_data = hrange == 180 ? hdiv_data180 : hdiv_data256;
|
|
||||||
|
|
||||||
sdiv_table[0] = hdiv_table180[0] = hdiv_table256[0] = 0;
|
|
||||||
|
|
||||||
int v = 255 << hsv_shift;
|
|
||||||
if (!initialized180 && !initialized256)
|
|
||||||
{
|
|
||||||
for(int i = 1; i < 256; i++ )
|
|
||||||
sdiv_table[i] = saturate_cast<int>(v/(1.*i));
|
|
||||||
Mat(1, 256, CV_32SC1, sdiv_table).copyTo(sdiv_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
v = hrange << hsv_shift;
|
|
||||||
for (int i = 1; i < 256; i++ )
|
|
||||||
hdiv_table[i] = saturate_cast<int>(v/(6.*i));
|
|
||||||
|
|
||||||
Mat(1, 256, CV_32SC1, hdiv_table).copyTo(hdiv_data);
|
|
||||||
initialized = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
h.setArg(ocl::KernelArg::PtrReadOnly(sdiv_data));
|
|
||||||
h.setArg(hrange == 256 ? ocl::KernelArg::PtrReadOnly(hdiv_data256) :
|
|
||||||
ocl::KernelArg::PtrReadOnly(hdiv_data180));
|
|
||||||
}
|
|
||||||
|
|
||||||
return h.run();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
CV_CPU_OPTIMIZATION_NAMESPACE_END
|
||||||
//
|
}} // namespace
|
||||||
// HAL calls
|
|
||||||
//
|
|
||||||
|
|
||||||
void cvtColorBGR2HLS( InputArray _src, OutputArray _dst, bool swapb, bool fullRange )
|
|
||||||
{
|
|
||||||
CvtHelper< Set<3, 4>, Set<3>, Set<CV_8U, CV_32F> > h(_src, _dst, 3);
|
|
||||||
|
|
||||||
hal::cvtBGRtoHSV(h.src.data, h.src.step, h.dst.data, h.dst.step, h.src.cols, h.src.rows,
|
|
||||||
h.depth, h.scn, swapb, fullRange, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void cvtColorBGR2HSV( InputArray _src, OutputArray _dst, bool swapb, bool fullRange )
|
|
||||||
{
|
|
||||||
CvtHelper< Set<3, 4>, Set<3>, Set<CV_8U, CV_32F> > h(_src, _dst, 3);
|
|
||||||
|
|
||||||
hal::cvtBGRtoHSV(h.src.data, h.src.step, h.dst.data, h.dst.step, h.src.cols, h.src.rows,
|
|
||||||
h.depth, h.scn, swapb, fullRange, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void cvtColorHLS2BGR( InputArray _src, OutputArray _dst, int dcn, bool swapb, bool fullRange)
|
|
||||||
{
|
|
||||||
if(dcn <= 0) dcn = 3;
|
|
||||||
CvtHelper< Set<3>, Set<3, 4>, Set<CV_8U, CV_32F> > h(_src, _dst, dcn);
|
|
||||||
|
|
||||||
hal::cvtHSVtoBGR(h.src.data, h.src.step, h.dst.data, h.dst.step, h.src.cols, h.src.rows,
|
|
||||||
h.depth, dcn, swapb, fullRange, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void cvtColorHSV2BGR( InputArray _src, OutputArray _dst, int dcn, bool swapb, bool fullRange)
|
|
||||||
{
|
|
||||||
if(dcn <= 0) dcn = 3;
|
|
||||||
CvtHelper< Set<3>, Set<3, 4>, Set<CV_8U, CV_32F> > h(_src, _dst, dcn);
|
|
||||||
|
|
||||||
hal::cvtHSVtoBGR(h.src.data, h.src.step, h.dst.data, h.dst.step, h.src.cols, h.src.rows,
|
|
||||||
h.depth, dcn, swapb, fullRange, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace cv
|
|
||||||
|
@ -9,6 +9,10 @@
|
|||||||
\**********************************************************************************/
|
\**********************************************************************************/
|
||||||
|
|
||||||
#include "precomp.hpp"
|
#include "precomp.hpp"
|
||||||
|
#include "opencl_kernels_imgproc.hpp"
|
||||||
|
#include "opencv2/core/hal/intrin.hpp"
|
||||||
|
#include "opencv2/core/softfloat.hpp"
|
||||||
|
|
||||||
#include "color.hpp"
|
#include "color.hpp"
|
||||||
|
|
||||||
using cv::softfloat;
|
using cv::softfloat;
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -3,13 +3,58 @@
|
|||||||
// of this distribution and at http://opencv.org/license.html
|
// of this distribution and at http://opencv.org/license.html
|
||||||
|
|
||||||
#include "precomp.hpp"
|
#include "precomp.hpp"
|
||||||
#include "color.hpp"
|
#include "opencv2/core/hal/intrin.hpp"
|
||||||
|
|
||||||
#define IPP_DISABLE_CVTCOLOR_GRAY2BGR_8UC3 1
|
namespace cv {
|
||||||
|
namespace hal {
|
||||||
|
CV_CPU_OPTIMIZATION_NAMESPACE_BEGIN
|
||||||
|
// forward declarations
|
||||||
|
|
||||||
namespace cv
|
void cvtBGRtoBGR(const uchar * src_data, size_t src_step,
|
||||||
{
|
uchar * dst_data, size_t dst_step,
|
||||||
|
int width, int height,
|
||||||
|
int depth, int scn, int dcn, bool swapBlue);
|
||||||
|
void cvtBGRtoBGR5x5(const uchar * src_data, size_t src_step,
|
||||||
|
uchar * dst_data, size_t dst_step,
|
||||||
|
int width, int height,
|
||||||
|
int scn, bool swapBlue, int greenBits);
|
||||||
|
void cvtBGR5x5toBGR(const uchar * src_data, size_t src_step,
|
||||||
|
uchar * dst_data, size_t dst_step,
|
||||||
|
int width, int height,
|
||||||
|
int dcn, bool swapBlue, int greenBits);
|
||||||
|
void cvtBGRtoGray(const uchar * src_data, size_t src_step,
|
||||||
|
uchar * dst_data, size_t dst_step,
|
||||||
|
int width, int height,
|
||||||
|
int depth, int scn, bool swapBlue);
|
||||||
|
void cvtGraytoBGR(const uchar * src_data, size_t src_step,
|
||||||
|
uchar * dst_data, size_t dst_step,
|
||||||
|
int width, int height,
|
||||||
|
int depth, int dcn);
|
||||||
|
void cvtBGR5x5toGray(const uchar * src_data, size_t src_step,
|
||||||
|
uchar * dst_data, size_t dst_step,
|
||||||
|
int width, int height,
|
||||||
|
int greenBits);
|
||||||
|
void cvtGraytoBGR5x5(const uchar * src_data, size_t src_step,
|
||||||
|
uchar * dst_data, size_t dst_step,
|
||||||
|
int width, int height,
|
||||||
|
int greenBits);
|
||||||
|
void cvtRGBAtoMultipliedRGBA(const uchar * src_data, size_t src_step,
|
||||||
|
uchar * dst_data, size_t dst_step,
|
||||||
|
int width, int height);
|
||||||
|
void cvtMultipliedRGBAtoRGBA(const uchar * src_data, size_t src_step,
|
||||||
|
uchar * dst_data, size_t dst_step,
|
||||||
|
int width, int height);
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef CV_CPU_OPTIMIZATION_DECLARATIONS_ONLY
|
||||||
|
|
||||||
|
#if defined(CV_CPU_BASELINE_MODE)
|
||||||
|
// included in color.hpp
|
||||||
|
#else
|
||||||
|
#include "color.simd_helpers.hpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace {
|
||||||
////////////////// Various 3/4-channel to 3/4-channel RGB transformations /////////////////
|
////////////////// Various 3/4-channel to 3/4-channel RGB transformations /////////////////
|
||||||
|
|
||||||
template<typename _Tp> struct v_type;
|
template<typename _Tp> struct v_type;
|
||||||
@ -1044,172 +1089,7 @@ struct mRGBA2RGBA<uchar>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
} // namespace anon
|
||||||
//
|
|
||||||
// IPP functions
|
|
||||||
//
|
|
||||||
|
|
||||||
#if NEED_IPP
|
|
||||||
|
|
||||||
static ippiColor2GrayFunc ippiColor2GrayC3Tab[] =
|
|
||||||
{
|
|
||||||
(ippiColor2GrayFunc)ippiColorToGray_8u_C3C1R, 0, (ippiColor2GrayFunc)ippiColorToGray_16u_C3C1R, 0,
|
|
||||||
0, (ippiColor2GrayFunc)ippiColorToGray_32f_C3C1R, 0, 0
|
|
||||||
};
|
|
||||||
|
|
||||||
static ippiColor2GrayFunc ippiColor2GrayC4Tab[] =
|
|
||||||
{
|
|
||||||
(ippiColor2GrayFunc)ippiColorToGray_8u_AC4C1R, 0, (ippiColor2GrayFunc)ippiColorToGray_16u_AC4C1R, 0,
|
|
||||||
0, (ippiColor2GrayFunc)ippiColorToGray_32f_AC4C1R, 0, 0
|
|
||||||
};
|
|
||||||
|
|
||||||
static ippiGeneralFunc ippiRGB2GrayC3Tab[] =
|
|
||||||
{
|
|
||||||
(ippiGeneralFunc)ippiRGBToGray_8u_C3C1R, 0, (ippiGeneralFunc)ippiRGBToGray_16u_C3C1R, 0,
|
|
||||||
0, (ippiGeneralFunc)ippiRGBToGray_32f_C3C1R, 0, 0
|
|
||||||
};
|
|
||||||
|
|
||||||
static ippiGeneralFunc ippiRGB2GrayC4Tab[] =
|
|
||||||
{
|
|
||||||
(ippiGeneralFunc)ippiRGBToGray_8u_AC4C1R, 0, (ippiGeneralFunc)ippiRGBToGray_16u_AC4C1R, 0,
|
|
||||||
0, (ippiGeneralFunc)ippiRGBToGray_32f_AC4C1R, 0, 0
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#if !IPP_DISABLE_CVTCOLOR_GRAY2BGR_8UC3
|
|
||||||
static IppStatus ippiGrayToRGB_C1C3R(const Ipp8u* pSrc, int srcStep, Ipp8u* pDst, int dstStep, IppiSize roiSize)
|
|
||||||
{
|
|
||||||
return CV_INSTRUMENT_FUN_IPP(ippiGrayToRGB_8u_C1C3R, pSrc, srcStep, pDst, dstStep, roiSize);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
static IppStatus ippiGrayToRGB_C1C3R(const Ipp16u* pSrc, int srcStep, Ipp16u* pDst, int dstStep, IppiSize roiSize)
|
|
||||||
{
|
|
||||||
return CV_INSTRUMENT_FUN_IPP(ippiGrayToRGB_16u_C1C3R, pSrc, srcStep, pDst, dstStep, roiSize);
|
|
||||||
}
|
|
||||||
static IppStatus ippiGrayToRGB_C1C3R(const Ipp32f* pSrc, int srcStep, Ipp32f* pDst, int dstStep, IppiSize roiSize)
|
|
||||||
{
|
|
||||||
return CV_INSTRUMENT_FUN_IPP(ippiGrayToRGB_32f_C1C3R, pSrc, srcStep, pDst, dstStep, roiSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
static IppStatus ippiGrayToRGB_C1C4R(const Ipp8u* pSrc, int srcStep, Ipp8u* pDst, int dstStep, IppiSize roiSize, Ipp8u aval)
|
|
||||||
{
|
|
||||||
return CV_INSTRUMENT_FUN_IPP(ippiGrayToRGB_8u_C1C4R, pSrc, srcStep, pDst, dstStep, roiSize, aval);
|
|
||||||
}
|
|
||||||
static IppStatus ippiGrayToRGB_C1C4R(const Ipp16u* pSrc, int srcStep, Ipp16u* pDst, int dstStep, IppiSize roiSize, Ipp16u aval)
|
|
||||||
{
|
|
||||||
return CV_INSTRUMENT_FUN_IPP(ippiGrayToRGB_16u_C1C4R, pSrc, srcStep, pDst, dstStep, roiSize, aval);
|
|
||||||
}
|
|
||||||
static IppStatus ippiGrayToRGB_C1C4R(const Ipp32f* pSrc, int srcStep, Ipp32f* pDst, int dstStep, IppiSize roiSize, Ipp32f aval)
|
|
||||||
{
|
|
||||||
return CV_INSTRUMENT_FUN_IPP(ippiGrayToRGB_32f_C1C4R, pSrc, srcStep, pDst, dstStep, roiSize, aval);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct IPPColor2GrayFunctor
|
|
||||||
{
|
|
||||||
IPPColor2GrayFunctor(ippiColor2GrayFunc _func) :
|
|
||||||
ippiColorToGray(_func)
|
|
||||||
{
|
|
||||||
coeffs[0] = B2YF;
|
|
||||||
coeffs[1] = G2YF;
|
|
||||||
coeffs[2] = R2YF;
|
|
||||||
}
|
|
||||||
bool operator()(const void *src, int srcStep, void *dst, int dstStep, int cols, int rows) const
|
|
||||||
{
|
|
||||||
return ippiColorToGray ? CV_INSTRUMENT_FUN_IPP(ippiColorToGray, src, srcStep, dst, dstStep, ippiSize(cols, rows), coeffs) >= 0 : false;
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
ippiColor2GrayFunc ippiColorToGray;
|
|
||||||
Ipp32f coeffs[3];
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct IPPGray2BGRFunctor
|
|
||||||
{
|
|
||||||
IPPGray2BGRFunctor(){}
|
|
||||||
|
|
||||||
bool operator()(const void *src, int srcStep, void *dst, int dstStep, int cols, int rows) const
|
|
||||||
{
|
|
||||||
return ippiGrayToRGB_C1C3R((T*)src, srcStep, (T*)dst, dstStep, ippiSize(cols, rows)) >= 0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct IPPGray2BGRAFunctor
|
|
||||||
{
|
|
||||||
IPPGray2BGRAFunctor()
|
|
||||||
{
|
|
||||||
alpha = ColorChannel<T>::max();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator()(const void *src, int srcStep, void *dst, int dstStep, int cols, int rows) const
|
|
||||||
{
|
|
||||||
return ippiGrayToRGB_C1C4R((T*)src, srcStep, (T*)dst, dstStep, ippiSize(cols, rows), alpha) >= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
T alpha;
|
|
||||||
};
|
|
||||||
|
|
||||||
static IppStatus CV_STDCALL ippiSwapChannels_8u_C3C4Rf(const Ipp8u* pSrc, int srcStep, Ipp8u* pDst, int dstStep,
|
|
||||||
IppiSize roiSize, const int *dstOrder)
|
|
||||||
{
|
|
||||||
return CV_INSTRUMENT_FUN_IPP(ippiSwapChannels_8u_C3C4R, pSrc, srcStep, pDst, dstStep, roiSize, dstOrder, MAX_IPP8u);
|
|
||||||
}
|
|
||||||
|
|
||||||
static IppStatus CV_STDCALL ippiSwapChannels_16u_C3C4Rf(const Ipp16u* pSrc, int srcStep, Ipp16u* pDst, int dstStep,
|
|
||||||
IppiSize roiSize, const int *dstOrder)
|
|
||||||
{
|
|
||||||
return CV_INSTRUMENT_FUN_IPP(ippiSwapChannels_16u_C3C4R, pSrc, srcStep, pDst, dstStep, roiSize, dstOrder, MAX_IPP16u);
|
|
||||||
}
|
|
||||||
|
|
||||||
static IppStatus CV_STDCALL ippiSwapChannels_32f_C3C4Rf(const Ipp32f* pSrc, int srcStep, Ipp32f* pDst, int dstStep,
|
|
||||||
IppiSize roiSize, const int *dstOrder)
|
|
||||||
{
|
|
||||||
return CV_INSTRUMENT_FUN_IPP(ippiSwapChannels_32f_C3C4R, pSrc, srcStep, pDst, dstStep, roiSize, dstOrder, MAX_IPP32f);
|
|
||||||
}
|
|
||||||
|
|
||||||
// shared
|
|
||||||
ippiReorderFunc ippiSwapChannelsC3C4RTab[] =
|
|
||||||
{
|
|
||||||
(ippiReorderFunc)ippiSwapChannels_8u_C3C4Rf, 0, (ippiReorderFunc)ippiSwapChannels_16u_C3C4Rf, 0,
|
|
||||||
0, (ippiReorderFunc)ippiSwapChannels_32f_C3C4Rf, 0, 0
|
|
||||||
};
|
|
||||||
|
|
||||||
static ippiGeneralFunc ippiCopyAC4C3RTab[] =
|
|
||||||
{
|
|
||||||
(ippiGeneralFunc)ippiCopy_8u_AC4C3R, 0, (ippiGeneralFunc)ippiCopy_16u_AC4C3R, 0,
|
|
||||||
0, (ippiGeneralFunc)ippiCopy_32f_AC4C3R, 0, 0
|
|
||||||
};
|
|
||||||
|
|
||||||
// shared
|
|
||||||
ippiReorderFunc ippiSwapChannelsC4C3RTab[] =
|
|
||||||
{
|
|
||||||
(ippiReorderFunc)ippiSwapChannels_8u_C4C3R, 0, (ippiReorderFunc)ippiSwapChannels_16u_C4C3R, 0,
|
|
||||||
0, (ippiReorderFunc)ippiSwapChannels_32f_C4C3R, 0, 0
|
|
||||||
};
|
|
||||||
|
|
||||||
// shared
|
|
||||||
ippiReorderFunc ippiSwapChannelsC3RTab[] =
|
|
||||||
{
|
|
||||||
(ippiReorderFunc)ippiSwapChannels_8u_C3R, 0, (ippiReorderFunc)ippiSwapChannels_16u_C3R, 0,
|
|
||||||
0, (ippiReorderFunc)ippiSwapChannels_32f_C3R, 0, 0
|
|
||||||
};
|
|
||||||
|
|
||||||
#if IPP_VERSION_X100 >= 810
|
|
||||||
static ippiReorderFunc ippiSwapChannelsC4RTab[] =
|
|
||||||
{
|
|
||||||
(ippiReorderFunc)ippiSwapChannels_8u_C4R, 0, (ippiReorderFunc)ippiSwapChannels_16u_C4R, 0,
|
|
||||||
0, (ippiReorderFunc)ippiSwapChannels_32f_C4R, 0, 0
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//
|
|
||||||
// HAL functions
|
|
||||||
//
|
|
||||||
|
|
||||||
namespace hal
|
|
||||||
{
|
|
||||||
|
|
||||||
// 8u, 16u, 32f
|
// 8u, 16u, 32f
|
||||||
void cvtBGRtoBGR(const uchar * src_data, size_t src_step,
|
void cvtBGRtoBGR(const uchar * src_data, size_t src_step,
|
||||||
@ -1219,52 +1099,6 @@ void cvtBGRtoBGR(const uchar * src_data, size_t src_step,
|
|||||||
{
|
{
|
||||||
CV_INSTRUMENT_REGION();
|
CV_INSTRUMENT_REGION();
|
||||||
|
|
||||||
CALL_HAL(cvtBGRtoBGR, cv_hal_cvtBGRtoBGR, src_data, src_step, dst_data, dst_step, width, height, depth, scn, dcn, swapBlue);
|
|
||||||
|
|
||||||
#if defined(HAVE_IPP) && IPP_VERSION_X100 >= 700
|
|
||||||
CV_IPP_CHECK()
|
|
||||||
{
|
|
||||||
if(scn == 3 && dcn == 4 && !swapBlue)
|
|
||||||
{
|
|
||||||
if ( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
|
|
||||||
IPPReorderFunctor(ippiSwapChannelsC3C4RTab[depth], 0, 1, 2)) )
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if(scn == 4 && dcn == 3 && !swapBlue)
|
|
||||||
{
|
|
||||||
if ( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
|
|
||||||
IPPGeneralFunctor(ippiCopyAC4C3RTab[depth])) )
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if(scn == 3 && dcn == 4 && swapBlue)
|
|
||||||
{
|
|
||||||
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
|
|
||||||
IPPReorderFunctor(ippiSwapChannelsC3C4RTab[depth], 2, 1, 0)) )
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if(scn == 4 && dcn == 3 && swapBlue)
|
|
||||||
{
|
|
||||||
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
|
|
||||||
IPPReorderFunctor(ippiSwapChannelsC4C3RTab[depth], 2, 1, 0)) )
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if(scn == 3 && dcn == 3 && swapBlue)
|
|
||||||
{
|
|
||||||
if( CvtColorIPPLoopCopy(src_data, src_step, CV_MAKETYPE(depth, scn), dst_data, dst_step, width, height,
|
|
||||||
IPPReorderFunctor(ippiSwapChannelsC3RTab[depth], 2, 1, 0)) )
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#if IPP_VERSION_X100 >= 810
|
|
||||||
else if(scn == 4 && dcn == 4 && swapBlue)
|
|
||||||
{
|
|
||||||
if( CvtColorIPPLoopCopy(src_data, src_step, CV_MAKETYPE(depth, scn), dst_data, dst_step, width, height,
|
|
||||||
IPPReorderFunctor(ippiSwapChannelsC4RTab[depth], 2, 1, 0)) )
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int blueIdx = swapBlue ? 2 : 0;
|
int blueIdx = swapBlue ? 2 : 0;
|
||||||
if( depth == CV_8U )
|
if( depth == CV_8U )
|
||||||
CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, RGB2RGB<uchar>(scn, dcn, blueIdx));
|
CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, RGB2RGB<uchar>(scn, dcn, blueIdx));
|
||||||
@ -1282,8 +1116,6 @@ void cvtBGRtoBGR5x5(const uchar * src_data, size_t src_step,
|
|||||||
{
|
{
|
||||||
CV_INSTRUMENT_REGION();
|
CV_INSTRUMENT_REGION();
|
||||||
|
|
||||||
CALL_HAL(cvtBGRtoBGR5x5, cv_hal_cvtBGRtoBGR5x5, src_data, src_step, dst_data, dst_step, width, height, scn, swapBlue, greenBits);
|
|
||||||
|
|
||||||
CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, RGB2RGB5x5(scn, swapBlue ? 2 : 0, greenBits));
|
CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, RGB2RGB5x5(scn, swapBlue ? 2 : 0, greenBits));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1295,8 +1127,6 @@ void cvtBGR5x5toBGR(const uchar * src_data, size_t src_step,
|
|||||||
{
|
{
|
||||||
CV_INSTRUMENT_REGION();
|
CV_INSTRUMENT_REGION();
|
||||||
|
|
||||||
CALL_HAL(cvtBGR5x5toBGR, cv_hal_cvtBGR5x5toBGR, src_data, src_step, dst_data, dst_step, width, height, dcn, swapBlue, greenBits);
|
|
||||||
|
|
||||||
CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, RGB5x52RGB(dcn, swapBlue ? 2 : 0, greenBits));
|
CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, RGB5x52RGB(dcn, swapBlue ? 2 : 0, greenBits));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1308,38 +1138,6 @@ void cvtBGRtoGray(const uchar * src_data, size_t src_step,
|
|||||||
{
|
{
|
||||||
CV_INSTRUMENT_REGION();
|
CV_INSTRUMENT_REGION();
|
||||||
|
|
||||||
CALL_HAL(cvtBGRtoGray, cv_hal_cvtBGRtoGray, src_data, src_step, dst_data, dst_step, width, height, depth, scn, swapBlue);
|
|
||||||
|
|
||||||
#if defined(HAVE_IPP) && IPP_VERSION_X100 >= 700
|
|
||||||
CV_IPP_CHECK()
|
|
||||||
{
|
|
||||||
if(depth == CV_32F && scn == 3 && !swapBlue)
|
|
||||||
{
|
|
||||||
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
|
|
||||||
IPPColor2GrayFunctor(ippiColor2GrayC3Tab[depth])) )
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if(depth == CV_32F && scn == 3 && swapBlue)
|
|
||||||
{
|
|
||||||
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
|
|
||||||
IPPGeneralFunctor(ippiRGB2GrayC3Tab[depth])) )
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if(depth == CV_32F && scn == 4 && !swapBlue)
|
|
||||||
{
|
|
||||||
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
|
|
||||||
IPPColor2GrayFunctor(ippiColor2GrayC4Tab[depth])) )
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if(depth == CV_32F && scn == 4 && swapBlue)
|
|
||||||
{
|
|
||||||
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
|
|
||||||
IPPGeneralFunctor(ippiRGB2GrayC4Tab[depth])) )
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int blueIdx = swapBlue ? 2 : 0;
|
int blueIdx = swapBlue ? 2 : 0;
|
||||||
if( depth == CV_8U )
|
if( depth == CV_8U )
|
||||||
CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, RGB2Gray<uchar>(scn, blueIdx, 0));
|
CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, RGB2Gray<uchar>(scn, blueIdx, 0));
|
||||||
@ -1357,39 +1155,6 @@ void cvtGraytoBGR(const uchar * src_data, size_t src_step,
|
|||||||
{
|
{
|
||||||
CV_INSTRUMENT_REGION();
|
CV_INSTRUMENT_REGION();
|
||||||
|
|
||||||
CALL_HAL(cvtGraytoBGR, cv_hal_cvtGraytoBGR, src_data, src_step, dst_data, dst_step, width, height, depth, dcn);
|
|
||||||
|
|
||||||
#if defined(HAVE_IPP) && IPP_VERSION_X100 >= 700
|
|
||||||
CV_IPP_CHECK()
|
|
||||||
{
|
|
||||||
bool ippres = false;
|
|
||||||
if(dcn == 3)
|
|
||||||
{
|
|
||||||
if( depth == CV_8U )
|
|
||||||
{
|
|
||||||
#if !IPP_DISABLE_CVTCOLOR_GRAY2BGR_8UC3
|
|
||||||
ippres = CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height, IPPGray2BGRFunctor<Ipp8u>());
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else if( depth == CV_16U )
|
|
||||||
ippres = CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height, IPPGray2BGRFunctor<Ipp16u>());
|
|
||||||
else
|
|
||||||
ippres = CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height, IPPGray2BGRFunctor<Ipp32f>());
|
|
||||||
}
|
|
||||||
else if(dcn == 4)
|
|
||||||
{
|
|
||||||
if( depth == CV_8U )
|
|
||||||
ippres = CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height, IPPGray2BGRAFunctor<Ipp8u>());
|
|
||||||
else if( depth == CV_16U )
|
|
||||||
ippres = CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height, IPPGray2BGRAFunctor<Ipp16u>());
|
|
||||||
else
|
|
||||||
ippres = CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height, IPPGray2BGRAFunctor<Ipp32f>());
|
|
||||||
}
|
|
||||||
if(ippres)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if( depth == CV_8U )
|
if( depth == CV_8U )
|
||||||
CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, Gray2RGB<uchar>(dcn));
|
CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, Gray2RGB<uchar>(dcn));
|
||||||
else if( depth == CV_16U )
|
else if( depth == CV_16U )
|
||||||
@ -1406,7 +1171,6 @@ void cvtBGR5x5toGray(const uchar * src_data, size_t src_step,
|
|||||||
{
|
{
|
||||||
CV_INSTRUMENT_REGION();
|
CV_INSTRUMENT_REGION();
|
||||||
|
|
||||||
CALL_HAL(cvtBGR5x5toGray, cv_hal_cvtBGR5x5toGray, src_data, src_step, dst_data, dst_step, width, height, greenBits);
|
|
||||||
CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, RGB5x52Gray(greenBits));
|
CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, RGB5x52Gray(greenBits));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1418,7 +1182,6 @@ void cvtGraytoBGR5x5(const uchar * src_data, size_t src_step,
|
|||||||
{
|
{
|
||||||
CV_INSTRUMENT_REGION();
|
CV_INSTRUMENT_REGION();
|
||||||
|
|
||||||
CALL_HAL(cvtGraytoBGR5x5, cv_hal_cvtGraytoBGR5x5, src_data, src_step, dst_data, dst_step, width, height, greenBits);
|
|
||||||
CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, Gray2RGB5x5(greenBits));
|
CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, Gray2RGB5x5(greenBits));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1428,17 +1191,6 @@ void cvtRGBAtoMultipliedRGBA(const uchar * src_data, size_t src_step,
|
|||||||
{
|
{
|
||||||
CV_INSTRUMENT_REGION();
|
CV_INSTRUMENT_REGION();
|
||||||
|
|
||||||
CALL_HAL(cvtRGBAtoMultipliedRGBA, cv_hal_cvtRGBAtoMultipliedRGBA, src_data, src_step, dst_data, dst_step, width, height);
|
|
||||||
|
|
||||||
#ifdef HAVE_IPP
|
|
||||||
CV_IPP_CHECK()
|
|
||||||
{
|
|
||||||
if (CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
|
|
||||||
IPPGeneralFunctor((ippiGeneralFunc)ippiAlphaPremul_8u_AC4R)))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, RGBA2mRGBA<uchar>());
|
CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, RGBA2mRGBA<uchar>());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1448,209 +1200,9 @@ void cvtMultipliedRGBAtoRGBA(const uchar * src_data, size_t src_step,
|
|||||||
{
|
{
|
||||||
CV_INSTRUMENT_REGION();
|
CV_INSTRUMENT_REGION();
|
||||||
|
|
||||||
CALL_HAL(cvtMultipliedRGBAtoRGBA, cv_hal_cvtMultipliedRGBAtoRGBA, src_data, src_step, dst_data, dst_step, width, height);
|
|
||||||
CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, mRGBA2RGBA<uchar>());
|
CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, mRGBA2RGBA<uchar>());
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace hal
|
|
||||||
|
|
||||||
//
|
|
||||||
// OCL calls
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifdef HAVE_OPENCL
|
|
||||||
|
|
||||||
bool oclCvtColorBGR2BGR( InputArray _src, OutputArray _dst, int dcn, bool reverse )
|
|
||||||
{
|
|
||||||
OclHelper< Set<3, 4>, Set<3, 4>, Set<CV_8U, CV_16U, CV_32F> > h(_src, _dst, dcn);
|
|
||||||
|
|
||||||
if(!h.createKernel("RGB", ocl::imgproc::color_rgb_oclsrc,
|
|
||||||
format("-D dcn=%d -D bidx=0 -D %s", dcn, reverse ? "REVERSE" : "ORDER")))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return h.run();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool oclCvtColorBGR25x5( InputArray _src, OutputArray _dst, int bidx, int gbits )
|
|
||||||
{
|
|
||||||
OclHelper< Set<3, 4>, Set<2>, Set<CV_8U> > h(_src, _dst, 2);
|
|
||||||
|
|
||||||
if(!h.createKernel("RGB2RGB5x5", ocl::imgproc::color_rgb_oclsrc,
|
|
||||||
format("-D dcn=2 -D bidx=%d -D greenbits=%d", bidx, gbits)))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return h.run();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool oclCvtColor5x52BGR( InputArray _src, OutputArray _dst, int dcn, int bidx, int gbits)
|
|
||||||
{
|
|
||||||
OclHelper< Set<2>, Set<3, 4>, Set<CV_8U> > h(_src, _dst, dcn);
|
|
||||||
|
|
||||||
if(!h.createKernel("RGB5x52RGB", ocl::imgproc::color_rgb_oclsrc,
|
|
||||||
format("-D dcn=%d -D bidx=%d -D greenbits=%d", dcn, bidx, gbits)))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return h.run();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool oclCvtColor5x52Gray( InputArray _src, OutputArray _dst, int gbits)
|
|
||||||
{
|
|
||||||
OclHelper< Set<2>, Set<1>, Set<CV_8U> > h(_src, _dst, 1);
|
|
||||||
|
|
||||||
if(!h.createKernel("BGR5x52Gray", ocl::imgproc::color_rgb_oclsrc,
|
|
||||||
format("-D dcn=1 -D bidx=0 -D greenbits=%d", gbits)))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return h.run();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool oclCvtColorGray25x5( InputArray _src, OutputArray _dst, int gbits)
|
|
||||||
{
|
|
||||||
OclHelper< Set<1>, Set<2>, Set<CV_8U> > h(_src, _dst, 2);
|
|
||||||
|
|
||||||
if(!h.createKernel("Gray2BGR5x5", ocl::imgproc::color_rgb_oclsrc,
|
|
||||||
format("-D dcn=2 -D bidx=0 -D greenbits=%d", gbits)))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return h.run();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool oclCvtColorBGR2Gray( InputArray _src, OutputArray _dst, int bidx)
|
|
||||||
{
|
|
||||||
OclHelper< Set<3, 4>, Set<1>, Set<CV_8U, CV_16U, CV_32F> > h(_src, _dst, 1);
|
|
||||||
|
|
||||||
int stripeSize = 1;
|
|
||||||
if(!h.createKernel("RGB2Gray", ocl::imgproc::color_rgb_oclsrc,
|
|
||||||
format("-D dcn=1 -D bidx=%d -D STRIPE_SIZE=%d", bidx, stripeSize)))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
h.globalSize[0] = (h.src.cols + stripeSize - 1)/stripeSize;
|
|
||||||
return h.run();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool oclCvtColorGray2BGR( InputArray _src, OutputArray _dst, int dcn)
|
|
||||||
{
|
|
||||||
OclHelper< Set<1>, Set<3, 4>, Set<CV_8U, CV_16U, CV_32F> > h(_src, _dst, dcn);
|
|
||||||
if(!h.createKernel("Gray2RGB", ocl::imgproc::color_rgb_oclsrc,
|
|
||||||
format("-D bidx=0 -D dcn=%d", dcn)))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return h.run();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool oclCvtColorRGBA2mRGBA( InputArray _src, OutputArray _dst)
|
|
||||||
{
|
|
||||||
OclHelper< Set<4>, Set<4>, Set<CV_8U> > h(_src, _dst, 4);
|
|
||||||
|
|
||||||
if(!h.createKernel("RGBA2mRGBA", ocl::imgproc::color_rgb_oclsrc,
|
|
||||||
"-D dcn=4 -D bidx=3"))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return h.run();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool oclCvtColormRGBA2RGBA( InputArray _src, OutputArray _dst)
|
|
||||||
{
|
|
||||||
OclHelper< Set<4>, Set<4>, Set<CV_8U> > h(_src, _dst, 4);
|
|
||||||
|
|
||||||
if(!h.createKernel("mRGBA2RGBA", ocl::imgproc::color_rgb_oclsrc,
|
|
||||||
"-D dcn=4 -D bidx=3"))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return h.run();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
CV_CPU_OPTIMIZATION_NAMESPACE_END
|
||||||
//
|
}} // namespace
|
||||||
// HAL calls
|
|
||||||
//
|
|
||||||
|
|
||||||
void cvtColorBGR2BGR( InputArray _src, OutputArray _dst, int dcn, bool swapb)
|
|
||||||
{
|
|
||||||
CvtHelper< Set<3, 4>, Set<3, 4>, Set<CV_8U, CV_16U, CV_32F> > h(_src, _dst, dcn);
|
|
||||||
|
|
||||||
hal::cvtBGRtoBGR(h.src.data, h.src.step, h.dst.data, h.dst.step, h.src.cols, h.src.rows,
|
|
||||||
h.depth, h.scn, dcn, swapb);
|
|
||||||
}
|
|
||||||
|
|
||||||
void cvtColorBGR25x5( InputArray _src, OutputArray _dst, bool swapb, int gbits)
|
|
||||||
{
|
|
||||||
CvtHelper< Set<3, 4>, Set<2>, Set<CV_8U> > h(_src, _dst, 2);
|
|
||||||
|
|
||||||
hal::cvtBGRtoBGR5x5(h.src.data, h.src.step, h.dst.data, h.dst.step, h.src.cols, h.src.rows,
|
|
||||||
h.scn, swapb, gbits);
|
|
||||||
}
|
|
||||||
|
|
||||||
void cvtColor5x52BGR( InputArray _src, OutputArray _dst, int dcn, bool swapb, int gbits)
|
|
||||||
{
|
|
||||||
if(dcn <= 0) dcn = 3;
|
|
||||||
CvtHelper< Set<2>, Set<3, 4>, Set<CV_8U> > h(_src, _dst, dcn);
|
|
||||||
|
|
||||||
hal::cvtBGR5x5toBGR(h.src.data, h.src.step, h.dst.data, h.dst.step, h.src.cols, h.src.rows,
|
|
||||||
dcn, swapb, gbits);
|
|
||||||
}
|
|
||||||
|
|
||||||
void cvtColorBGR2Gray( InputArray _src, OutputArray _dst, bool swapb)
|
|
||||||
{
|
|
||||||
CvtHelper< Set<3, 4>, Set<1>, Set<CV_8U, CV_16U, CV_32F> > h(_src, _dst, 1);
|
|
||||||
|
|
||||||
hal::cvtBGRtoGray(h.src.data, h.src.step, h.dst.data, h.dst.step, h.src.cols, h.src.rows,
|
|
||||||
h.depth, h.scn, swapb);
|
|
||||||
}
|
|
||||||
|
|
||||||
void cvtColorGray2BGR( InputArray _src, OutputArray _dst, int dcn)
|
|
||||||
{
|
|
||||||
if(dcn <= 0) dcn = 3;
|
|
||||||
CvtHelper< Set<1>, Set<3, 4>, Set<CV_8U, CV_16U, CV_32F> > h(_src, _dst, dcn);
|
|
||||||
|
|
||||||
hal::cvtGraytoBGR(h.src.data, h.src.step, h.dst.data, h.dst.step, h.src.cols, h.src.rows, h.depth, dcn);
|
|
||||||
}
|
|
||||||
|
|
||||||
void cvtColor5x52Gray( InputArray _src, OutputArray _dst, int gbits)
|
|
||||||
{
|
|
||||||
CvtHelper< Set<2>, Set<1>, Set<CV_8U> > h(_src, _dst, 1);
|
|
||||||
|
|
||||||
hal::cvtBGR5x5toGray(h.src.data, h.src.step, h.dst.data, h.dst.step, h.src.cols, h.src.rows, gbits);
|
|
||||||
}
|
|
||||||
|
|
||||||
void cvtColorGray25x5( InputArray _src, OutputArray _dst, int gbits)
|
|
||||||
{
|
|
||||||
CvtHelper< Set<1>, Set<2>, Set<CV_8U> > h(_src, _dst, 2);
|
|
||||||
|
|
||||||
hal::cvtGraytoBGR5x5(h.src.data, h.src.step, h.dst.data, h.dst.step, h.src.cols, h.src.rows, gbits);
|
|
||||||
}
|
|
||||||
|
|
||||||
void cvtColorRGBA2mRGBA( InputArray _src, OutputArray _dst)
|
|
||||||
{
|
|
||||||
CvtHelper< Set<4>, Set<4>, Set<CV_8U> > h(_src, _dst, 4);
|
|
||||||
|
|
||||||
hal::cvtRGBAtoMultipliedRGBA(h.src.data, h.src.step, h.dst.data, h.dst.step, h.src.cols, h.src.rows);
|
|
||||||
}
|
|
||||||
|
|
||||||
void cvtColormRGBA2RGBA( InputArray _src, OutputArray _dst)
|
|
||||||
{
|
|
||||||
CvtHelper< Set<4>, Set<4>, Set<CV_8U> > h(_src, _dst, 4);
|
|
||||||
|
|
||||||
hal::cvtMultipliedRGBAtoRGBA(h.src.data, h.src.step, h.dst.data, h.dst.step, h.src.cols, h.src.rows);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace cv
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -3,11 +3,54 @@
|
|||||||
// of this distribution and at http://opencv.org/license.html
|
// of this distribution and at http://opencv.org/license.html
|
||||||
|
|
||||||
#include "precomp.hpp"
|
#include "precomp.hpp"
|
||||||
#include "color.hpp"
|
#include "opencv2/core/hal/intrin.hpp"
|
||||||
|
|
||||||
namespace cv
|
namespace cv {
|
||||||
{
|
namespace hal {
|
||||||
|
CV_CPU_OPTIMIZATION_NAMESPACE_BEGIN
|
||||||
|
// forward declarations
|
||||||
|
void cvtBGRtoYUV(const uchar * src_data, size_t src_step,
|
||||||
|
uchar * dst_data, size_t dst_step,
|
||||||
|
int width, int height,
|
||||||
|
int depth, int scn, bool swapBlue, bool isCbCr);
|
||||||
|
void cvtYUVtoBGR(const uchar * src_data, size_t src_step,
|
||||||
|
uchar * dst_data, size_t dst_step,
|
||||||
|
int width, int height,
|
||||||
|
int depth, int dcn, bool swapBlue, bool isCbCr);
|
||||||
|
void cvtTwoPlaneYUVtoBGR(const uchar * src_data, size_t src_step,
|
||||||
|
uchar * dst_data, size_t dst_step,
|
||||||
|
int dst_width, int dst_height,
|
||||||
|
int dcn, bool swapBlue, int uIdx);
|
||||||
|
void cvtTwoPlaneYUVtoBGR(const uchar * y_data, const uchar * uv_data, size_t src_step,
|
||||||
|
uchar * dst_data, size_t dst_step,
|
||||||
|
int dst_width, int dst_height,
|
||||||
|
int dcn, bool swapBlue, int uIdx);
|
||||||
|
void cvtThreePlaneYUVtoBGR(const uchar * src_data, size_t src_step,
|
||||||
|
uchar * dst_data, size_t dst_step,
|
||||||
|
int dst_width, int dst_height,
|
||||||
|
int dcn, bool swapBlue, int uIdx);
|
||||||
|
void cvtBGRtoThreePlaneYUV(const uchar * src_data, size_t src_step,
|
||||||
|
uchar * dst_data, size_t dst_step,
|
||||||
|
int width, int height,
|
||||||
|
int scn, bool swapBlue, int uIdx);
|
||||||
|
void cvtBGRtoTwoPlaneYUV(const uchar * src_data, size_t src_step,
|
||||||
|
uchar * y_data, uchar * uv_data, size_t dst_step,
|
||||||
|
int width, int height,
|
||||||
|
int scn, bool swapBlue, int uIdx);
|
||||||
|
void cvtOnePlaneYUVtoBGR(const uchar * src_data, size_t src_step,
|
||||||
|
uchar * dst_data, size_t dst_step,
|
||||||
|
int width, int height,
|
||||||
|
int dcn, bool swapBlue, int uIdx, int ycn);
|
||||||
|
|
||||||
|
#ifndef CV_CPU_OPTIMIZATION_DECLARATIONS_ONLY
|
||||||
|
|
||||||
|
#if defined(CV_CPU_BASELINE_MODE)
|
||||||
|
// included in color.hpp
|
||||||
|
#else
|
||||||
|
#include "color.simd_helpers.hpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace {
|
||||||
//constants for conversion from/to RGB and YUV, YCrCb according to BT.601
|
//constants for conversion from/to RGB and YUV, YCrCb according to BT.601
|
||||||
|
|
||||||
//to YCbCr
|
//to YCbCr
|
||||||
@ -1738,12 +1781,8 @@ inline void cvtYUV422toRGB(uchar * dst_data, size_t dst_step, const uchar * src_
|
|||||||
converter(Range(0, height));
|
converter(Range(0, height));
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
} // namespace anon
|
||||||
// HAL functions
|
|
||||||
//
|
|
||||||
|
|
||||||
namespace hal
|
|
||||||
{
|
|
||||||
|
|
||||||
// 8u, 16u, 32f
|
// 8u, 16u, 32f
|
||||||
void cvtBGRtoYUV(const uchar * src_data, size_t src_step,
|
void cvtBGRtoYUV(const uchar * src_data, size_t src_step,
|
||||||
@ -1753,43 +1792,6 @@ void cvtBGRtoYUV(const uchar * src_data, size_t src_step,
|
|||||||
{
|
{
|
||||||
CV_INSTRUMENT_REGION();
|
CV_INSTRUMENT_REGION();
|
||||||
|
|
||||||
CALL_HAL(cvtBGRtoYUV, cv_hal_cvtBGRtoYUV, src_data, src_step, dst_data, dst_step, width, height, depth, scn, swapBlue, isCbCr);
|
|
||||||
|
|
||||||
#if defined(HAVE_IPP)
|
|
||||||
#if !IPP_DISABLE_RGB_YUV
|
|
||||||
CV_IPP_CHECK()
|
|
||||||
{
|
|
||||||
if (scn == 3 && depth == CV_8U && swapBlue && !isCbCr)
|
|
||||||
{
|
|
||||||
if (CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
|
|
||||||
IPPGeneralFunctor((ippiGeneralFunc)ippiRGBToYUV_8u_C3R)))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if (scn == 3 && depth == CV_8U && !swapBlue && !isCbCr)
|
|
||||||
{
|
|
||||||
if (CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
|
|
||||||
IPPReorderGeneralFunctor(ippiSwapChannelsC3RTab[depth],
|
|
||||||
(ippiGeneralFunc)ippiRGBToYUV_8u_C3R, 2, 1, 0, depth)))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if (scn == 4 && depth == CV_8U && swapBlue && !isCbCr)
|
|
||||||
{
|
|
||||||
if (CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
|
|
||||||
IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth],
|
|
||||||
(ippiGeneralFunc)ippiRGBToYUV_8u_C3R, 0, 1, 2, depth)))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if (scn == 4 && depth == CV_8U && !swapBlue && !isCbCr)
|
|
||||||
{
|
|
||||||
if (CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
|
|
||||||
IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth],
|
|
||||||
(ippiGeneralFunc)ippiRGBToYUV_8u_C3R, 2, 1, 0, depth)))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int blueIdx = swapBlue ? 2 : 0;
|
int blueIdx = swapBlue ? 2 : 0;
|
||||||
if( depth == CV_8U )
|
if( depth == CV_8U )
|
||||||
CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, RGB2YCrCb_i<uchar>(scn, blueIdx, isCbCr));
|
CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, RGB2YCrCb_i<uchar>(scn, blueIdx, isCbCr));
|
||||||
@ -1806,44 +1808,6 @@ void cvtYUVtoBGR(const uchar * src_data, size_t src_step,
|
|||||||
{
|
{
|
||||||
CV_INSTRUMENT_REGION();
|
CV_INSTRUMENT_REGION();
|
||||||
|
|
||||||
CALL_HAL(cvtYUVtoBGR, cv_hal_cvtYUVtoBGR, src_data, src_step, dst_data, dst_step, width, height, depth, dcn, swapBlue, isCbCr);
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(HAVE_IPP)
|
|
||||||
#if !IPP_DISABLE_YUV_RGB
|
|
||||||
CV_IPP_CHECK()
|
|
||||||
{
|
|
||||||
if (dcn == 3 && depth == CV_8U && swapBlue && !isCbCr)
|
|
||||||
{
|
|
||||||
if (CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
|
|
||||||
IPPGeneralFunctor((ippiGeneralFunc)ippiYUVToRGB_8u_C3R)))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if (dcn == 3 && depth == CV_8U && !swapBlue && !isCbCr)
|
|
||||||
{
|
|
||||||
if (CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
|
|
||||||
IPPGeneralReorderFunctor((ippiGeneralFunc)ippiYUVToRGB_8u_C3R,
|
|
||||||
ippiSwapChannelsC3RTab[depth], 2, 1, 0, depth)))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if (dcn == 4 && depth == CV_8U && swapBlue && !isCbCr)
|
|
||||||
{
|
|
||||||
if (CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
|
|
||||||
IPPGeneralReorderFunctor((ippiGeneralFunc)ippiYUVToRGB_8u_C3R,
|
|
||||||
ippiSwapChannelsC3C4RTab[depth], 0, 1, 2, depth)))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if (dcn == 4 && depth == CV_8U && !swapBlue && !isCbCr)
|
|
||||||
{
|
|
||||||
if (CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
|
|
||||||
IPPGeneralReorderFunctor((ippiGeneralFunc)ippiYUVToRGB_8u_C3R,
|
|
||||||
ippiSwapChannelsC3C4RTab[depth], 2, 1, 0, depth)))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int blueIdx = swapBlue ? 2 : 0;
|
int blueIdx = swapBlue ? 2 : 0;
|
||||||
if( depth == CV_8U )
|
if( depth == CV_8U )
|
||||||
CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, YCrCb2RGB_i<uchar>(dcn, blueIdx, isCbCr));
|
CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, YCrCb2RGB_i<uchar>(dcn, blueIdx, isCbCr));
|
||||||
@ -1860,7 +1824,6 @@ void cvtTwoPlaneYUVtoBGR(const uchar * src_data, size_t src_step,
|
|||||||
{
|
{
|
||||||
CV_INSTRUMENT_REGION();
|
CV_INSTRUMENT_REGION();
|
||||||
|
|
||||||
CALL_HAL(cvtTwoPlaneYUVtoBGR, cv_hal_cvtTwoPlaneYUVtoBGR, src_data, src_step, dst_data, dst_step, dst_width, dst_height, dcn, swapBlue, uIdx);
|
|
||||||
const uchar* uv = src_data + src_step * static_cast<size_t>(dst_height);
|
const uchar* uv = src_data + src_step * static_cast<size_t>(dst_height);
|
||||||
cvtTwoPlaneYUVtoBGR(src_data, uv, src_step, dst_data, dst_step, dst_width, dst_height, dcn, swapBlue, uIdx);
|
cvtTwoPlaneYUVtoBGR(src_data, uv, src_step, dst_data, dst_step, dst_width, dst_height, dcn, swapBlue, uIdx);
|
||||||
}
|
}
|
||||||
@ -1880,8 +1843,6 @@ void cvtTwoPlaneYUVtoBGR(const uchar * y_data, const uchar * uv_data, size_t src
|
|||||||
{
|
{
|
||||||
CV_INSTRUMENT_REGION();
|
CV_INSTRUMENT_REGION();
|
||||||
|
|
||||||
// TODO: add hal replacement method
|
|
||||||
|
|
||||||
int blueIdx = swapBlue ? 2 : 0;
|
int blueIdx = swapBlue ? 2 : 0;
|
||||||
|
|
||||||
cvt_2plane_yuv_ptr_t cvtPtr;
|
cvt_2plane_yuv_ptr_t cvtPtr;
|
||||||
@ -1919,7 +1880,6 @@ void cvtThreePlaneYUVtoBGR(const uchar * src_data, size_t src_step,
|
|||||||
{
|
{
|
||||||
CV_INSTRUMENT_REGION();
|
CV_INSTRUMENT_REGION();
|
||||||
|
|
||||||
CALL_HAL(cvtThreePlaneYUVtoBGR, cv_hal_cvtThreePlaneYUVtoBGR, src_data, src_step, dst_data, dst_step, dst_width, dst_height, dcn, swapBlue, uIdx);
|
|
||||||
const uchar* u = src_data + src_step * static_cast<size_t>(dst_height);
|
const uchar* u = src_data + src_step * static_cast<size_t>(dst_height);
|
||||||
const uchar* v = src_data + src_step * static_cast<size_t>(dst_height + dst_height/4) + (dst_width/2) * ((dst_height % 4)/2);
|
const uchar* v = src_data + src_step * static_cast<size_t>(dst_height + dst_height/4) + (dst_width/2) * ((dst_height % 4)/2);
|
||||||
|
|
||||||
@ -1949,7 +1909,6 @@ void cvtBGRtoThreePlaneYUV(const uchar * src_data, size_t src_step,
|
|||||||
{
|
{
|
||||||
CV_INSTRUMENT_REGION();
|
CV_INSTRUMENT_REGION();
|
||||||
|
|
||||||
CALL_HAL(cvtBGRtoThreePlaneYUV, cv_hal_cvtBGRtoThreePlaneYUV, src_data, src_step, dst_data, dst_step, width, height, scn, swapBlue, uIdx);
|
|
||||||
uchar * uv_data = dst_data + dst_step * height;
|
uchar * uv_data = dst_data + dst_step * height;
|
||||||
|
|
||||||
RGB8toYUV420pInvoker cvt(src_data, src_step, dst_data, uv_data, dst_step, width, height,
|
RGB8toYUV420pInvoker cvt(src_data, src_step, dst_data, uv_data, dst_step, width, height,
|
||||||
@ -1968,8 +1927,6 @@ void cvtBGRtoTwoPlaneYUV(const uchar * src_data, size_t src_step,
|
|||||||
{
|
{
|
||||||
CV_INSTRUMENT_REGION();
|
CV_INSTRUMENT_REGION();
|
||||||
|
|
||||||
// TODO: add hal replacement method
|
|
||||||
|
|
||||||
RGB8toYUV420pInvoker cvt(src_data, src_step, y_data, uv_data, dst_step, width, height,
|
RGB8toYUV420pInvoker cvt(src_data, src_step, y_data, uv_data, dst_step, width, height,
|
||||||
scn, swapBlue, uIdx == 2, true);
|
scn, swapBlue, uIdx == 2, true);
|
||||||
|
|
||||||
@ -1993,8 +1950,6 @@ void cvtOnePlaneYUVtoBGR(const uchar * src_data, size_t src_step,
|
|||||||
{
|
{
|
||||||
CV_INSTRUMENT_REGION();
|
CV_INSTRUMENT_REGION();
|
||||||
|
|
||||||
CALL_HAL(cvtOnePlaneYUVtoBGR, cv_hal_cvtOnePlaneYUVtoBGR, src_data, src_step, dst_data, dst_step, width, height, dcn, swapBlue, uIdx, ycn);
|
|
||||||
|
|
||||||
cvt_1plane_yuv_ptr_t cvtPtr;
|
cvt_1plane_yuv_ptr_t cvtPtr;
|
||||||
int blueIdx = swapBlue ? 2 : 0;
|
int blueIdx = swapBlue ? 2 : 0;
|
||||||
switch(dcn*1000 + blueIdx*100 + uIdx*10 + ycn)
|
switch(dcn*1000 + blueIdx*100 + uIdx*10 + ycn)
|
||||||
@ -2017,227 +1972,6 @@ void cvtOnePlaneYUVtoBGR(const uchar * src_data, size_t src_step,
|
|||||||
cvtPtr(dst_data, dst_step, src_data, src_step, width, height);
|
cvtPtr(dst_data, dst_step, src_data, src_step, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace hal
|
|
||||||
|
|
||||||
//
|
|
||||||
// OCL calls
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifdef HAVE_OPENCL
|
|
||||||
|
|
||||||
bool oclCvtColorYUV2BGR( InputArray _src, OutputArray _dst, int dcn, int bidx )
|
|
||||||
{
|
|
||||||
OclHelper< Set<3>, Set<3, 4>, Set<CV_8U, CV_16U, CV_32F> > h(_src, _dst, dcn);
|
|
||||||
|
|
||||||
if(!h.createKernel("YUV2RGB", ocl::imgproc::color_yuv_oclsrc,
|
|
||||||
format("-D dcn=%d -D bidx=%d", dcn, bidx)))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return h.run();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool oclCvtColorBGR2YUV( InputArray _src, OutputArray _dst, int bidx )
|
|
||||||
{
|
|
||||||
OclHelper< Set<3, 4>, Set<3>, Set<CV_8U, CV_16U, CV_32F> > h(_src, _dst, 3);
|
|
||||||
|
|
||||||
if(!h.createKernel("RGB2YUV", ocl::imgproc::color_yuv_oclsrc,
|
|
||||||
format("-D dcn=3 -D bidx=%d", bidx)))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return h.run();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool oclCvtcolorYCrCb2BGR( InputArray _src, OutputArray _dst, int dcn, int bidx)
|
|
||||||
{
|
|
||||||
OclHelper< Set<3>, Set<3, 4>, Set<CV_8U, CV_16U, CV_32F> > h(_src, _dst, dcn);
|
|
||||||
|
|
||||||
if(!h.createKernel("YCrCb2RGB", ocl::imgproc::color_yuv_oclsrc,
|
|
||||||
format("-D dcn=%d -D bidx=%d", dcn, bidx)))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return h.run();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool oclCvtColorBGR2YCrCb( InputArray _src, OutputArray _dst, int bidx)
|
|
||||||
{
|
|
||||||
OclHelper< Set<3, 4>, Set<3>, Set<CV_8U, CV_16U, CV_32F> > h(_src, _dst, 3);
|
|
||||||
|
|
||||||
if(!h.createKernel("RGB2YCrCb", ocl::imgproc::color_yuv_oclsrc,
|
|
||||||
format("-D dcn=3 -D bidx=%d", bidx)))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return h.run();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool oclCvtColorOnePlaneYUV2BGR( InputArray _src, OutputArray _dst, int dcn, int bidx, int uidx, int yidx )
|
|
||||||
{
|
|
||||||
OclHelper< Set<2>, Set<3, 4>, Set<CV_8U> > h(_src, _dst, dcn);
|
|
||||||
|
|
||||||
bool optimized = _src.offset() % 4 == 0 && _src.step() % 4 == 0;
|
|
||||||
if(!h.createKernel("YUV2RGB_422", ocl::imgproc::color_yuv_oclsrc,
|
|
||||||
format("-D dcn=%d -D bidx=%d -D uidx=%d -D yidx=%d%s", dcn, bidx, uidx, yidx,
|
|
||||||
optimized ? " -D USE_OPTIMIZED_LOAD" : "")))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return h.run();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool oclCvtColorYUV2Gray_420( InputArray _src, OutputArray _dst )
|
|
||||||
{
|
|
||||||
OclHelper< Set<1>, Set<1>, Set<CV_8U>, FROM_YUV> h(_src, _dst, 1);
|
|
||||||
|
|
||||||
h.src.rowRange(0, _dst.rows()).copyTo(_dst);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool oclCvtColorTwoPlaneYUV2BGR( InputArray _src, OutputArray _dst, int dcn, int bidx, int uidx )
|
|
||||||
{
|
|
||||||
OclHelper< Set<1>, Set<3, 4>, Set<CV_8U>, FROM_YUV > h(_src, _dst, dcn);
|
|
||||||
|
|
||||||
if(!h.createKernel("YUV2RGB_NVx", ocl::imgproc::color_yuv_oclsrc,
|
|
||||||
format("-D dcn=%d -D bidx=%d -D uidx=%d", dcn, bidx, uidx)))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return h.run();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool oclCvtColorThreePlaneYUV2BGR( InputArray _src, OutputArray _dst, int dcn, int bidx, int uidx )
|
|
||||||
{
|
|
||||||
OclHelper< Set<1>, Set<3, 4>, Set<CV_8U>, FROM_YUV > h(_src, _dst, dcn);
|
|
||||||
|
|
||||||
if(!h.createKernel("YUV2RGB_YV12_IYUV", ocl::imgproc::color_yuv_oclsrc,
|
|
||||||
format("-D dcn=%d -D bidx=%d -D uidx=%d%s", dcn, bidx, uidx,
|
|
||||||
_src.isContinuous() ? " -D SRC_CONT" : "")))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return h.run();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool oclCvtColorBGR2ThreePlaneYUV( InputArray _src, OutputArray _dst, int bidx, int uidx )
|
|
||||||
{
|
|
||||||
OclHelper< Set<3, 4>, Set<1>, Set<CV_8U>, TO_YUV > h(_src, _dst, 1);
|
|
||||||
|
|
||||||
if(!h.createKernel("RGB2YUV_YV12_IYUV", ocl::imgproc::color_yuv_oclsrc,
|
|
||||||
format("-D dcn=1 -D bidx=%d -D uidx=%d", bidx, uidx)))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return h.run();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
CV_CPU_OPTIMIZATION_NAMESPACE_END
|
||||||
//
|
}} // namespace
|
||||||
// HAL calls
|
|
||||||
//
|
|
||||||
|
|
||||||
void cvtColorBGR2YUV(InputArray _src, OutputArray _dst, bool swapb, bool crcb)
|
|
||||||
{
|
|
||||||
CvtHelper< Set<3, 4>, Set<3>, Set<CV_8U, CV_16U, CV_32F> > h(_src, _dst, 3);
|
|
||||||
|
|
||||||
hal::cvtBGRtoYUV(h.src.data, h.src.step, h.dst.data, h.dst.step, h.src.cols, h.src.rows,
|
|
||||||
h.depth, h.scn, swapb, crcb);
|
|
||||||
}
|
|
||||||
|
|
||||||
void cvtColorYUV2BGR(InputArray _src, OutputArray _dst, int dcn, bool swapb, bool crcb)
|
|
||||||
{
|
|
||||||
if(dcn <= 0) dcn = 3;
|
|
||||||
CvtHelper< Set<3>, Set<3, 4>, Set<CV_8U, CV_16U, CV_32F> > h(_src, _dst, dcn);
|
|
||||||
|
|
||||||
hal::cvtYUVtoBGR(h.src.data, h.src.step, h.dst.data, h.dst.step, h.src.cols, h.src.rows,
|
|
||||||
h.depth, dcn, swapb, crcb);
|
|
||||||
}
|
|
||||||
|
|
||||||
void cvtColorOnePlaneYUV2BGR( InputArray _src, OutputArray _dst, int dcn, bool swapb, int uidx, int ycn)
|
|
||||||
{
|
|
||||||
CvtHelper< Set<2>, Set<3, 4>, Set<CV_8U> > h(_src, _dst, dcn);
|
|
||||||
|
|
||||||
hal::cvtOnePlaneYUVtoBGR(h.src.data, h.src.step, h.dst.data, h.dst.step, h.src.cols, h.src.rows,
|
|
||||||
dcn, swapb, uidx, ycn);
|
|
||||||
}
|
|
||||||
|
|
||||||
void cvtColorYUV2Gray_ch( InputArray _src, OutputArray _dst, int coi )
|
|
||||||
{
|
|
||||||
CV_Assert( _src.channels() == 2 && _src.depth() == CV_8U );
|
|
||||||
|
|
||||||
extractChannel(_src, _dst, coi);
|
|
||||||
}
|
|
||||||
|
|
||||||
void cvtColorBGR2ThreePlaneYUV( InputArray _src, OutputArray _dst, bool swapb, int uidx)
|
|
||||||
{
|
|
||||||
CvtHelper< Set<3, 4>, Set<1>, Set<CV_8U>, TO_YUV > h(_src, _dst, 1);
|
|
||||||
|
|
||||||
hal::cvtBGRtoThreePlaneYUV(h.src.data, h.src.step, h.dst.data, h.dst.step, h.src.cols, h.src.rows,
|
|
||||||
h.scn, swapb, uidx);
|
|
||||||
}
|
|
||||||
|
|
||||||
void cvtColorYUV2Gray_420( InputArray _src, OutputArray _dst )
|
|
||||||
{
|
|
||||||
CvtHelper< Set<1>, Set<1>, Set<CV_8U>, FROM_YUV > h(_src, _dst, 1);
|
|
||||||
|
|
||||||
#ifdef HAVE_IPP
|
|
||||||
#if IPP_VERSION_X100 >= 201700
|
|
||||||
if (CV_INSTRUMENT_FUN_IPP(ippiCopy_8u_C1R_L, h.src.data, (IppSizeL)h.src.step, h.dst.data, (IppSizeL)h.dst.step,
|
|
||||||
ippiSizeL(h.dstSz.width, h.dstSz.height)) >= 0)
|
|
||||||
return;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
h.src(Range(0, h.dstSz.height), Range::all()).copyTo(h.dst);
|
|
||||||
}
|
|
||||||
|
|
||||||
void cvtColorThreePlaneYUV2BGR( InputArray _src, OutputArray _dst, int dcn, bool swapb, int uidx)
|
|
||||||
{
|
|
||||||
if(dcn <= 0) dcn = 3;
|
|
||||||
CvtHelper< Set<1>, Set<3, 4>, Set<CV_8U>, FROM_YUV> h(_src, _dst, dcn);
|
|
||||||
|
|
||||||
hal::cvtThreePlaneYUVtoBGR(h.src.data, h.src.step, h.dst.data, h.dst.step, h.dst.cols, h.dst.rows,
|
|
||||||
dcn, swapb, uidx);
|
|
||||||
}
|
|
||||||
|
|
||||||
// http://www.fourcc.org/yuv.php#NV21 == yuv420sp -> a plane of 8 bit Y samples followed by an interleaved V/U plane containing 8 bit 2x2 subsampled chroma samples
|
|
||||||
// http://www.fourcc.org/yuv.php#NV12 -> a plane of 8 bit Y samples followed by an interleaved U/V plane containing 8 bit 2x2 subsampled colour difference samples
|
|
||||||
|
|
||||||
void cvtColorTwoPlaneYUV2BGR( InputArray _src, OutputArray _dst, int dcn, bool swapb, int uidx )
|
|
||||||
{
|
|
||||||
if(dcn <= 0) dcn = 3;
|
|
||||||
CvtHelper< Set<1>, Set<3, 4>, Set<CV_8U>, FROM_YUV> h(_src, _dst, dcn);
|
|
||||||
|
|
||||||
hal::cvtTwoPlaneYUVtoBGR(h.src.data, h.src.step, h.dst.data, h.dst.step, h.dst.cols, h.dst.rows,
|
|
||||||
dcn, swapb, uidx);
|
|
||||||
}
|
|
||||||
|
|
||||||
void cvtColorTwoPlaneYUV2BGRpair( InputArray _ysrc, InputArray _uvsrc, OutputArray _dst, int dcn, bool swapb, int uidx )
|
|
||||||
{
|
|
||||||
int stype = _ysrc.type();
|
|
||||||
int depth = CV_MAT_DEPTH(stype);
|
|
||||||
Size ysz = _ysrc.size(), uvs = _uvsrc.size();
|
|
||||||
CV_Assert( dcn == 3 || dcn == 4 );
|
|
||||||
CV_Assert( depth == CV_8U );
|
|
||||||
CV_Assert( ysz.width == uvs.width * 2 && ysz.height == uvs.height * 2 );
|
|
||||||
|
|
||||||
Mat ysrc = _ysrc.getMat(), uvsrc = _uvsrc.getMat();
|
|
||||||
|
|
||||||
_dst.create( ysz, CV_MAKETYPE(depth, dcn));
|
|
||||||
Mat dst = _dst.getMat();
|
|
||||||
|
|
||||||
hal::cvtTwoPlaneYUVtoBGR(ysrc.data, uvsrc.data, ysrc.step,
|
|
||||||
dst.data, dst.step, dst.cols, dst.rows,
|
|
||||||
dcn, swapb, uidx);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace cv
|
|
||||||
|
Loading…
Reference in New Issue
Block a user