Merge pull request #13997 from alalek:imgproc_dispatch_cvtcolor
commit
7e8cc580c9
13 changed files with 1712 additions and 1262 deletions
@ -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) |
||||||
|
@ -0,0 +1,167 @@ |
|||||||
|
// This file is part of OpenCV project.
|
||||||
|
// 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
|
||||||
|
|
||||||
|
#define CV_DESCALE(x,n) (((x) + (1 << ((n)-1))) >> (n)) |
||||||
|
|
||||||
|
namespace { |
||||||
|
|
||||||
|
//constants for conversion from/to RGB and Gray, YUV, YCrCb according to BT.601
|
||||||
|
static const float B2YF = 0.114f; |
||||||
|
static const float G2YF = 0.587f; |
||||||
|
static 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 inline _Tp max() { return std::numeric_limits<_Tp>::max(); } |
||||||
|
static inline _Tp half() { return (_Tp)(max()/2 + 1); } |
||||||
|
}; |
||||||
|
|
||||||
|
template<> struct ColorChannel<float> |
||||||
|
{ |
||||||
|
typedef float worktype_f; |
||||||
|
static inline float max() { return 1.f; } |
||||||
|
static inline float half() { return 0.5f; } |
||||||
|
}; |
||||||
|
|
||||||
|
/*template<> struct ColorChannel<double>
|
||||||
|
{ |
||||||
|
typedef double worktype_f; |
||||||
|
static double max() { return 1.; } |
||||||
|
static double half() { return 0.5; } |
||||||
|
};*/ |
||||||
|
|
||||||
|
|
||||||
|
template<int i0, int i1 = -1, int i2 = -1> |
||||||
|
struct Set |
||||||
|
{ |
||||||
|
static inline bool contains(int i) |
||||||
|
{ |
||||||
|
return (i == i0 || i == i1 || i == i2); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
template<int i0, int i1> |
||||||
|
struct Set<i0, i1, -1> |
||||||
|
{ |
||||||
|
static inline bool contains(int i) |
||||||
|
{ |
||||||
|
return (i == i0 || i == i1); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
template<int i0> |
||||||
|
struct Set<i0, -1, -1> |
||||||
|
{ |
||||||
|
static inline 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 |
||||||
|
{ |
||||||
|
CvtHelper(InputArray _src, OutputArray _dst, int dcn) |
||||||
|
{ |
||||||
|
CV_Assert(!_src.empty()); |
||||||
|
|
||||||
|
int stype = _src.type(); |
||||||
|
scn = CV_MAT_CN(stype), depth = CV_MAT_DEPTH(stype); |
||||||
|
|
||||||
|
CV_Check(scn, VScn::contains(scn), "Invalid number of channels in input image"); |
||||||
|
CV_Check(dcn, VDcn::contains(dcn), "Invalid number of channels in output image"); |
||||||
|
CV_CheckDepth(depth, VDepth::contains(depth), "Unsupported depth of input image"); |
||||||
|
|
||||||
|
if (_src.getObj() == _dst.getObj()) // inplace processing (#6653)
|
||||||
|
_src.copyTo(src); |
||||||
|
else |
||||||
|
src = _src.getMat(); |
||||||
|
Size sz = src.size(); |
||||||
|
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.getMat(); |
||||||
|
} |
||||||
|
Mat src, dst; |
||||||
|
int depth, scn; |
||||||
|
Size dstSz; |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////// 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; |
||||||
|
|
||||||
|
CvtColorLoop_Invoker(const CvtColorLoop_Invoker&); // = delete;
|
||||||
|
const CvtColorLoop_Invoker& operator= (const CvtColorLoop_Invoker&); // = delete;
|
||||||
|
}; |
||||||
|
|
||||||
|
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) |
||||||
|
{ |
||||||
|
CV_AVX_GUARD |
||||||
|
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)); |
||||||
|
} |
||||||
|
|
||||||
|
} //namespace
|
@ -0,0 +1,358 @@ |
|||||||
|
// This file is part of OpenCV project.
|
||||||
|
// 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
|
||||||
|
|
||||||
|
#include "precomp.hpp" |
||||||
|
|
||||||
|
#include "opencl_kernels_imgproc.hpp" |
||||||
|
|
||||||
|
#include "color.hpp" |
||||||
|
|
||||||
|
#include "color_hsv.simd.hpp" |
||||||
|
#include "color_hsv.simd_declarations.hpp" // defines CV_CPU_DISPATCH_MODES_ALL=AVX2,...,BASELINE based on CMakeLists.txt content |
||||||
|
|
||||||
|
namespace cv { |
||||||
|
|
||||||
|
//
|
||||||
|
// 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
|
||||||
|
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) |
||||||
|
{ |
||||||
|
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 |
||||||
|
|
||||||
|
CV_CPU_DISPATCH(cvtBGRtoHSV, (src_data, src_step, dst_data, dst_step, width, height, depth, scn, swapBlue, isFullRange, isHSV), |
||||||
|
CV_CPU_DISPATCH_MODES_ALL); |
||||||
|
} |
||||||
|
|
||||||
|
// 8u, 32f
|
||||||
|
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) |
||||||
|
{ |
||||||
|
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 |
||||||
|
|
||||||
|
CV_CPU_DISPATCH(cvtHSVtoBGR, (src_data, src_step, dst_data, dst_step, width, height, depth, dcn, swapBlue, isFullRange, isHSV), |
||||||
|
CV_CPU_DISPATCH_MODES_ALL); |
||||||
|
} |
||||||
|
|
||||||
|
} // 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 |
||||||
|
|
||||||
|
//
|
||||||
|
// 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
|
@ -0,0 +1,619 @@ |
|||||||
|
// This file is part of OpenCV project.
|
||||||
|
// 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
|
||||||
|
|
||||||
|
#include "precomp.hpp" |
||||||
|
#include "opencl_kernels_imgproc.hpp" |
||||||
|
|
||||||
|
#include "color.hpp" |
||||||
|
|
||||||
|
#include "color_rgb.simd.hpp" |
||||||
|
#include "color_rgb.simd_declarations.hpp" // defines CV_CPU_DISPATCH_MODES_ALL=AVX2,...,BASELINE based on CMakeLists.txt content |
||||||
|
|
||||||
|
#define IPP_DISABLE_CVTCOLOR_GRAY2BGR_8UC3 1 |
||||||
|
|
||||||
|
namespace cv { |
||||||
|
|
||||||
|
//
|
||||||
|
// IPP functions
|
||||||
|
//
|
||||||
|
|
||||||
|
#if NEED_IPP |
||||||
|
|
||||||
|
static const ippiColor2GrayFunc ippiColor2GrayC3Tab[] = |
||||||
|
{ |
||||||
|
(ippiColor2GrayFunc)ippiColorToGray_8u_C3C1R, 0, (ippiColor2GrayFunc)ippiColorToGray_16u_C3C1R, 0, |
||||||
|
0, (ippiColor2GrayFunc)ippiColorToGray_32f_C3C1R, 0, 0 |
||||||
|
}; |
||||||
|
|
||||||
|
static const ippiColor2GrayFunc ippiColor2GrayC4Tab[] = |
||||||
|
{ |
||||||
|
(ippiColor2GrayFunc)ippiColorToGray_8u_AC4C1R, 0, (ippiColor2GrayFunc)ippiColorToGray_16u_AC4C1R, 0, |
||||||
|
0, (ippiColor2GrayFunc)ippiColorToGray_32f_AC4C1R, 0, 0 |
||||||
|
}; |
||||||
|
|
||||||
|
static const ippiGeneralFunc ippiRGB2GrayC3Tab[] = |
||||||
|
{ |
||||||
|
(ippiGeneralFunc)ippiRGBToGray_8u_C3C1R, 0, (ippiGeneralFunc)ippiRGBToGray_16u_C3C1R, 0, |
||||||
|
0, (ippiGeneralFunc)ippiRGBToGray_32f_C3C1R, 0, 0 |
||||||
|
}; |
||||||
|
|
||||||
|
static const 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
|
||||||
|
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) |
||||||
|
{ |
||||||
|
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 |
||||||
|
|
||||||
|
CV_CPU_DISPATCH(cvtBGRtoBGR, (src_data, src_step, dst_data, dst_step, width, height, depth, scn, dcn, swapBlue), |
||||||
|
CV_CPU_DISPATCH_MODES_ALL); |
||||||
|
} |
||||||
|
|
||||||
|
// only 8u
|
||||||
|
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) |
||||||
|
{ |
||||||
|
CV_INSTRUMENT_REGION(); |
||||||
|
|
||||||
|
CALL_HAL(cvtBGRtoBGR5x5, cv_hal_cvtBGRtoBGR5x5, src_data, src_step, dst_data, dst_step, width, height, scn, swapBlue, greenBits); |
||||||
|
|
||||||
|
CV_CPU_DISPATCH(cvtBGRtoBGR5x5, (src_data, src_step, dst_data, dst_step, width, height, scn, swapBlue, greenBits), |
||||||
|
CV_CPU_DISPATCH_MODES_ALL); |
||||||
|
} |
||||||
|
|
||||||
|
// only 8u
|
||||||
|
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) |
||||||
|
{ |
||||||
|
CV_INSTRUMENT_REGION(); |
||||||
|
|
||||||
|
CALL_HAL(cvtBGR5x5toBGR, cv_hal_cvtBGR5x5toBGR, src_data, src_step, dst_data, dst_step, width, height, dcn, swapBlue, greenBits); |
||||||
|
|
||||||
|
CV_CPU_DISPATCH(cvtBGR5x5toBGR, (src_data, src_step, dst_data, dst_step, width, height, dcn, swapBlue, greenBits), |
||||||
|
CV_CPU_DISPATCH_MODES_ALL); |
||||||
|
} |
||||||
|
|
||||||
|
// 8u, 16u, 32f
|
||||||
|
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) |
||||||
|
{ |
||||||
|
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 |
||||||
|
|
||||||
|
CV_CPU_DISPATCH(cvtBGRtoGray, (src_data, src_step, dst_data, dst_step, width, height, depth, scn, swapBlue), |
||||||
|
CV_CPU_DISPATCH_MODES_ALL); |
||||||
|
} |
||||||
|
|
||||||
|
// 8u, 16u, 32f
|
||||||
|
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) |
||||||
|
{ |
||||||
|
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 |
||||||
|
|
||||||
|
CV_CPU_DISPATCH(cvtGraytoBGR, (src_data, src_step, dst_data, dst_step, width, height, depth, dcn), |
||||||
|
CV_CPU_DISPATCH_MODES_ALL); |
||||||
|
} |
||||||
|
|
||||||
|
// only 8u
|
||||||
|
void cvtBGR5x5toGray(const uchar * src_data, size_t src_step, |
||||||
|
uchar * dst_data, size_t dst_step, |
||||||
|
int width, int height, |
||||||
|
int greenBits) |
||||||
|
{ |
||||||
|
CV_INSTRUMENT_REGION(); |
||||||
|
|
||||||
|
CALL_HAL(cvtBGR5x5toGray, cv_hal_cvtBGR5x5toGray, src_data, src_step, dst_data, dst_step, width, height, greenBits); |
||||||
|
|
||||||
|
CV_CPU_DISPATCH(cvtBGR5x5toGray, (src_data, src_step, dst_data, dst_step, width, height, greenBits), |
||||||
|
CV_CPU_DISPATCH_MODES_ALL); |
||||||
|
} |
||||||
|
|
||||||
|
// only 8u
|
||||||
|
void cvtGraytoBGR5x5(const uchar * src_data, size_t src_step, |
||||||
|
uchar * dst_data, size_t dst_step, |
||||||
|
int width, int height, |
||||||
|
int greenBits) |
||||||
|
{ |
||||||
|
CV_INSTRUMENT_REGION(); |
||||||
|
|
||||||
|
CALL_HAL(cvtGraytoBGR5x5, cv_hal_cvtGraytoBGR5x5, src_data, src_step, dst_data, dst_step, width, height, greenBits); |
||||||
|
|
||||||
|
CV_CPU_DISPATCH(cvtGraytoBGR5x5, (src_data, src_step, dst_data, dst_step, width, height, greenBits), |
||||||
|
CV_CPU_DISPATCH_MODES_ALL); |
||||||
|
} |
||||||
|
|
||||||
|
void cvtRGBAtoMultipliedRGBA(const uchar * src_data, size_t src_step, |
||||||
|
uchar * dst_data, size_t dst_step, |
||||||
|
int width, int height) |
||||||
|
{ |
||||||
|
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 |
||||||
|
|
||||||
|
CV_CPU_DISPATCH(cvtRGBAtoMultipliedRGBA, (src_data, src_step, dst_data, dst_step, width, height), |
||||||
|
CV_CPU_DISPATCH_MODES_ALL); |
||||||
|
} |
||||||
|
|
||||||
|
void cvtMultipliedRGBAtoRGBA(const uchar * src_data, size_t src_step, |
||||||
|
uchar * dst_data, size_t dst_step, |
||||||
|
int width, int height) |
||||||
|
{ |
||||||
|
CV_INSTRUMENT_REGION(); |
||||||
|
|
||||||
|
CALL_HAL(cvtMultipliedRGBAtoRGBA, cv_hal_cvtMultipliedRGBAtoRGBA, src_data, src_step, dst_data, dst_step, width, height); |
||||||
|
|
||||||
|
CV_CPU_DISPATCH(cvtMultipliedRGBAtoRGBA, (src_data, src_step, dst_data, dst_step, width, height), |
||||||
|
CV_CPU_DISPATCH_MODES_ALL); |
||||||
|
} |
||||||
|
|
||||||
|
} // 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 |
||||||
|
|
||||||
|
//
|
||||||
|
// 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
|
@ -0,0 +1,417 @@ |
|||||||
|
// This file is part of OpenCV project.
|
||||||
|
// 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
|
||||||
|
|
||||||
|
#include "precomp.hpp" |
||||||
|
#include "opencl_kernels_imgproc.hpp" |
||||||
|
|
||||||
|
#include "color.hpp" |
||||||
|
|
||||||
|
#include "color_yuv.simd.hpp" |
||||||
|
#include "color_yuv.simd_declarations.hpp" // defines CV_CPU_DISPATCH_MODES_ALL=AVX2,...,BASELINE based on CMakeLists.txt content |
||||||
|
|
||||||
|
namespace cv { |
||||||
|
|
||||||
|
//
|
||||||
|
// HAL functions
|
||||||
|
//
|
||||||
|
namespace hal { |
||||||
|
|
||||||
|
// 8u, 16u, 32f
|
||||||
|
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) |
||||||
|
{ |
||||||
|
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 |
||||||
|
|
||||||
|
CV_CPU_DISPATCH(cvtBGRtoYUV, (src_data, src_step, dst_data, dst_step, width, height, depth, scn, swapBlue, isCbCr), |
||||||
|
CV_CPU_DISPATCH_MODES_ALL); |
||||||
|
} |
||||||
|
|
||||||
|
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) |
||||||
|
{ |
||||||
|
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 |
||||||
|
|
||||||
|
CV_CPU_DISPATCH(cvtYUVtoBGR, (src_data, src_step, dst_data, dst_step, width, height, depth, dcn, swapBlue, isCbCr), |
||||||
|
CV_CPU_DISPATCH_MODES_ALL); |
||||||
|
} |
||||||
|
|
||||||
|
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) |
||||||
|
{ |
||||||
|
CV_INSTRUMENT_REGION(); |
||||||
|
|
||||||
|
CALL_HAL(cvtTwoPlaneYUVtoBGR, cv_hal_cvtTwoPlaneYUVtoBGR, src_data, src_step, dst_data, dst_step, dst_width, dst_height, dcn, swapBlue, uIdx); |
||||||
|
|
||||||
|
CV_CPU_DISPATCH(cvtTwoPlaneYUVtoBGR, (src_data, src_step, dst_data, dst_step, dst_width, dst_height, dcn, swapBlue, uIdx), |
||||||
|
CV_CPU_DISPATCH_MODES_ALL); |
||||||
|
} |
||||||
|
|
||||||
|
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) |
||||||
|
{ |
||||||
|
CV_INSTRUMENT_REGION(); |
||||||
|
|
||||||
|
CV_CPU_DISPATCH(cvtTwoPlaneYUVtoBGR, (y_data, uv_data, src_step, dst_data, dst_step, dst_width, dst_height, dcn, swapBlue, uIdx), |
||||||
|
CV_CPU_DISPATCH_MODES_ALL); |
||||||
|
} |
||||||
|
|
||||||
|
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) |
||||||
|
{ |
||||||
|
CV_INSTRUMENT_REGION(); |
||||||
|
|
||||||
|
CALL_HAL(cvtThreePlaneYUVtoBGR, cv_hal_cvtThreePlaneYUVtoBGR, src_data, src_step, dst_data, dst_step, dst_width, dst_height, dcn, swapBlue, uIdx); |
||||||
|
|
||||||
|
CV_CPU_DISPATCH(cvtThreePlaneYUVtoBGR, (src_data, src_step, dst_data, dst_step, dst_width, dst_height, dcn, swapBlue, uIdx), |
||||||
|
CV_CPU_DISPATCH_MODES_ALL); |
||||||
|
} |
||||||
|
|
||||||
|
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) |
||||||
|
{ |
||||||
|
CV_INSTRUMENT_REGION(); |
||||||
|
|
||||||
|
CALL_HAL(cvtBGRtoThreePlaneYUV, cv_hal_cvtBGRtoThreePlaneYUV, src_data, src_step, dst_data, dst_step, width, height, scn, swapBlue, uIdx); |
||||||
|
|
||||||
|
CV_CPU_DISPATCH(cvtBGRtoThreePlaneYUV, (src_data, src_step, dst_data, dst_step, width, height, scn, swapBlue, uIdx), |
||||||
|
CV_CPU_DISPATCH_MODES_ALL); |
||||||
|
} |
||||||
|
|
||||||
|
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) |
||||||
|
{ |
||||||
|
CV_INSTRUMENT_REGION(); |
||||||
|
|
||||||
|
// TODO: add hal replacement method
|
||||||
|
|
||||||
|
CV_CPU_DISPATCH(cvtBGRtoTwoPlaneYUV, (src_data, src_step, y_data, uv_data, dst_step, width, height, scn, swapBlue, uIdx), |
||||||
|
CV_CPU_DISPATCH_MODES_ALL); |
||||||
|
} |
||||||
|
|
||||||
|
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) |
||||||
|
{ |
||||||
|
CV_INSTRUMENT_REGION(); |
||||||
|
|
||||||
|
CALL_HAL(cvtOnePlaneYUVtoBGR, cv_hal_cvtOnePlaneYUVtoBGR, src_data, src_step, dst_data, dst_step, width, height, dcn, swapBlue, uIdx, ycn); |
||||||
|
|
||||||
|
CV_CPU_DISPATCH(cvtOnePlaneYUVtoBGR, (src_data, src_step, dst_data, dst_step, width, height, dcn, swapBlue, uIdx, ycn), |
||||||
|
CV_CPU_DISPATCH_MODES_ALL); |
||||||
|
} |
||||||
|
|
||||||
|
} // 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 |
||||||
|
|
||||||
|
//
|
||||||
|
// 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