mirror of
https://github.com/opencv/opencv.git
synced 2026-07-31 00:03:03 +04:00
Merge branch 4.x
This commit is contained in:
@@ -12,6 +12,7 @@
|
||||
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
|
||||
// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
|
||||
// Copyright (C) 2014, Itseez Inc., all rights reserved.
|
||||
// Copyright (C) 2025, SpaceMIT Inc., all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
@@ -192,6 +193,41 @@ copyMask_<uchar>(const uchar* _src, size_t sstep, const uchar* mask, size_t mste
|
||||
}
|
||||
}
|
||||
|
||||
template<> void
|
||||
copyMask_<Vec3b>(const uchar* _src, size_t sstep, const uchar* mask, size_t mstep, uchar* _dst, size_t dstep, Size size)
|
||||
{
|
||||
for( ; size.height--; mask += mstep, _src += sstep, _dst += dstep )
|
||||
{
|
||||
const uchar* src = (const uchar*)_src;
|
||||
uchar* dst = (uchar*)_dst;
|
||||
int x = 0;
|
||||
#if (CV_SIMD || CV_SIMD_SCALABLE)
|
||||
for( ; x <= size.width - VTraits<v_uint8>::vlanes(); x += VTraits<v_uint8>::vlanes() )
|
||||
{
|
||||
v_uint8 v_nmask = v_eq(vx_load(mask + x), vx_setzero_u8());
|
||||
|
||||
v_uint8 v_src0, v_src1, v_src2;
|
||||
v_uint8 v_dst0, v_dst1, v_dst2;
|
||||
v_load_deinterleave(src + 3 * x, v_src0, v_src1, v_src2);
|
||||
v_load_deinterleave(dst + 3 * x, v_dst0, v_dst1, v_dst2);
|
||||
|
||||
v_dst0 = v_select(v_nmask, v_dst0, v_src0);
|
||||
v_dst1 = v_select(v_nmask, v_dst1, v_src1);
|
||||
v_dst2 = v_select(v_nmask, v_dst2, v_src2);
|
||||
|
||||
v_store_interleave(dst + 3 * x, v_dst0, v_dst1, v_dst2);
|
||||
}
|
||||
vx_cleanup();
|
||||
#endif
|
||||
for( ; x < size.width; x++ )
|
||||
if( mask[x] ) {
|
||||
dst[3 * x] = src[3 * x];
|
||||
dst[3 * x + 1] = src[3 * x + 1];
|
||||
dst[3 * x + 2] = src[3 * x + 2];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<> void
|
||||
copyMask_<ushort>(const uchar* _src, size_t sstep, const uchar* mask, size_t mstep, uchar* _dst, size_t dstep, Size size)
|
||||
{
|
||||
@@ -229,6 +265,92 @@ copyMask_<ushort>(const uchar* _src, size_t sstep, const uchar* mask, size_t mst
|
||||
}
|
||||
}
|
||||
|
||||
template<> void
|
||||
copyMask_<Vec3s>(const uchar* _src, size_t sstep, const uchar* mask, size_t mstep, uchar* _dst, size_t dstep, Size size)
|
||||
{
|
||||
for( ; size.height--; mask += mstep, _src += sstep, _dst += dstep )
|
||||
{
|
||||
const ushort* src = (const ushort*)_src;
|
||||
ushort* dst = (ushort*)_dst;
|
||||
int x = 0;
|
||||
#if (CV_SIMD || CV_SIMD_SCALABLE)
|
||||
for( ; x <= size.width - VTraits<v_uint8>::vlanes(); x += VTraits<v_uint8>::vlanes() )
|
||||
{
|
||||
v_uint8 v_nmask = v_eq(vx_load(mask + x), vx_setzero_u8());
|
||||
v_uint8 v_nmask0, v_nmask1;
|
||||
v_zip(v_nmask, v_nmask, v_nmask0, v_nmask1);
|
||||
|
||||
v_uint16 v_src0, v_src1, v_src2;
|
||||
v_uint16 v_dst0, v_dst1, v_dst2;
|
||||
v_load_deinterleave(src + 3 * x, v_src0, v_src1, v_src2);
|
||||
v_load_deinterleave(dst + 3 * x, v_dst0, v_dst1, v_dst2);
|
||||
v_uint16 v_src3, v_src4, v_src5;
|
||||
v_uint16 v_dst3, v_dst4, v_dst5;
|
||||
v_load_deinterleave(src + 3 * (x + VTraits<v_uint16>::vlanes()), v_src3, v_src4, v_src5);
|
||||
v_load_deinterleave(dst + 3 * (x + VTraits<v_uint16>::vlanes()), v_dst3, v_dst4, v_dst5);
|
||||
|
||||
v_dst0 = v_select(v_reinterpret_as_u16(v_nmask0), v_dst0, v_src0);
|
||||
v_dst1 = v_select(v_reinterpret_as_u16(v_nmask0), v_dst1, v_src1);
|
||||
v_dst2 = v_select(v_reinterpret_as_u16(v_nmask0), v_dst2, v_src2);
|
||||
v_dst3 = v_select(v_reinterpret_as_u16(v_nmask1), v_dst3, v_src3);
|
||||
v_dst4 = v_select(v_reinterpret_as_u16(v_nmask1), v_dst4, v_src4);
|
||||
v_dst5 = v_select(v_reinterpret_as_u16(v_nmask1), v_dst5, v_src5);
|
||||
|
||||
v_store_interleave(dst + 3 * x, v_dst0, v_dst1, v_dst2);
|
||||
v_store_interleave(dst + 3 * (x + VTraits<v_uint16>::vlanes()), v_dst3, v_dst4, v_dst5);
|
||||
}
|
||||
vx_cleanup();
|
||||
#endif
|
||||
for( ; x < size.width; x++ )
|
||||
if( mask[x] ) {
|
||||
dst[3 * x] = src[3 * x];
|
||||
dst[3 * x + 1] = src[3 * x + 1];
|
||||
dst[3 * x + 2] = src[3 * x + 2];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<> void
|
||||
copyMask_<int>(const uchar* _src, size_t sstep, const uchar* mask, size_t mstep, uchar* _dst, size_t dstep, Size size)
|
||||
{
|
||||
for( ; size.height--; mask += mstep, _src += sstep, _dst += dstep )
|
||||
{
|
||||
const int* src = (const int*)_src;
|
||||
int* dst = (int*)_dst;
|
||||
int x = 0;
|
||||
#if (CV_SIMD || CV_SIMD_SCALABLE)
|
||||
for (; x <= size.width - VTraits<v_uint8>::vlanes(); x += VTraits<v_uint8>::vlanes())
|
||||
{
|
||||
v_int32 v_src0 = vx_load(src + x), v_dst0 = vx_load(dst + x);
|
||||
v_int32 v_src1 = vx_load(src + x + VTraits<v_int32>::vlanes()), v_dst1 = vx_load(dst + x + VTraits<v_int32>::vlanes());
|
||||
v_int32 v_src2 = vx_load(src + x + 2 * VTraits<v_int32>::vlanes()), v_dst2 = vx_load(dst + x + 2 * VTraits<v_int32>::vlanes());
|
||||
v_int32 v_src3 = vx_load(src + x + 3 * VTraits<v_int32>::vlanes()), v_dst3 = vx_load(dst + x + 3 * VTraits<v_int32>::vlanes());
|
||||
|
||||
v_uint8 v_nmask = v_eq(vx_load(mask + x), vx_setzero_u8());
|
||||
v_uint8 v_nmask0, v_nmask1;
|
||||
v_zip(v_nmask, v_nmask, v_nmask0, v_nmask1);
|
||||
v_uint8 v_nmask00, v_nmask01, v_nmask10, v_nmask11;
|
||||
v_zip(v_nmask0, v_nmask0, v_nmask00, v_nmask01);
|
||||
v_zip(v_nmask1, v_nmask1, v_nmask10, v_nmask11);
|
||||
|
||||
v_dst0 = v_select(v_reinterpret_as_s32(v_nmask00), v_dst0, v_src0);
|
||||
v_dst1 = v_select(v_reinterpret_as_s32(v_nmask01), v_dst1, v_src1);
|
||||
v_dst2 = v_select(v_reinterpret_as_s32(v_nmask10), v_dst2, v_src2);
|
||||
v_dst3 = v_select(v_reinterpret_as_s32(v_nmask11), v_dst3, v_src3);
|
||||
|
||||
vx_store(dst + x, v_dst0);
|
||||
vx_store(dst + x + VTraits<v_int32>::vlanes(), v_dst1);
|
||||
vx_store(dst + x + 2 * VTraits<v_int32>::vlanes(), v_dst2);
|
||||
vx_store(dst + x + 3 * VTraits<v_int32>::vlanes(), v_dst3);
|
||||
}
|
||||
vx_cleanup();
|
||||
#endif
|
||||
for (; x < size.width; x++)
|
||||
if ( mask[x] )
|
||||
dst[x] = src[x];
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
copyMaskGeneric(const uchar* _src, size_t sstep, const uchar* mask, size_t mstep, uchar* _dst, size_t dstep, Size size, void* _esz)
|
||||
{
|
||||
@@ -487,6 +609,18 @@ void Mat::copyTo( OutputArray _dst, InputArray _mask ) const
|
||||
}
|
||||
|
||||
CV_IPP_RUN_FAST(ipp_copyTo(*this, dst, mask))
|
||||
if ( this->dims <= 2 ) {
|
||||
if ( this->size() == dst.size() && this->size() == dst.size() ) {
|
||||
CALL_HAL(copyToMask, cv_hal_copyToMasked, this->data, this->step, dst.data, dst.step, this->cols, this->rows, this->type(), mask.data, mask.step, mask.type());
|
||||
}
|
||||
}
|
||||
else if ( this->isContinuous() && dst.isContinuous() && mask.isContinuous() )
|
||||
{
|
||||
size_t sz = this->total();
|
||||
if (sz < INT_MAX) {
|
||||
CALL_HAL(copyToMask, cv_hal_copyToMasked, this->data, 0, dst.data, 0, (int)sz, 1, this->type(), mask.data, 0, mask.type());
|
||||
}
|
||||
}
|
||||
|
||||
size_t esz = colorMask ? elemSize1() : elemSize();
|
||||
BinaryFunc copymask = getCopyMaskFunc(esz);
|
||||
|
||||
@@ -1207,6 +1207,22 @@ inline int hal_ni_transpose2d(const uchar* src_data, size_t src_step, uchar* dst
|
||||
#define cv_hal_transpose2d hal_ni_transpose2d
|
||||
//! @endcond
|
||||
|
||||
/**
|
||||
@brief copyTo with mask
|
||||
@param src_data, src_step Source image
|
||||
@param dst_data, dst_step Destination image
|
||||
@param width, height Image dimensions of source, destination and mask
|
||||
@param type Type of source and destination images, for example CV_8UC1 or CV_32FC3
|
||||
@param mask_data, mask_step, mask_type Mask
|
||||
*/
|
||||
inline int hal_ni_copyToMasked(const uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, int width, int height,
|
||||
int type, const uchar* mask_data, size_t mask_step, int mask_type)
|
||||
{ return CV_HAL_ERROR_NOT_IMPLEMENTED; }
|
||||
|
||||
//! @cond IGNORED
|
||||
#define cv_hal_copyToMasked hal_ni_copyToMasked
|
||||
//! @endcond
|
||||
|
||||
//! @}
|
||||
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <atomic>
|
||||
|
||||
#ifdef __ANDROID__
|
||||
# include <android/log.h>
|
||||
@@ -181,6 +182,12 @@ LogLevel getLogLevel()
|
||||
|
||||
namespace internal {
|
||||
|
||||
namespace //unnamed
|
||||
{
|
||||
std::atomic<WriteLogMessageFuncType> stc_userWriteLogMessageFunc{};
|
||||
std::atomic<WriteLogMessageExFuncType> stc_userWriteLogMessageExFunc{};
|
||||
} //unnamed
|
||||
|
||||
static int getShowTimestampMode()
|
||||
{
|
||||
static bool param_timestamp_enable = utils::getConfigurationParameterBool("OPENCV_LOG_TIMESTAMP", true);
|
||||
@@ -190,6 +197,13 @@ static int getShowTimestampMode()
|
||||
|
||||
void writeLogMessage(LogLevel logLevel, const char* message)
|
||||
{
|
||||
WriteLogMessageFuncType userFunc = stc_userWriteLogMessageFunc.load();
|
||||
if (userFunc && userFunc != writeLogMessage)
|
||||
{
|
||||
(*userFunc)(logLevel, message);
|
||||
return;
|
||||
}
|
||||
|
||||
const int threadID = cv::utils::getThreadID();
|
||||
|
||||
std::string message_id;
|
||||
@@ -230,7 +244,9 @@ void writeLogMessage(LogLevel logLevel, const char* message)
|
||||
std::ostream* out = (logLevel <= LOG_LEVEL_WARNING) ? &std::cerr : &std::cout;
|
||||
(*out) << ss.str();
|
||||
if (logLevel <= LOG_LEVEL_WARNING)
|
||||
{
|
||||
(*out) << std::flush;
|
||||
}
|
||||
}
|
||||
|
||||
static const char* stripSourceFilePathPrefix(const char* file)
|
||||
@@ -252,6 +268,13 @@ static const char* stripSourceFilePathPrefix(const char* file)
|
||||
|
||||
void writeLogMessageEx(LogLevel logLevel, const char* tag, const char* file, int line, const char* func, const char* message)
|
||||
{
|
||||
WriteLogMessageExFuncType userFunc = stc_userWriteLogMessageExFunc.load();
|
||||
if (userFunc && userFunc != writeLogMessageEx)
|
||||
{
|
||||
(*userFunc)(logLevel, tag, file, line, func, message);
|
||||
return;
|
||||
}
|
||||
|
||||
std::ostringstream strm;
|
||||
if (tag)
|
||||
{
|
||||
@@ -274,6 +297,24 @@ void writeLogMessageEx(LogLevel logLevel, const char* tag, const char* file, int
|
||||
writeLogMessage(logLevel, strm.str().c_str());
|
||||
}
|
||||
|
||||
void replaceWriteLogMessage(WriteLogMessageFuncType f)
|
||||
{
|
||||
if (f == writeLogMessage)
|
||||
{
|
||||
f = nullptr;
|
||||
}
|
||||
stc_userWriteLogMessageFunc.store(f);
|
||||
}
|
||||
|
||||
void replaceWriteLogMessageEx(WriteLogMessageExFuncType f)
|
||||
{
|
||||
if (f == writeLogMessageEx)
|
||||
{
|
||||
f = nullptr;
|
||||
}
|
||||
stc_userWriteLogMessageExFunc.store(f);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
}}} // namespace
|
||||
|
||||
@@ -122,184 +122,6 @@ static bool ocl_LUT(InputArray _src, InputArray _lut, OutputArray _dst)
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_IPP)
|
||||
#if !IPP_DISABLE_PERF_LUT // there are no performance benefits (PR #2653)
|
||||
namespace ipp {
|
||||
|
||||
class IppLUTParallelBody_LUTC1 : public ParallelLoopBody
|
||||
{
|
||||
public:
|
||||
bool* ok;
|
||||
const Mat& src_;
|
||||
const Mat& lut_;
|
||||
Mat& dst_;
|
||||
|
||||
int width;
|
||||
size_t elemSize1;
|
||||
|
||||
IppLUTParallelBody_LUTC1(const Mat& src, const Mat& lut, Mat& dst, bool* _ok)
|
||||
: ok(_ok), src_(src), lut_(lut), dst_(dst)
|
||||
{
|
||||
width = dst.cols * dst.channels();
|
||||
elemSize1 = CV_ELEM_SIZE1(dst.depth());
|
||||
|
||||
CV_DbgAssert(elemSize1 == 1 || elemSize1 == 4);
|
||||
*ok = true;
|
||||
}
|
||||
|
||||
void operator()( const cv::Range& range ) const
|
||||
{
|
||||
if (!*ok)
|
||||
return;
|
||||
|
||||
const int row0 = range.start;
|
||||
const int row1 = range.end;
|
||||
|
||||
Mat src = src_.rowRange(row0, row1);
|
||||
Mat dst = dst_.rowRange(row0, row1);
|
||||
|
||||
IppiSize sz = { width, dst.rows };
|
||||
|
||||
if (elemSize1 == 1)
|
||||
{
|
||||
if (CV_INSTRUMENT_FUN_IPP(ippiLUTPalette_8u_C1R, (const Ipp8u*)src.data, (int)src.step[0], dst.data, (int)dst.step[0], sz, lut_.data, 8) >= 0)
|
||||
return;
|
||||
}
|
||||
else if (elemSize1 == 4)
|
||||
{
|
||||
if (CV_INSTRUMENT_FUN_IPP(ippiLUTPalette_8u32u_C1R, (const Ipp8u*)src.data, (int)src.step[0], (Ipp32u*)dst.data, (int)dst.step[0], sz, (Ipp32u*)lut_.data, 8) >= 0)
|
||||
return;
|
||||
}
|
||||
*ok = false;
|
||||
}
|
||||
private:
|
||||
IppLUTParallelBody_LUTC1(const IppLUTParallelBody_LUTC1&);
|
||||
IppLUTParallelBody_LUTC1& operator=(const IppLUTParallelBody_LUTC1&);
|
||||
};
|
||||
|
||||
class IppLUTParallelBody_LUTCN : public ParallelLoopBody
|
||||
{
|
||||
public:
|
||||
bool *ok;
|
||||
const Mat& src_;
|
||||
const Mat& lut_;
|
||||
Mat& dst_;
|
||||
|
||||
int lutcn;
|
||||
|
||||
uchar* lutBuffer;
|
||||
uchar* lutTable[4];
|
||||
|
||||
IppLUTParallelBody_LUTCN(const Mat& src, const Mat& lut, Mat& dst, bool* _ok)
|
||||
: ok(_ok), src_(src), lut_(lut), dst_(dst), lutBuffer(NULL)
|
||||
{
|
||||
lutcn = lut.channels();
|
||||
IppiSize sz256 = {256, 1};
|
||||
|
||||
size_t elemSize1 = dst.elemSize1();
|
||||
CV_DbgAssert(elemSize1 == 1);
|
||||
lutBuffer = (uchar*)CV_IPP_MALLOC(256 * (int)elemSize1 * 4);
|
||||
lutTable[0] = lutBuffer + 0;
|
||||
lutTable[1] = lutBuffer + 1 * 256 * elemSize1;
|
||||
lutTable[2] = lutBuffer + 2 * 256 * elemSize1;
|
||||
lutTable[3] = lutBuffer + 3 * 256 * elemSize1;
|
||||
|
||||
CV_DbgAssert(lutcn == 3 || lutcn == 4);
|
||||
if (lutcn == 3)
|
||||
{
|
||||
IppStatus status = CV_INSTRUMENT_FUN_IPP(ippiCopy_8u_C3P3R, lut.ptr(), (int)lut.step[0], lutTable, (int)lut.step[0], sz256);
|
||||
if (status < 0)
|
||||
return;
|
||||
}
|
||||
else if (lutcn == 4)
|
||||
{
|
||||
IppStatus status = CV_INSTRUMENT_FUN_IPP(ippiCopy_8u_C4P4R, lut.ptr(), (int)lut.step[0], lutTable, (int)lut.step[0], sz256);
|
||||
if (status < 0)
|
||||
return;
|
||||
}
|
||||
|
||||
*ok = true;
|
||||
}
|
||||
|
||||
~IppLUTParallelBody_LUTCN()
|
||||
{
|
||||
if (lutBuffer != NULL)
|
||||
ippFree(lutBuffer);
|
||||
lutBuffer = NULL;
|
||||
lutTable[0] = NULL;
|
||||
}
|
||||
|
||||
void operator()( const cv::Range& range ) const
|
||||
{
|
||||
if (!*ok)
|
||||
return;
|
||||
|
||||
const int row0 = range.start;
|
||||
const int row1 = range.end;
|
||||
|
||||
Mat src = src_.rowRange(row0, row1);
|
||||
Mat dst = dst_.rowRange(row0, row1);
|
||||
|
||||
if (lutcn == 3)
|
||||
{
|
||||
if (CV_INSTRUMENT_FUN_IPP(ippiLUTPalette_8u_C3R, src.ptr(), (int)src.step[0], dst.ptr(), (int)dst.step[0], ippiSize(dst.size()), lutTable, 8) >= 0)
|
||||
return;
|
||||
}
|
||||
else if (lutcn == 4)
|
||||
{
|
||||
if (CV_INSTRUMENT_FUN_IPP(ippiLUTPalette_8u_C4R, src.ptr(), (int)src.step[0], dst.ptr(), (int)dst.step[0], ippiSize(dst.size()), lutTable, 8) >= 0)
|
||||
return;
|
||||
}
|
||||
*ok = false;
|
||||
}
|
||||
private:
|
||||
IppLUTParallelBody_LUTCN(const IppLUTParallelBody_LUTCN&);
|
||||
IppLUTParallelBody_LUTCN& operator=(const IppLUTParallelBody_LUTCN&);
|
||||
};
|
||||
} // namespace ipp
|
||||
|
||||
static bool ipp_lut(Mat &src, Mat &lut, Mat &dst)
|
||||
{
|
||||
CV_INSTRUMENT_REGION_IPP();
|
||||
|
||||
int lutcn = lut.channels();
|
||||
|
||||
if(src.dims > 2)
|
||||
return false;
|
||||
|
||||
bool ok = false;
|
||||
Ptr<ParallelLoopBody> body;
|
||||
|
||||
size_t elemSize1 = CV_ELEM_SIZE1(dst.depth());
|
||||
|
||||
if (lutcn == 1)
|
||||
{
|
||||
ParallelLoopBody* p = new ipp::IppLUTParallelBody_LUTC1(src, lut, dst, &ok);
|
||||
body.reset(p);
|
||||
}
|
||||
else if ((lutcn == 3 || lutcn == 4) && elemSize1 == 1)
|
||||
{
|
||||
ParallelLoopBody* p = new ipp::IppLUTParallelBody_LUTCN(src, lut, dst, &ok);
|
||||
body.reset(p);
|
||||
}
|
||||
|
||||
if (body != NULL && ok)
|
||||
{
|
||||
Range all(0, dst.rows);
|
||||
if (dst.total()>>18)
|
||||
parallel_for_(all, *body, (double)std::max((size_t)1, dst.total()>>16));
|
||||
else
|
||||
(*body)(all);
|
||||
if (ok)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif // IPP
|
||||
|
||||
class LUTParallelBody : public ParallelLoopBody
|
||||
{
|
||||
public:
|
||||
@@ -366,10 +188,6 @@ void cv::LUT( InputArray _src, InputArray _lut, OutputArray _dst )
|
||||
CALL_HAL(LUT, cv_hal_lut, src.data, src.step, src.type(), lut.data,
|
||||
lut.elemSize1(), lutcn, dst.data, dst.step, src.cols, src.rows);
|
||||
|
||||
#if !IPP_DISABLE_PERF_LUT
|
||||
CV_IPP_RUN(_src.dims() <= 2, ipp_lut(src, lut, dst));
|
||||
#endif
|
||||
|
||||
if (_src.dims() <= 2)
|
||||
{
|
||||
bool ok = false;
|
||||
|
||||
@@ -328,149 +328,6 @@ void cartToPolar( InputArray src1, InputArray src2,
|
||||
* Polar -> Cartezian *
|
||||
\****************************************************************************************/
|
||||
|
||||
static void SinCos_32f( const float *angle, float *sinval, float* cosval,
|
||||
int len, int angle_in_degrees )
|
||||
{
|
||||
const int N = 64;
|
||||
|
||||
static const double sin_table[] =
|
||||
{
|
||||
0.00000000000000000000, 0.09801714032956060400,
|
||||
0.19509032201612825000, 0.29028467725446233000,
|
||||
0.38268343236508978000, 0.47139673682599764000,
|
||||
0.55557023301960218000, 0.63439328416364549000,
|
||||
0.70710678118654746000, 0.77301045336273699000,
|
||||
0.83146961230254524000, 0.88192126434835494000,
|
||||
0.92387953251128674000, 0.95694033573220894000,
|
||||
0.98078528040323043000, 0.99518472667219682000,
|
||||
1.00000000000000000000, 0.99518472667219693000,
|
||||
0.98078528040323043000, 0.95694033573220894000,
|
||||
0.92387953251128674000, 0.88192126434835505000,
|
||||
0.83146961230254546000, 0.77301045336273710000,
|
||||
0.70710678118654757000, 0.63439328416364549000,
|
||||
0.55557023301960218000, 0.47139673682599786000,
|
||||
0.38268343236508989000, 0.29028467725446239000,
|
||||
0.19509032201612861000, 0.09801714032956082600,
|
||||
0.00000000000000012246, -0.09801714032956059000,
|
||||
-0.19509032201612836000, -0.29028467725446211000,
|
||||
-0.38268343236508967000, -0.47139673682599764000,
|
||||
-0.55557023301960196000, -0.63439328416364527000,
|
||||
-0.70710678118654746000, -0.77301045336273666000,
|
||||
-0.83146961230254524000, -0.88192126434835494000,
|
||||
-0.92387953251128652000, -0.95694033573220882000,
|
||||
-0.98078528040323032000, -0.99518472667219693000,
|
||||
-1.00000000000000000000, -0.99518472667219693000,
|
||||
-0.98078528040323043000, -0.95694033573220894000,
|
||||
-0.92387953251128663000, -0.88192126434835505000,
|
||||
-0.83146961230254546000, -0.77301045336273688000,
|
||||
-0.70710678118654768000, -0.63439328416364593000,
|
||||
-0.55557023301960218000, -0.47139673682599792000,
|
||||
-0.38268343236509039000, -0.29028467725446250000,
|
||||
-0.19509032201612872000, -0.09801714032956050600,
|
||||
};
|
||||
|
||||
static const double k2 = (2*CV_PI)/N;
|
||||
|
||||
static const double sin_a0 = -0.166630293345647*k2*k2*k2;
|
||||
static const double sin_a2 = k2;
|
||||
|
||||
static const double cos_a0 = -0.499818138450326*k2*k2;
|
||||
/*static const double cos_a2 = 1;*/
|
||||
|
||||
double k1;
|
||||
int i = 0;
|
||||
|
||||
if( !angle_in_degrees )
|
||||
k1 = N/(2*CV_PI);
|
||||
else
|
||||
k1 = N/360.;
|
||||
|
||||
#if CV_AVX2
|
||||
if (USE_AVX2)
|
||||
{
|
||||
__m128d v_k1 = _mm_set1_pd(k1);
|
||||
__m128d v_1 = _mm_set1_pd(1);
|
||||
__m128i v_N1 = _mm_set1_epi32(N - 1);
|
||||
__m128i v_N4 = _mm_set1_epi32(N >> 2);
|
||||
__m128d v_sin_a0 = _mm_set1_pd(sin_a0);
|
||||
__m128d v_sin_a2 = _mm_set1_pd(sin_a2);
|
||||
__m128d v_cos_a0 = _mm_set1_pd(cos_a0);
|
||||
|
||||
for ( ; i <= len - 4; i += 4)
|
||||
{
|
||||
__m128 v_angle = _mm_loadu_ps(angle + i);
|
||||
|
||||
// 0-1
|
||||
__m128d v_t = _mm_mul_pd(_mm_cvtps_pd(v_angle), v_k1);
|
||||
__m128i v_it = _mm_cvtpd_epi32(v_t);
|
||||
v_t = _mm_sub_pd(v_t, _mm_cvtepi32_pd(v_it));
|
||||
|
||||
__m128i v_sin_idx = _mm_and_si128(v_it, v_N1);
|
||||
__m128i v_cos_idx = _mm_and_si128(_mm_sub_epi32(v_N4, v_sin_idx), v_N1);
|
||||
|
||||
__m128d v_t2 = _mm_mul_pd(v_t, v_t);
|
||||
__m128d v_sin_b = _mm_mul_pd(_mm_add_pd(_mm_mul_pd(v_sin_a0, v_t2), v_sin_a2), v_t);
|
||||
__m128d v_cos_b = _mm_add_pd(_mm_mul_pd(v_cos_a0, v_t2), v_1);
|
||||
|
||||
__m128d v_sin_a = _mm_i32gather_pd(sin_table, v_sin_idx, 8);
|
||||
__m128d v_cos_a = _mm_i32gather_pd(sin_table, v_cos_idx, 8);
|
||||
|
||||
__m128d v_sin_val_0 = _mm_add_pd(_mm_mul_pd(v_sin_a, v_cos_b),
|
||||
_mm_mul_pd(v_cos_a, v_sin_b));
|
||||
__m128d v_cos_val_0 = _mm_sub_pd(_mm_mul_pd(v_cos_a, v_cos_b),
|
||||
_mm_mul_pd(v_sin_a, v_sin_b));
|
||||
|
||||
// 2-3
|
||||
v_t = _mm_mul_pd(_mm_cvtps_pd(_mm_castsi128_ps(_mm_srli_si128(_mm_castps_si128(v_angle), 8))), v_k1);
|
||||
v_it = _mm_cvtpd_epi32(v_t);
|
||||
v_t = _mm_sub_pd(v_t, _mm_cvtepi32_pd(v_it));
|
||||
|
||||
v_sin_idx = _mm_and_si128(v_it, v_N1);
|
||||
v_cos_idx = _mm_and_si128(_mm_sub_epi32(v_N4, v_sin_idx), v_N1);
|
||||
|
||||
v_t2 = _mm_mul_pd(v_t, v_t);
|
||||
v_sin_b = _mm_mul_pd(_mm_add_pd(_mm_mul_pd(v_sin_a0, v_t2), v_sin_a2), v_t);
|
||||
v_cos_b = _mm_add_pd(_mm_mul_pd(v_cos_a0, v_t2), v_1);
|
||||
|
||||
v_sin_a = _mm_i32gather_pd(sin_table, v_sin_idx, 8);
|
||||
v_cos_a = _mm_i32gather_pd(sin_table, v_cos_idx, 8);
|
||||
|
||||
__m128d v_sin_val_1 = _mm_add_pd(_mm_mul_pd(v_sin_a, v_cos_b),
|
||||
_mm_mul_pd(v_cos_a, v_sin_b));
|
||||
__m128d v_cos_val_1 = _mm_sub_pd(_mm_mul_pd(v_cos_a, v_cos_b),
|
||||
_mm_mul_pd(v_sin_a, v_sin_b));
|
||||
|
||||
_mm_storeu_ps(sinval + i, _mm_movelh_ps(_mm_cvtpd_ps(v_sin_val_0),
|
||||
_mm_cvtpd_ps(v_sin_val_1)));
|
||||
_mm_storeu_ps(cosval + i, _mm_movelh_ps(_mm_cvtpd_ps(v_cos_val_0),
|
||||
_mm_cvtpd_ps(v_cos_val_1)));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
for( ; i < len; i++ )
|
||||
{
|
||||
double t = angle[i]*k1;
|
||||
int it = cvRound(t);
|
||||
t -= it;
|
||||
int sin_idx = it & (N - 1);
|
||||
int cos_idx = (N/4 - sin_idx) & (N - 1);
|
||||
|
||||
double sin_b = (sin_a0*t*t + sin_a2)*t;
|
||||
double cos_b = cos_a0*t*t + 1;
|
||||
|
||||
double sin_a = sin_table[sin_idx];
|
||||
double cos_a = sin_table[cos_idx];
|
||||
|
||||
double sin_val = sin_a*cos_b + cos_a*sin_b;
|
||||
double cos_val = cos_a*cos_b - sin_a*sin_b;
|
||||
|
||||
sinval[i] = (float)sin_val;
|
||||
cosval[i] = (float)cos_val;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_OPENCL
|
||||
|
||||
static bool ocl_polarToCart( InputArray _mag, InputArray _angle,
|
||||
@@ -521,65 +378,6 @@ static bool ocl_polarToCart( InputArray _mag, InputArray _angle,
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_IPP
|
||||
static bool ipp_polarToCart(Mat &mag, Mat &angle, Mat &x, Mat &y)
|
||||
{
|
||||
CV_INSTRUMENT_REGION_IPP();
|
||||
|
||||
int depth = angle.depth();
|
||||
if(depth != CV_32F && depth != CV_64F)
|
||||
return false;
|
||||
|
||||
if(angle.dims <= 2)
|
||||
{
|
||||
int len = (int)(angle.cols*angle.channels());
|
||||
|
||||
if(depth == CV_32F)
|
||||
{
|
||||
for (int h = 0; h < angle.rows; h++)
|
||||
{
|
||||
if(CV_INSTRUMENT_FUN_IPP(ippsPolarToCart_32f, (const float*)mag.ptr(h), (const float*)angle.ptr(h), (float*)x.ptr(h), (float*)y.ptr(h), len) < 0)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int h = 0; h < angle.rows; h++)
|
||||
{
|
||||
if(CV_INSTRUMENT_FUN_IPP(ippsPolarToCart_64f, (const double*)mag.ptr(h), (const double*)angle.ptr(h), (double*)x.ptr(h), (double*)y.ptr(h), len) < 0)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
const Mat *arrays[] = {&mag, &angle, &x, &y, NULL};
|
||||
uchar *ptrs[4] = {NULL};
|
||||
NAryMatIterator it(arrays, ptrs);
|
||||
int len = (int)(it.size*angle.channels());
|
||||
|
||||
if(depth == CV_32F)
|
||||
{
|
||||
for (size_t i = 0; i < it.nplanes; i++, ++it)
|
||||
{
|
||||
if(CV_INSTRUMENT_FUN_IPP(ippsPolarToCart_32f, (const float*)ptrs[0], (const float*)ptrs[1], (float*)ptrs[2], (float*)ptrs[3], len) < 0)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (size_t i = 0; i < it.nplanes; i++, ++it)
|
||||
{
|
||||
if(CV_INSTRUMENT_FUN_IPP(ippsPolarToCart_64f, (const double*)ptrs[0], (const double*)ptrs[1], (double*)ptrs[2], (double*)ptrs[3], len) < 0)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void polarToCart( InputArray src1, InputArray src2,
|
||||
OutputArray dst1, OutputArray dst2, bool angleInDegrees )
|
||||
{
|
||||
@@ -587,12 +385,6 @@ void polarToCart( InputArray src1, InputArray src2,
|
||||
|
||||
CV_Assert(dst1.getObj() != dst2.getObj());
|
||||
|
||||
const bool isInPlace =
|
||||
(src1.getObj() == dst1.getObj()) ||
|
||||
(src1.getObj() == dst2.getObj()) ||
|
||||
(src2.getObj() == dst1.getObj()) ||
|
||||
(src2.getObj() == dst2.getObj());
|
||||
|
||||
int type = src2.type(), depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
|
||||
CV_Assert((depth == CV_32F || depth == CV_64F) && (src1.empty() || src1.type() == type));
|
||||
|
||||
@@ -605,100 +397,28 @@ void polarToCart( InputArray src1, InputArray src2,
|
||||
dst2.create( Angle.dims, Angle.size, type );
|
||||
Mat X = dst1.getMat(), Y = dst2.getMat();
|
||||
|
||||
CV_IPP_RUN(!angleInDegrees && !isInPlace, ipp_polarToCart(Mag, Angle, X, Y));
|
||||
|
||||
const Mat* arrays[] = {&Mag, &Angle, &X, &Y, 0};
|
||||
uchar* ptrs[4] = {};
|
||||
NAryMatIterator it(arrays, ptrs);
|
||||
cv::AutoBuffer<float> _buf;
|
||||
float* buf[2] = {0, 0};
|
||||
int j, k, total = (int)(it.size*cn), blockSize = std::min(total, ((BLOCK_SIZE+cn-1)/cn)*cn);
|
||||
int j, total = (int)(it.size*cn), blockSize = std::min(total, ((BLOCK_SIZE+cn-1)/cn)*cn);
|
||||
size_t esz1 = Angle.elemSize1();
|
||||
|
||||
if (( depth == CV_64F ) || isInPlace)
|
||||
{
|
||||
_buf.allocate(blockSize*2);
|
||||
buf[0] = _buf.data();
|
||||
buf[1] = buf[0] + blockSize;
|
||||
}
|
||||
|
||||
for( size_t i = 0; i < it.nplanes; i++, ++it )
|
||||
{
|
||||
for( j = 0; j < total; j += blockSize )
|
||||
{
|
||||
int len = std::min(total - j, blockSize);
|
||||
if (( depth == CV_32F ) && !isInPlace)
|
||||
if ( depth == CV_32F )
|
||||
{
|
||||
const float *mag = (const float*)ptrs[0], *angle = (const float*)ptrs[1];
|
||||
float *x = (float*)ptrs[2], *y = (float*)ptrs[3];
|
||||
|
||||
SinCos_32f( angle, y, x, len, angleInDegrees );
|
||||
if( mag )
|
||||
{
|
||||
k = 0;
|
||||
|
||||
#if (CV_SIMD || CV_SIMD_SCALABLE)
|
||||
int cWidth = VTraits<v_float32>::vlanes();
|
||||
for( ; k <= len - cWidth; k += cWidth )
|
||||
{
|
||||
v_float32 v_m = vx_load(mag + k);
|
||||
v_store(x + k, v_mul(vx_load(x + k), v_m));
|
||||
v_store(y + k, v_mul(vx_load(y + k), v_m));
|
||||
}
|
||||
vx_cleanup();
|
||||
#endif
|
||||
|
||||
for( ; k < len; k++ )
|
||||
{
|
||||
float m = mag[k];
|
||||
x[k] *= m; y[k] *= m;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (( depth == CV_32F ) && isInPlace)
|
||||
{
|
||||
const float *mag = (const float*)ptrs[0], *angle = (const float*)ptrs[1];
|
||||
float *x = (float*)ptrs[2], *y = (float*)ptrs[3];
|
||||
|
||||
for( k = 0; k < len; k++ )
|
||||
buf[0][k] = (float)angle[k];
|
||||
|
||||
SinCos_32f( buf[0], buf[1], buf[0], len, angleInDegrees );
|
||||
if( mag )
|
||||
for( k = 0; k < len; k++ )
|
||||
{
|
||||
float m = mag[k];
|
||||
x[k] = buf[0][k]*m; y[k] = buf[1][k]*m;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::memcpy(x, buf[0], sizeof(float) * len);
|
||||
std::memcpy(y, buf[1], sizeof(float) * len);
|
||||
}
|
||||
hal::polarToCart32f( mag, angle, x, y, len, angleInDegrees );
|
||||
}
|
||||
else
|
||||
{
|
||||
const double *mag = (const double*)ptrs[0], *angle = (const double*)ptrs[1];
|
||||
double *x = (double*)ptrs[2], *y = (double*)ptrs[3];
|
||||
|
||||
for( k = 0; k < len; k++ )
|
||||
buf[0][k] = (float)angle[k];
|
||||
|
||||
SinCos_32f( buf[0], buf[1], buf[0], len, angleInDegrees );
|
||||
if( mag )
|
||||
for( k = 0; k < len; k++ )
|
||||
{
|
||||
double m = mag[k];
|
||||
x[k] = buf[0][k]*m; y[k] = buf[1][k]*m;
|
||||
}
|
||||
else
|
||||
{
|
||||
for( k = 0; k < len; k++ )
|
||||
{
|
||||
x[k] = buf[0][k];
|
||||
y[k] = buf[1][k];
|
||||
}
|
||||
}
|
||||
hal::polarToCart64f( mag, angle, x, y, len, angleInDegrees );
|
||||
}
|
||||
|
||||
if( ptrs[0] )
|
||||
|
||||
@@ -29,6 +29,26 @@ void cartToPolar64f(const double* x, const double* y, double* mag, double* angle
|
||||
CV_CPU_DISPATCH_MODES_ALL);
|
||||
}
|
||||
|
||||
void polarToCart32f(const float* mag, const float* angle, float* x, float* y, int len, bool angleInDegrees)
|
||||
{
|
||||
CV_INSTRUMENT_REGION();
|
||||
|
||||
CALL_HAL(polarToCart32f, cv_hal_polarToCart32f, mag, angle, x, y, len, angleInDegrees);
|
||||
|
||||
CV_CPU_DISPATCH(polarToCart32f, (mag, angle, x, y, len, angleInDegrees),
|
||||
CV_CPU_DISPATCH_MODES_ALL);
|
||||
}
|
||||
|
||||
void polarToCart64f(const double* mag, const double* angle, double* x, double* y, int len, bool angleInDegrees)
|
||||
{
|
||||
CV_INSTRUMENT_REGION();
|
||||
|
||||
CALL_HAL(polarToCart64f, cv_hal_polarToCart64f, mag, angle, x, y, len, angleInDegrees);
|
||||
|
||||
CV_CPU_DISPATCH(polarToCart64f, (mag, angle, x, y, len, angleInDegrees),
|
||||
CV_CPU_DISPATCH_MODES_ALL);
|
||||
}
|
||||
|
||||
void fastAtan32f(const float *Y, const float *X, float *angle, int len, bool angleInDegrees )
|
||||
{
|
||||
CV_INSTRUMENT_REGION();
|
||||
|
||||
@@ -11,6 +11,8 @@ CV_CPU_OPTIMIZATION_NAMESPACE_BEGIN
|
||||
// forward declarations
|
||||
void cartToPolar32f(const float *X, const float *Y, float* mag, float *angle, int len, bool angleInDegrees);
|
||||
void cartToPolar64f(const double *X, const double *Y, double* mag, double *angle, int len, bool angleInDegrees);
|
||||
void polarToCart32f(const float *mag, const float *angle, float *X, float *Y, int len, bool angleInDegrees);
|
||||
void polarToCart64f(const double *mag, const double *angle, double *X, double *Y, int len, bool angleInDegrees);
|
||||
void fastAtan32f(const float *Y, const float *X, float *angle, int len, bool angleInDegrees);
|
||||
void fastAtan64f(const double *Y, const double *X, double *angle, int len, bool angleInDegrees);
|
||||
void fastAtan2(const float *Y, const float *X, float *angle, int len, bool angleInDegrees);
|
||||
@@ -73,48 +75,30 @@ static inline float atan_f32(float y, float x)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CV_SIMD
|
||||
#if (CV_SIMD || CV_SIMD_SCALABLE)
|
||||
|
||||
struct v_atan_f32
|
||||
v_float32 v_atan_f32(const v_float32& y, const v_float32& x)
|
||||
{
|
||||
explicit v_atan_f32(const float& scale)
|
||||
{
|
||||
eps = vx_setall_f32((float)DBL_EPSILON);
|
||||
z = vx_setzero_f32();
|
||||
p7 = vx_setall_f32(atan2_p7);
|
||||
p5 = vx_setall_f32(atan2_p5);
|
||||
p3 = vx_setall_f32(atan2_p3);
|
||||
p1 = vx_setall_f32(atan2_p1);
|
||||
val90 = vx_setall_f32(90.f);
|
||||
val180 = vx_setall_f32(180.f);
|
||||
val360 = vx_setall_f32(360.f);
|
||||
s = vx_setall_f32(scale);
|
||||
}
|
||||
v_float32 eps = vx_setall_f32((float)DBL_EPSILON);
|
||||
v_float32 z = vx_setzero_f32();
|
||||
v_float32 p7 = vx_setall_f32(atan2_p7);
|
||||
v_float32 p5 = vx_setall_f32(atan2_p5);
|
||||
v_float32 p3 = vx_setall_f32(atan2_p3);
|
||||
v_float32 p1 = vx_setall_f32(atan2_p1);
|
||||
v_float32 val90 = vx_setall_f32(90.f);
|
||||
v_float32 val180 = vx_setall_f32(180.f);
|
||||
v_float32 val360 = vx_setall_f32(360.f);
|
||||
|
||||
v_float32 compute(const v_float32& y, const v_float32& x)
|
||||
{
|
||||
v_float32 ax = v_abs(x);
|
||||
v_float32 ay = v_abs(y);
|
||||
v_float32 c = v_div(v_min(ax, ay), v_add(v_max(ax, ay), this->eps));
|
||||
v_float32 cc = v_mul(c, c);
|
||||
v_float32 a = v_mul(v_fma(v_fma(v_fma(cc, this->p7, this->p5), cc, this->p3), cc, this->p1), c);
|
||||
a = v_select(v_ge(ax, ay), a, v_sub(this->val90, a));
|
||||
a = v_select(v_lt(x, this->z), v_sub(this->val180, a), a);
|
||||
a = v_select(v_lt(y, this->z), v_sub(this->val360, a), a);
|
||||
return v_mul(a, this->s);
|
||||
}
|
||||
|
||||
v_float32 eps;
|
||||
v_float32 z;
|
||||
v_float32 p7;
|
||||
v_float32 p5;
|
||||
v_float32 p3;
|
||||
v_float32 p1;
|
||||
v_float32 val90;
|
||||
v_float32 val180;
|
||||
v_float32 val360;
|
||||
v_float32 s;
|
||||
};
|
||||
v_float32 ax = v_abs(x);
|
||||
v_float32 ay = v_abs(y);
|
||||
v_float32 c = v_div(v_min(ax, ay), v_add(v_max(ax, ay), eps));
|
||||
v_float32 cc = v_mul(c, c);
|
||||
v_float32 a = v_mul(v_fma(v_fma(v_fma(cc, p7, p5), cc, p3), cc, p1), c);
|
||||
a = v_select(v_ge(ax, ay), a, v_sub(val90, a));
|
||||
a = v_select(v_lt(x, z), v_sub(val180, a), a);
|
||||
a = v_select(v_lt(y, z), v_sub(val360, a), a);
|
||||
return a;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -124,9 +108,9 @@ static void cartToPolar32f_(const float *X, const float *Y, float *mag, float *a
|
||||
{
|
||||
float scale = angleInDegrees ? 1.f : (float)(CV_PI/180);
|
||||
int i = 0;
|
||||
#if CV_SIMD
|
||||
#if (CV_SIMD || CV_SIMD_SCALABLE)
|
||||
const int VECSZ = VTraits<v_float32>::vlanes();
|
||||
v_atan_f32 v(scale);
|
||||
v_float32 s = vx_setall_f32(scale);
|
||||
|
||||
for( ; i < len; i += VECSZ*2 )
|
||||
{
|
||||
@@ -148,8 +132,8 @@ static void cartToPolar32f_(const float *X, const float *Y, float *mag, float *a
|
||||
v_float32 m0 = v_sqrt(v_muladd(x0, x0, v_mul(y0, y0)));
|
||||
v_float32 m1 = v_sqrt(v_muladd(x1, x1, v_mul(y1, y1)));
|
||||
|
||||
v_float32 r0 = v.compute(y0, x0);
|
||||
v_float32 r1 = v.compute(y1, x1);
|
||||
v_float32 r0 = v_mul(v_atan_f32(y0, x0), s);
|
||||
v_float32 r1 = v_mul(v_atan_f32(y1, x1), s);
|
||||
|
||||
v_store(mag + i, m0);
|
||||
v_store(mag + i + VECSZ, m1);
|
||||
@@ -196,13 +180,174 @@ void cartToPolar64f(const double *X, const double *Y, double *mag, double *angle
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
static inline void SinCos_32f(const float* mag, const float* angle, float* cosval, float* sinval, int len, int angle_in_degrees)
|
||||
{
|
||||
const int N = 64;
|
||||
|
||||
static const double sin_table[] =
|
||||
{
|
||||
0.00000000000000000000, 0.09801714032956060400,
|
||||
0.19509032201612825000, 0.29028467725446233000,
|
||||
0.38268343236508978000, 0.47139673682599764000,
|
||||
0.55557023301960218000, 0.63439328416364549000,
|
||||
0.70710678118654746000, 0.77301045336273699000,
|
||||
0.83146961230254524000, 0.88192126434835494000,
|
||||
0.92387953251128674000, 0.95694033573220894000,
|
||||
0.98078528040323043000, 0.99518472667219682000,
|
||||
1.00000000000000000000, 0.99518472667219693000,
|
||||
0.98078528040323043000, 0.95694033573220894000,
|
||||
0.92387953251128674000, 0.88192126434835505000,
|
||||
0.83146961230254546000, 0.77301045336273710000,
|
||||
0.70710678118654757000, 0.63439328416364549000,
|
||||
0.55557023301960218000, 0.47139673682599786000,
|
||||
0.38268343236508989000, 0.29028467725446239000,
|
||||
0.19509032201612861000, 0.09801714032956082600,
|
||||
0.00000000000000012246, -0.09801714032956059000,
|
||||
-0.19509032201612836000, -0.29028467725446211000,
|
||||
-0.38268343236508967000, -0.47139673682599764000,
|
||||
-0.55557023301960196000, -0.63439328416364527000,
|
||||
-0.70710678118654746000, -0.77301045336273666000,
|
||||
-0.83146961230254524000, -0.88192126434835494000,
|
||||
-0.92387953251128652000, -0.95694033573220882000,
|
||||
-0.98078528040323032000, -0.99518472667219693000,
|
||||
-1.00000000000000000000, -0.99518472667219693000,
|
||||
-0.98078528040323043000, -0.95694033573220894000,
|
||||
-0.92387953251128663000, -0.88192126434835505000,
|
||||
-0.83146961230254546000, -0.77301045336273688000,
|
||||
-0.70710678118654768000, -0.63439328416364593000,
|
||||
-0.55557023301960218000, -0.47139673682599792000,
|
||||
-0.38268343236509039000, -0.29028467725446250000,
|
||||
-0.19509032201612872000, -0.09801714032956050600,
|
||||
};
|
||||
|
||||
static const double k2 = (2*CV_PI)/N;
|
||||
|
||||
static const double sin_a0 = -0.166630293345647*k2*k2*k2;
|
||||
static const double sin_a2 = k2;
|
||||
|
||||
static const double cos_a0 = -0.499818138450326*k2*k2;
|
||||
/*static const double cos_a2 = 1;*/
|
||||
|
||||
double k1;
|
||||
int i = 0;
|
||||
|
||||
if( !angle_in_degrees )
|
||||
k1 = N/(2*CV_PI);
|
||||
else
|
||||
k1 = N/360.;
|
||||
|
||||
#if (CV_SIMD || CV_SIMD_SCALABLE)
|
||||
const int VECSZ = VTraits<v_float32>::vlanes();
|
||||
const v_float32 scale = vx_setall_f32(angle_in_degrees ? (float)CV_PI / 180.f : 1.f);
|
||||
|
||||
for( ; i < len; i += VECSZ*2 )
|
||||
{
|
||||
if( i + VECSZ*2 > len )
|
||||
{
|
||||
// if it's inplace operation, we cannot repeatedly process
|
||||
// the tail for the second time, so we have to use the
|
||||
// scalar code
|
||||
if( i == 0 || angle == cosval || angle == sinval || mag == cosval || mag == sinval )
|
||||
break;
|
||||
i = len - VECSZ*2;
|
||||
}
|
||||
|
||||
v_float32 r0 = v_mul(vx_load(angle + i), scale);
|
||||
v_float32 r1 = v_mul(vx_load(angle + i + VECSZ), scale);
|
||||
|
||||
v_float32 c0, c1, s0, s1;
|
||||
v_sincos(r0, s0, c0);
|
||||
v_sincos(r1, s1, c1);
|
||||
|
||||
if( mag )
|
||||
{
|
||||
v_float32 m0 = vx_load(mag + i);
|
||||
v_float32 m1 = vx_load(mag + i + VECSZ);
|
||||
c0 = v_mul(c0, m0);
|
||||
c1 = v_mul(c1, m1);
|
||||
s0 = v_mul(s0, m0);
|
||||
s1 = v_mul(s1, m1);
|
||||
}
|
||||
|
||||
v_store(cosval + i, c0);
|
||||
v_store(cosval + i + VECSZ, c1);
|
||||
|
||||
v_store(sinval + i, s0);
|
||||
v_store(sinval + i + VECSZ, s1);
|
||||
}
|
||||
vx_cleanup();
|
||||
#endif
|
||||
|
||||
for( ; i < len; i++ )
|
||||
{
|
||||
double t = angle[i]*k1;
|
||||
int it = cvRound(t);
|
||||
t -= it;
|
||||
int sin_idx = it & (N - 1);
|
||||
int cos_idx = (N/4 - sin_idx) & (N - 1);
|
||||
|
||||
double sin_b = (sin_a0*t*t + sin_a2)*t;
|
||||
double cos_b = cos_a0*t*t + 1;
|
||||
|
||||
double sin_a = sin_table[sin_idx];
|
||||
double cos_a = sin_table[cos_idx];
|
||||
|
||||
double sin_val = sin_a*cos_b + cos_a*sin_b;
|
||||
double cos_val = cos_a*cos_b - sin_a*sin_b;
|
||||
|
||||
if (mag)
|
||||
{
|
||||
double mag_val = mag[i];
|
||||
sin_val *= mag_val;
|
||||
cos_val *= mag_val;
|
||||
}
|
||||
|
||||
sinval[i] = (float)sin_val;
|
||||
cosval[i] = (float)cos_val;
|
||||
}
|
||||
}
|
||||
|
||||
} // anonymous::
|
||||
|
||||
void polarToCart32f(const float *mag, const float *angle, float *X, float *Y, int len, bool angleInDegrees)
|
||||
{
|
||||
CV_INSTRUMENT_REGION();
|
||||
SinCos_32f(mag, angle, X, Y, len, angleInDegrees);
|
||||
}
|
||||
|
||||
void polarToCart64f(const double *mag, const double *angle, double *X, double *Y, int len, bool angleInDegrees)
|
||||
{
|
||||
CV_INSTRUMENT_REGION();
|
||||
|
||||
const int BLKSZ = 128;
|
||||
float ybuf[BLKSZ], xbuf[BLKSZ], _mbuf[BLKSZ], abuf[BLKSZ];
|
||||
float* mbuf = mag ? _mbuf : nullptr;
|
||||
for( int i = 0; i < len; i += BLKSZ )
|
||||
{
|
||||
int j, blksz = std::min(BLKSZ, len - i);
|
||||
for( j = 0; j < blksz; j++ )
|
||||
{
|
||||
if (mbuf)
|
||||
mbuf[j] = (float)mag[i + j];
|
||||
abuf[j] = (float)angle[i + j];
|
||||
}
|
||||
SinCos_32f(mbuf, abuf, xbuf, ybuf, blksz, angleInDegrees);
|
||||
for( j = 0; j < blksz; j++ )
|
||||
X[i + j] = xbuf[j];
|
||||
for( j = 0; j < blksz; j++ )
|
||||
Y[i + j] = ybuf[j];
|
||||
}
|
||||
}
|
||||
|
||||
static void fastAtan32f_(const float *Y, const float *X, float *angle, int len, bool angleInDegrees )
|
||||
{
|
||||
float scale = angleInDegrees ? 1.f : (float)(CV_PI/180);
|
||||
int i = 0;
|
||||
#if CV_SIMD
|
||||
#if (CV_SIMD || CV_SIMD_SCALABLE)
|
||||
const int VECSZ = VTraits<v_float32>::vlanes();
|
||||
v_atan_f32 v(scale);
|
||||
v_float32 s = vx_setall_f32(scale);
|
||||
|
||||
for( ; i < len; i += VECSZ*2 )
|
||||
{
|
||||
@@ -221,8 +366,8 @@ static void fastAtan32f_(const float *Y, const float *X, float *angle, int len,
|
||||
v_float32 y1 = vx_load(Y + i + VECSZ);
|
||||
v_float32 x1 = vx_load(X + i + VECSZ);
|
||||
|
||||
v_float32 r0 = v.compute(y0, x0);
|
||||
v_float32 r1 = v.compute(y1, x1);
|
||||
v_float32 r0 = v_mul(v_atan_f32(y0, x0), s);
|
||||
v_float32 r1 = v_mul(v_atan_f32(y1, x1), s);
|
||||
|
||||
v_store(angle + i, r0);
|
||||
v_store(angle + i + VECSZ, r1);
|
||||
@@ -273,7 +418,7 @@ void magnitude32f(const float* x, const float* y, float* mag, int len)
|
||||
|
||||
int i = 0;
|
||||
|
||||
#if CV_SIMD
|
||||
#if (CV_SIMD || CV_SIMD_SCALABLE)
|
||||
const int VECSZ = VTraits<v_float32>::vlanes();
|
||||
for( ; i < len; i += VECSZ*2 )
|
||||
{
|
||||
@@ -306,7 +451,7 @@ void magnitude64f(const double* x, const double* y, double* mag, int len)
|
||||
|
||||
int i = 0;
|
||||
|
||||
#if CV_SIMD_64F
|
||||
#if (CV_SIMD_64F || CV_SIMD_SCALABLE_64F)
|
||||
const int VECSZ = VTraits<v_float64>::vlanes();
|
||||
for( ; i < len; i += VECSZ*2 )
|
||||
{
|
||||
|
||||
@@ -3068,7 +3068,7 @@ double dotProd_32s(const int* src1, const int* src2, int len)
|
||||
#if CV_SIMD_WIDTH == 16
|
||||
const int wstep = step * 2;
|
||||
v_float64 v_sum1 = vx_setzero_f64();
|
||||
for (; i < len - wstep; i += wstep, src1 += wstep, src2 += wstep)
|
||||
for (; i <= len - wstep; i += wstep, src1 += wstep, src2 += wstep)
|
||||
{
|
||||
v_int32 v_src10 = vx_load(src1);
|
||||
v_int32 v_src20 = vx_load(src2);
|
||||
@@ -3079,7 +3079,7 @@ double dotProd_32s(const int* src1, const int* src2, int len)
|
||||
}
|
||||
v_sum0 = v_add(v_sum0, v_sum1);
|
||||
#endif
|
||||
for (; i < len - step; i += step, src1 += step, src2 += step)
|
||||
for (; i <= len - step; i += step, src1 += step, src2 += step)
|
||||
{
|
||||
v_int32 v_src1 = vx_load(src1);
|
||||
v_int32 v_src2 = vx_load(src2);
|
||||
|
||||
@@ -1876,6 +1876,16 @@ Mat Mat::reshape(int _cn, std::initializer_list<int> newshape_) const
|
||||
return reshape(_cn, (int)newshape_dims, newshape);
|
||||
}
|
||||
|
||||
Mat Mat::reinterpret(int type) const
|
||||
{
|
||||
type = CV_MAT_TYPE(type);
|
||||
CV_Assert(CV_ELEM_SIZE(this->type()) == CV_ELEM_SIZE(type));
|
||||
Mat m = *this;
|
||||
m.flags = (m.flags & ~CV_MAT_TYPE_MASK) | type;
|
||||
m.updateContinuityFlag();
|
||||
return m;
|
||||
}
|
||||
|
||||
Mat Mat::diag(const Mat& d)
|
||||
{
|
||||
CV_Assert( d.cols == 1 || d.rows == 1 );
|
||||
|
||||
@@ -173,74 +173,6 @@ static bool ocl_transpose( InputArray _src, OutputArray _dst )
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_IPP
|
||||
static bool ipp_transpose( Mat &src, Mat &dst )
|
||||
{
|
||||
CV_INSTRUMENT_REGION_IPP();
|
||||
|
||||
int type = src.type();
|
||||
typedef IppStatus (CV_STDCALL * IppiTranspose)(const void * pSrc, int srcStep, void * pDst, int dstStep, IppiSize roiSize);
|
||||
typedef IppStatus (CV_STDCALL * IppiTransposeI)(const void * pSrcDst, int srcDstStep, IppiSize roiSize);
|
||||
IppiTranspose ippiTranspose = 0;
|
||||
IppiTransposeI ippiTranspose_I = 0;
|
||||
|
||||
if (dst.data == src.data && dst.cols == dst.rows)
|
||||
{
|
||||
CV_SUPPRESS_DEPRECATED_START
|
||||
ippiTranspose_I =
|
||||
type == CV_8UC1 ? (IppiTransposeI)ippiTranspose_8u_C1IR :
|
||||
type == CV_8UC3 ? (IppiTransposeI)ippiTranspose_8u_C3IR :
|
||||
type == CV_8UC4 ? (IppiTransposeI)ippiTranspose_8u_C4IR :
|
||||
type == CV_16UC1 ? (IppiTransposeI)ippiTranspose_16u_C1IR :
|
||||
type == CV_16UC3 ? (IppiTransposeI)ippiTranspose_16u_C3IR :
|
||||
type == CV_16UC4 ? (IppiTransposeI)ippiTranspose_16u_C4IR :
|
||||
type == CV_16SC1 ? (IppiTransposeI)ippiTranspose_16s_C1IR :
|
||||
type == CV_16SC3 ? (IppiTransposeI)ippiTranspose_16s_C3IR :
|
||||
type == CV_16SC4 ? (IppiTransposeI)ippiTranspose_16s_C4IR :
|
||||
type == CV_32SC1 ? (IppiTransposeI)ippiTranspose_32s_C1IR :
|
||||
type == CV_32SC3 ? (IppiTransposeI)ippiTranspose_32s_C3IR :
|
||||
type == CV_32SC4 ? (IppiTransposeI)ippiTranspose_32s_C4IR :
|
||||
type == CV_32FC1 ? (IppiTransposeI)ippiTranspose_32f_C1IR :
|
||||
type == CV_32FC3 ? (IppiTransposeI)ippiTranspose_32f_C3IR :
|
||||
type == CV_32FC4 ? (IppiTransposeI)ippiTranspose_32f_C4IR : 0;
|
||||
CV_SUPPRESS_DEPRECATED_END
|
||||
}
|
||||
else
|
||||
{
|
||||
ippiTranspose =
|
||||
type == CV_8UC1 ? (IppiTranspose)ippiTranspose_8u_C1R :
|
||||
type == CV_8UC3 ? (IppiTranspose)ippiTranspose_8u_C3R :
|
||||
type == CV_8UC4 ? (IppiTranspose)ippiTranspose_8u_C4R :
|
||||
type == CV_16UC1 ? (IppiTranspose)ippiTranspose_16u_C1R :
|
||||
type == CV_16UC3 ? (IppiTranspose)ippiTranspose_16u_C3R :
|
||||
type == CV_16UC4 ? (IppiTranspose)ippiTranspose_16u_C4R :
|
||||
type == CV_16SC1 ? (IppiTranspose)ippiTranspose_16s_C1R :
|
||||
type == CV_16SC3 ? (IppiTranspose)ippiTranspose_16s_C3R :
|
||||
type == CV_16SC4 ? (IppiTranspose)ippiTranspose_16s_C4R :
|
||||
type == CV_32SC1 ? (IppiTranspose)ippiTranspose_32s_C1R :
|
||||
type == CV_32SC3 ? (IppiTranspose)ippiTranspose_32s_C3R :
|
||||
type == CV_32SC4 ? (IppiTranspose)ippiTranspose_32s_C4R :
|
||||
type == CV_32FC1 ? (IppiTranspose)ippiTranspose_32f_C1R :
|
||||
type == CV_32FC3 ? (IppiTranspose)ippiTranspose_32f_C3R :
|
||||
type == CV_32FC4 ? (IppiTranspose)ippiTranspose_32f_C4R : 0;
|
||||
}
|
||||
|
||||
IppiSize roiSize = { src.cols, src.rows };
|
||||
if (ippiTranspose != 0)
|
||||
{
|
||||
if (CV_INSTRUMENT_FUN_IPP(ippiTranspose, src.ptr(), (int)src.step, dst.ptr(), (int)dst.step, roiSize) >= 0)
|
||||
return true;
|
||||
}
|
||||
else if (ippiTranspose_I != 0)
|
||||
{
|
||||
if (CV_INSTRUMENT_FUN_IPP(ippiTranspose_I, dst.ptr(), (int)dst.step, roiSize) >= 0)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void transpose( InputArray _src, OutputArray _dst )
|
||||
{
|
||||
CV_INSTRUMENT_REGION();
|
||||
@@ -271,8 +203,6 @@ void transpose( InputArray _src, OutputArray _dst )
|
||||
|
||||
CALL_HAL(transpose2d, cv_hal_transpose2d, src.data, src.step, dst.data, dst.step, src.cols, src.rows, esz);
|
||||
|
||||
CV_IPP_RUN_FAST(ipp_transpose(src, dst))
|
||||
|
||||
if( dst.data == src.data )
|
||||
{
|
||||
TransposeInplaceFunc func = transposeInplaceTab[esz];
|
||||
@@ -735,48 +665,6 @@ static bool ocl_flip(InputArray _src, OutputArray _dst, int flipCode )
|
||||
|
||||
#endif
|
||||
|
||||
#if defined HAVE_IPP
|
||||
static bool ipp_flip(Mat &src, Mat &dst, int flip_mode)
|
||||
{
|
||||
#ifdef HAVE_IPP_IW
|
||||
CV_INSTRUMENT_REGION_IPP();
|
||||
|
||||
// Details: https://github.com/opencv/opencv/issues/12943
|
||||
if (flip_mode <= 0 /* swap rows */
|
||||
&& cv::ipp::getIppTopFeatures() != ippCPUID_SSE42
|
||||
&& (int64_t)(src.total()) * src.elemSize() >= CV_BIG_INT(0x80000000)/*2Gb*/
|
||||
)
|
||||
return false;
|
||||
|
||||
IppiAxis ippMode;
|
||||
if(flip_mode < 0)
|
||||
ippMode = ippAxsBoth;
|
||||
else if(flip_mode == 0)
|
||||
ippMode = ippAxsHorizontal;
|
||||
else
|
||||
ippMode = ippAxsVertical;
|
||||
|
||||
try
|
||||
{
|
||||
::ipp::IwiImage iwSrc = ippiGetImage(src);
|
||||
::ipp::IwiImage iwDst = ippiGetImage(dst);
|
||||
|
||||
CV_INSTRUMENT_FUN_IPP(::ipp::iwiMirror, iwSrc, iwDst, ippMode);
|
||||
}
|
||||
catch(const ::ipp::IwException &)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
#else
|
||||
CV_UNUSED(src); CV_UNUSED(dst); CV_UNUSED(flip_mode);
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void flip( InputArray _src, OutputArray _dst, int flip_mode )
|
||||
{
|
||||
CV_INSTRUMENT_REGION();
|
||||
@@ -808,8 +696,6 @@ void flip( InputArray _src, OutputArray _dst, int flip_mode )
|
||||
CALL_HAL(flip, cv_hal_flip, type, src.ptr(), src.step, src.cols, src.rows,
|
||||
dst.ptr(), dst.step, flip_mode);
|
||||
|
||||
CV_IPP_RUN_FAST(ipp_flip(src, dst, flip_mode));
|
||||
|
||||
size_t esz = CV_ELEM_SIZE(type);
|
||||
|
||||
if( flip_mode <= 0 )
|
||||
|
||||
@@ -1718,6 +1718,12 @@ void _OutputArray::create(const MatShape& shape, int mtype, int i,
|
||||
}
|
||||
}
|
||||
|
||||
Mat _OutputArray::reinterpret(int mtype) const
|
||||
{
|
||||
mtype = CV_MAT_TYPE(mtype);
|
||||
return getMat().reinterpret(mtype);
|
||||
}
|
||||
|
||||
void _OutputArray::createSameSize(const _InputArray& arr, int mtype) const
|
||||
{
|
||||
int arrsz[CV_MAX_DIM], d = arr.sizend(arrsz);
|
||||
|
||||
@@ -7,120 +7,12 @@
|
||||
#include "opencl_kernels_core.hpp"
|
||||
#include "stat.hpp"
|
||||
|
||||
#ifndef OPENCV_IPP_MEAN
|
||||
#undef HAVE_IPP
|
||||
#undef CV_IPP_RUN_FAST
|
||||
#define CV_IPP_RUN_FAST(f, ...)
|
||||
#undef CV_IPP_RUN
|
||||
#define CV_IPP_RUN(c, f, ...)
|
||||
#endif // OPENCV_IPP_MEAN
|
||||
|
||||
#include "mean.simd.hpp"
|
||||
#include "mean.simd_declarations.hpp" // defines CV_CPU_DISPATCH_MODES_ALL=AVX2,...,BASELINE based on CMakeLists.txt content
|
||||
|
||||
#ifndef OPENCV_IPP_MEAN
|
||||
#undef HAVE_IPP
|
||||
#undef CV_IPP_RUN_FAST
|
||||
#define CV_IPP_RUN_FAST(f, ...)
|
||||
#undef CV_IPP_RUN
|
||||
#define CV_IPP_RUN(c, f, ...)
|
||||
#endif // OPENCV_IPP_MEAN
|
||||
|
||||
namespace cv {
|
||||
|
||||
#if defined HAVE_IPP
|
||||
static bool ipp_mean( Mat &src, Mat &mask, Scalar &ret )
|
||||
{
|
||||
CV_INSTRUMENT_REGION_IPP();
|
||||
|
||||
#if IPP_VERSION_X100 >= 700
|
||||
size_t total_size = src.total();
|
||||
int cn = src.channels();
|
||||
if (cn > 4)
|
||||
return false;
|
||||
int rows = src.size[0], cols = rows ? (int)(total_size/rows) : 0;
|
||||
if( src.dims <= 2 || (src.isContinuous() && mask.isContinuous() && cols > 0 && (size_t)rows*cols == total_size) )
|
||||
{
|
||||
IppiSize sz = { cols, rows };
|
||||
int type = src.type();
|
||||
if( !mask.empty() )
|
||||
{
|
||||
typedef IppStatus (CV_STDCALL* ippiMaskMeanFuncC1)(const void *, int, const void *, int, IppiSize, Ipp64f *);
|
||||
ippiMaskMeanFuncC1 ippiMean_C1MR =
|
||||
type == CV_8UC1 ? (ippiMaskMeanFuncC1)ippiMean_8u_C1MR :
|
||||
type == CV_16UC1 ? (ippiMaskMeanFuncC1)ippiMean_16u_C1MR :
|
||||
type == CV_32FC1 ? (ippiMaskMeanFuncC1)ippiMean_32f_C1MR :
|
||||
0;
|
||||
if( ippiMean_C1MR )
|
||||
{
|
||||
Ipp64f res;
|
||||
if( CV_INSTRUMENT_FUN_IPP(ippiMean_C1MR, src.ptr(), (int)src.step[0], mask.ptr(), (int)mask.step[0], sz, &res) >= 0 )
|
||||
{
|
||||
ret = Scalar(res);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
typedef IppStatus (CV_STDCALL* ippiMaskMeanFuncC3)(const void *, int, const void *, int, IppiSize, int, Ipp64f *);
|
||||
ippiMaskMeanFuncC3 ippiMean_C3MR =
|
||||
type == CV_8UC3 ? (ippiMaskMeanFuncC3)ippiMean_8u_C3CMR :
|
||||
type == CV_16UC3 ? (ippiMaskMeanFuncC3)ippiMean_16u_C3CMR :
|
||||
type == CV_32FC3 ? (ippiMaskMeanFuncC3)ippiMean_32f_C3CMR :
|
||||
0;
|
||||
if( ippiMean_C3MR )
|
||||
{
|
||||
Ipp64f res1, res2, res3;
|
||||
if( CV_INSTRUMENT_FUN_IPP(ippiMean_C3MR, src.ptr(), (int)src.step[0], mask.ptr(), (int)mask.step[0], sz, 1, &res1) >= 0 &&
|
||||
CV_INSTRUMENT_FUN_IPP(ippiMean_C3MR, src.ptr(), (int)src.step[0], mask.ptr(), (int)mask.step[0], sz, 2, &res2) >= 0 &&
|
||||
CV_INSTRUMENT_FUN_IPP(ippiMean_C3MR, src.ptr(), (int)src.step[0], mask.ptr(), (int)mask.step[0], sz, 3, &res3) >= 0 )
|
||||
{
|
||||
ret = Scalar(res1, res2, res3);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
typedef IppStatus (CV_STDCALL* ippiMeanFuncHint)(const void*, int, IppiSize, double *, IppHintAlgorithm);
|
||||
typedef IppStatus (CV_STDCALL* ippiMeanFuncNoHint)(const void*, int, IppiSize, double *);
|
||||
ippiMeanFuncHint ippiMeanHint =
|
||||
type == CV_32FC1 ? (ippiMeanFuncHint)ippiMean_32f_C1R :
|
||||
type == CV_32FC3 ? (ippiMeanFuncHint)ippiMean_32f_C3R :
|
||||
type == CV_32FC4 ? (ippiMeanFuncHint)ippiMean_32f_C4R :
|
||||
0;
|
||||
ippiMeanFuncNoHint ippiMean =
|
||||
type == CV_8UC1 ? (ippiMeanFuncNoHint)ippiMean_8u_C1R :
|
||||
type == CV_8UC3 ? (ippiMeanFuncNoHint)ippiMean_8u_C3R :
|
||||
type == CV_8UC4 ? (ippiMeanFuncNoHint)ippiMean_8u_C4R :
|
||||
type == CV_16UC1 ? (ippiMeanFuncNoHint)ippiMean_16u_C1R :
|
||||
type == CV_16UC3 ? (ippiMeanFuncNoHint)ippiMean_16u_C3R :
|
||||
type == CV_16UC4 ? (ippiMeanFuncNoHint)ippiMean_16u_C4R :
|
||||
type == CV_16SC1 ? (ippiMeanFuncNoHint)ippiMean_16s_C1R :
|
||||
type == CV_16SC3 ? (ippiMeanFuncNoHint)ippiMean_16s_C3R :
|
||||
type == CV_16SC4 ? (ippiMeanFuncNoHint)ippiMean_16s_C4R :
|
||||
0;
|
||||
// Make sure only zero or one version of the function pointer is valid
|
||||
CV_Assert(!ippiMeanHint || !ippiMean);
|
||||
if( ippiMeanHint || ippiMean )
|
||||
{
|
||||
Ipp64f res[4];
|
||||
IppStatus status = ippiMeanHint ? CV_INSTRUMENT_FUN_IPP(ippiMeanHint, src.ptr(), (int)src.step[0], sz, res, ippAlgHintAccurate) :
|
||||
CV_INSTRUMENT_FUN_IPP(ippiMean, src.ptr(), (int)src.step[0], sz, res);
|
||||
if( status >= 0 )
|
||||
{
|
||||
for( int i = 0; i < cn; i++ )
|
||||
ret[i] = res[i];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
Scalar mean(InputArray _src, InputArray _mask)
|
||||
{
|
||||
CV_INSTRUMENT_REGION();
|
||||
@@ -133,8 +25,6 @@ Scalar mean(InputArray _src, InputArray _mask)
|
||||
|
||||
CV_Assert( cn <= 4 );
|
||||
|
||||
CV_IPP_RUN(IPP_VERSION_X100 >= 700, ipp_mean(src, mask, s), s)
|
||||
|
||||
if (src.isContinuous() && mask.isContinuous())
|
||||
{
|
||||
CALL_HAL_RET2(meanStdDev, cv_hal_meanStdDev, s, src.data, 0, (int)src.total(), 1, src.type(),
|
||||
@@ -334,143 +224,6 @@ static bool ocl_meanStdDev( InputArray _src, OutputArray _mean, OutputArray _sdv
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_IPP
|
||||
static bool ipp_meanStdDev(Mat& src, OutputArray _mean, OutputArray _sdv, Mat& mask)
|
||||
{
|
||||
CV_INSTRUMENT_REGION_IPP();
|
||||
|
||||
#if IPP_VERSION_X100 >= 700
|
||||
int cn = src.channels();
|
||||
|
||||
#if IPP_VERSION_X100 < 201801
|
||||
// IPP_DISABLE: C3C functions can read outside of allocated memory
|
||||
if (cn > 1)
|
||||
return false;
|
||||
#endif
|
||||
#if IPP_VERSION_X100 >= 201900 && IPP_VERSION_X100 < 201901
|
||||
// IPP_DISABLE: 32f C3C functions can read outside of allocated memory
|
||||
if (cn > 1 && src.depth() == CV_32F)
|
||||
return false;
|
||||
|
||||
// SSE4.2 buffer overrun
|
||||
#if defined(_WIN32) && !defined(_WIN64)
|
||||
// IPPICV doesn't have AVX2 in 32-bit builds
|
||||
// However cv::ipp::getIppTopFeatures() may return AVX2 value on AVX2 capable H/W
|
||||
// details #12959
|
||||
#else
|
||||
if (cv::ipp::getIppTopFeatures() == ippCPUID_SSE42) // Linux x64 + OPENCV_IPP=SSE42 is affected too
|
||||
#endif
|
||||
{
|
||||
if (src.depth() == CV_32F && src.dims > 1 && src.size[src.dims - 1] == 6)
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
size_t total_size = src.total();
|
||||
int rows = src.size[0], cols = rows ? (int)(total_size/rows) : 0;
|
||||
if( src.dims <= 2 || (src.isContinuous() && mask.isContinuous() && cols > 0 && (size_t)rows*cols == total_size) )
|
||||
{
|
||||
Ipp64f mean_temp[3];
|
||||
Ipp64f stddev_temp[3];
|
||||
Ipp64f *pmean = &mean_temp[0];
|
||||
Ipp64f *pstddev = &stddev_temp[0];
|
||||
Mat mean, stddev;
|
||||
int dcn_mean = -1;
|
||||
if( _mean.needed() )
|
||||
{
|
||||
if( !_mean.fixedSize() )
|
||||
_mean.create(cn, 1, CV_64F, -1, true);
|
||||
mean = _mean.getMat();
|
||||
dcn_mean = (int)mean.total();
|
||||
pmean = mean.ptr<Ipp64f>();
|
||||
}
|
||||
int dcn_stddev = -1;
|
||||
if( _sdv.needed() )
|
||||
{
|
||||
if( !_sdv.fixedSize() )
|
||||
_sdv.create(cn, 1, CV_64F, -1, true);
|
||||
stddev = _sdv.getMat();
|
||||
dcn_stddev = (int)stddev.total();
|
||||
pstddev = stddev.ptr<Ipp64f>();
|
||||
}
|
||||
for( int c = cn; c < dcn_mean; c++ )
|
||||
pmean[c] = 0;
|
||||
for( int c = cn; c < dcn_stddev; c++ )
|
||||
pstddev[c] = 0;
|
||||
IppiSize sz = { cols, rows };
|
||||
int type = src.type();
|
||||
if( !mask.empty() )
|
||||
{
|
||||
typedef IppStatus (CV_STDCALL* ippiMaskMeanStdDevFuncC1)(const void *, int, const void *, int, IppiSize, Ipp64f *, Ipp64f *);
|
||||
ippiMaskMeanStdDevFuncC1 ippiMean_StdDev_C1MR =
|
||||
type == CV_8UC1 ? (ippiMaskMeanStdDevFuncC1)ippiMean_StdDev_8u_C1MR :
|
||||
type == CV_16UC1 ? (ippiMaskMeanStdDevFuncC1)ippiMean_StdDev_16u_C1MR :
|
||||
type == CV_32FC1 ? (ippiMaskMeanStdDevFuncC1)ippiMean_StdDev_32f_C1MR :
|
||||
0;
|
||||
if( ippiMean_StdDev_C1MR )
|
||||
{
|
||||
if( CV_INSTRUMENT_FUN_IPP(ippiMean_StdDev_C1MR, src.ptr(), (int)src.step[0], mask.ptr(), (int)mask.step[0], sz, pmean, pstddev) >= 0 )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
typedef IppStatus (CV_STDCALL* ippiMaskMeanStdDevFuncC3)(const void *, int, const void *, int, IppiSize, int, Ipp64f *, Ipp64f *);
|
||||
ippiMaskMeanStdDevFuncC3 ippiMean_StdDev_C3CMR =
|
||||
type == CV_8UC3 ? (ippiMaskMeanStdDevFuncC3)ippiMean_StdDev_8u_C3CMR :
|
||||
type == CV_16UC3 ? (ippiMaskMeanStdDevFuncC3)ippiMean_StdDev_16u_C3CMR :
|
||||
type == CV_32FC3 ? (ippiMaskMeanStdDevFuncC3)ippiMean_StdDev_32f_C3CMR :
|
||||
0;
|
||||
if( ippiMean_StdDev_C3CMR )
|
||||
{
|
||||
if( CV_INSTRUMENT_FUN_IPP(ippiMean_StdDev_C3CMR, src.ptr(), (int)src.step[0], mask.ptr(), (int)mask.step[0], sz, 1, &pmean[0], &pstddev[0]) >= 0 &&
|
||||
CV_INSTRUMENT_FUN_IPP(ippiMean_StdDev_C3CMR, src.ptr(), (int)src.step[0], mask.ptr(), (int)mask.step[0], sz, 2, &pmean[1], &pstddev[1]) >= 0 &&
|
||||
CV_INSTRUMENT_FUN_IPP(ippiMean_StdDev_C3CMR, src.ptr(), (int)src.step[0], mask.ptr(), (int)mask.step[0], sz, 3, &pmean[2], &pstddev[2]) >= 0 )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
typedef IppStatus (CV_STDCALL* ippiMeanStdDevFuncC1)(const void *, int, IppiSize, Ipp64f *, Ipp64f *);
|
||||
ippiMeanStdDevFuncC1 ippiMean_StdDev_C1R =
|
||||
type == CV_8UC1 ? (ippiMeanStdDevFuncC1)ippiMean_StdDev_8u_C1R :
|
||||
type == CV_16UC1 ? (ippiMeanStdDevFuncC1)ippiMean_StdDev_16u_C1R :
|
||||
#if (IPP_VERSION_X100 >= 810)
|
||||
type == CV_32FC1 ? (ippiMeanStdDevFuncC1)ippiMean_StdDev_32f_C1R ://Aug 2013: bug in IPP 7.1, 8.0
|
||||
#endif
|
||||
0;
|
||||
if( ippiMean_StdDev_C1R )
|
||||
{
|
||||
if( CV_INSTRUMENT_FUN_IPP(ippiMean_StdDev_C1R, src.ptr(), (int)src.step[0], sz, pmean, pstddev) >= 0 )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
typedef IppStatus (CV_STDCALL* ippiMeanStdDevFuncC3)(const void *, int, IppiSize, int, Ipp64f *, Ipp64f *);
|
||||
ippiMeanStdDevFuncC3 ippiMean_StdDev_C3CR =
|
||||
type == CV_8UC3 ? (ippiMeanStdDevFuncC3)ippiMean_StdDev_8u_C3CR :
|
||||
type == CV_16UC3 ? (ippiMeanStdDevFuncC3)ippiMean_StdDev_16u_C3CR :
|
||||
type == CV_32FC3 ? (ippiMeanStdDevFuncC3)ippiMean_StdDev_32f_C3CR :
|
||||
0;
|
||||
if( ippiMean_StdDev_C3CR )
|
||||
{
|
||||
if( CV_INSTRUMENT_FUN_IPP(ippiMean_StdDev_C3CR, src.ptr(), (int)src.step[0], sz, 1, &pmean[0], &pstddev[0]) >= 0 &&
|
||||
CV_INSTRUMENT_FUN_IPP(ippiMean_StdDev_C3CR, src.ptr(), (int)src.step[0], sz, 2, &pmean[1], &pstddev[1]) >= 0 &&
|
||||
CV_INSTRUMENT_FUN_IPP(ippiMean_StdDev_C3CR, src.ptr(), (int)src.step[0], sz, 3, &pmean[2], &pstddev[2]) >= 0 )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
CV_UNUSED(src); CV_UNUSED(_mean); CV_UNUSED(_sdv); CV_UNUSED(mask);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
void meanStdDev(InputArray _src, OutputArray _mean, OutputArray _sdv, InputArray _mask)
|
||||
{
|
||||
CV_INSTRUMENT_REGION();
|
||||
@@ -485,8 +238,6 @@ void meanStdDev(InputArray _src, OutputArray _mean, OutputArray _sdv, InputArray
|
||||
|
||||
CV_Assert(mask.empty() || ((mask.type() == CV_8U || mask.type() == CV_8S || mask.type() == CV_Bool) && src.size == mask.size));
|
||||
|
||||
CV_IPP_RUN(IPP_VERSION_X100 >= 700, ipp_meanStdDev(src, _mean, _sdv, mask));
|
||||
|
||||
int k, cn = src.channels(), depth = src.depth();
|
||||
Mat mean_mat, stddev_mat;
|
||||
|
||||
|
||||
@@ -274,137 +274,6 @@ static bool ocl_norm( InputArray _src, int normType, InputArray _mask, double &
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_IPP
|
||||
static bool ipp_norm(Mat &src, int normType, Mat &mask, double &result)
|
||||
{
|
||||
CV_INSTRUMENT_REGION_IPP();
|
||||
|
||||
#if IPP_VERSION_X100 >= 700
|
||||
size_t total_size = src.total();
|
||||
int rows = src.size[0], cols = rows ? (int)(total_size/rows) : 0;
|
||||
|
||||
if( (src.dims <= 2 || (src.isContinuous() && mask.isContinuous()))
|
||||
&& cols > 0 && (size_t)rows*cols == total_size )
|
||||
{
|
||||
if( !mask.empty() )
|
||||
{
|
||||
IppiSize sz = { cols, rows };
|
||||
int type = src.type();
|
||||
|
||||
typedef IppStatus (CV_STDCALL* ippiMaskNormFuncC1)(const void *, int, const void *, int, IppiSize, Ipp64f *);
|
||||
ippiMaskNormFuncC1 ippiNorm_C1MR =
|
||||
normType == NORM_INF ?
|
||||
(type == CV_8UC1 ? (ippiMaskNormFuncC1)ippiNorm_Inf_8u_C1MR :
|
||||
type == CV_16UC1 ? (ippiMaskNormFuncC1)ippiNorm_Inf_16u_C1MR :
|
||||
type == CV_32FC1 ? (ippiMaskNormFuncC1)ippiNorm_Inf_32f_C1MR :
|
||||
0) :
|
||||
normType == NORM_L1 ?
|
||||
(type == CV_8UC1 ? (ippiMaskNormFuncC1)ippiNorm_L1_8u_C1MR :
|
||||
type == CV_16UC1 ? (ippiMaskNormFuncC1)ippiNorm_L1_16u_C1MR :
|
||||
type == CV_32FC1 ? (ippiMaskNormFuncC1)ippiNorm_L1_32f_C1MR :
|
||||
0) :
|
||||
normType == NORM_L2 || normType == NORM_L2SQR ?
|
||||
(type == CV_8UC1 ? (ippiMaskNormFuncC1)ippiNorm_L2_8u_C1MR :
|
||||
type == CV_16UC1 ? (ippiMaskNormFuncC1)ippiNorm_L2_16u_C1MR :
|
||||
type == CV_32FC1 ? (ippiMaskNormFuncC1)ippiNorm_L2_32f_C1MR :
|
||||
0) : 0;
|
||||
if( ippiNorm_C1MR )
|
||||
{
|
||||
Ipp64f norm;
|
||||
if( CV_INSTRUMENT_FUN_IPP(ippiNorm_C1MR, src.ptr(), (int)src.step[0], mask.ptr(), (int)mask.step[0], sz, &norm) >= 0 )
|
||||
{
|
||||
result = (normType == NORM_L2SQR ? (double)(norm * norm) : (double)norm);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
typedef IppStatus (CV_STDCALL* ippiMaskNormFuncC3)(const void *, int, const void *, int, IppiSize, int, Ipp64f *);
|
||||
ippiMaskNormFuncC3 ippiNorm_C3CMR =
|
||||
normType == NORM_INF ?
|
||||
(type == CV_8UC3 ? (ippiMaskNormFuncC3)ippiNorm_Inf_8u_C3CMR :
|
||||
type == CV_16UC3 ? (ippiMaskNormFuncC3)ippiNorm_Inf_16u_C3CMR :
|
||||
type == CV_32FC3 ? (ippiMaskNormFuncC3)ippiNorm_Inf_32f_C3CMR :
|
||||
0) :
|
||||
normType == NORM_L1 ?
|
||||
(type == CV_8UC3 ? (ippiMaskNormFuncC3)ippiNorm_L1_8u_C3CMR :
|
||||
type == CV_16UC3 ? (ippiMaskNormFuncC3)ippiNorm_L1_16u_C3CMR :
|
||||
type == CV_32FC3 ? (ippiMaskNormFuncC3)ippiNorm_L1_32f_C3CMR :
|
||||
0) :
|
||||
normType == NORM_L2 || normType == NORM_L2SQR ?
|
||||
(type == CV_8UC3 ? (ippiMaskNormFuncC3)ippiNorm_L2_8u_C3CMR :
|
||||
type == CV_16UC3 ? (ippiMaskNormFuncC3)ippiNorm_L2_16u_C3CMR :
|
||||
type == CV_32FC3 ? (ippiMaskNormFuncC3)ippiNorm_L2_32f_C3CMR :
|
||||
0) : 0;
|
||||
if( ippiNorm_C3CMR )
|
||||
{
|
||||
Ipp64f norm1, norm2, norm3;
|
||||
if( CV_INSTRUMENT_FUN_IPP(ippiNorm_C3CMR, src.data, (int)src.step[0], mask.data, (int)mask.step[0], sz, 1, &norm1) >= 0 &&
|
||||
CV_INSTRUMENT_FUN_IPP(ippiNorm_C3CMR, src.data, (int)src.step[0], mask.data, (int)mask.step[0], sz, 2, &norm2) >= 0 &&
|
||||
CV_INSTRUMENT_FUN_IPP(ippiNorm_C3CMR, src.data, (int)src.step[0], mask.data, (int)mask.step[0], sz, 3, &norm3) >= 0)
|
||||
{
|
||||
Ipp64f norm =
|
||||
normType == NORM_INF ? std::max(std::max(norm1, norm2), norm3) :
|
||||
normType == NORM_L1 ? norm1 + norm2 + norm3 :
|
||||
normType == NORM_L2 || normType == NORM_L2SQR ? std::sqrt(norm1 * norm1 + norm2 * norm2 + norm3 * norm3) :
|
||||
0;
|
||||
result = (normType == NORM_L2SQR ? (double)(norm * norm) : (double)norm);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
IppiSize sz = { cols*src.channels(), rows };
|
||||
int type = src.depth();
|
||||
|
||||
typedef IppStatus (CV_STDCALL* ippiNormFuncHint)(const void *, int, IppiSize, Ipp64f *, IppHintAlgorithm hint);
|
||||
typedef IppStatus (CV_STDCALL* ippiNormFuncNoHint)(const void *, int, IppiSize, Ipp64f *);
|
||||
ippiNormFuncHint ippiNormHint =
|
||||
normType == NORM_L1 ?
|
||||
(type == CV_32FC1 ? (ippiNormFuncHint)ippiNorm_L1_32f_C1R :
|
||||
0) :
|
||||
normType == NORM_L2 || normType == NORM_L2SQR ?
|
||||
(type == CV_32FC1 ? (ippiNormFuncHint)ippiNorm_L2_32f_C1R :
|
||||
0) : 0;
|
||||
ippiNormFuncNoHint ippiNorm =
|
||||
normType == NORM_INF ?
|
||||
(type == CV_8UC1 ? (ippiNormFuncNoHint)ippiNorm_Inf_8u_C1R :
|
||||
type == CV_16UC1 ? (ippiNormFuncNoHint)ippiNorm_Inf_16u_C1R :
|
||||
type == CV_16SC1 ? (ippiNormFuncNoHint)ippiNorm_Inf_16s_C1R :
|
||||
type == CV_32FC1 ? (ippiNormFuncNoHint)ippiNorm_Inf_32f_C1R :
|
||||
0) :
|
||||
normType == NORM_L1 ?
|
||||
(type == CV_8UC1 ? (ippiNormFuncNoHint)ippiNorm_L1_8u_C1R :
|
||||
type == CV_16UC1 ? (ippiNormFuncNoHint)ippiNorm_L1_16u_C1R :
|
||||
type == CV_16SC1 ? (ippiNormFuncNoHint)ippiNorm_L1_16s_C1R :
|
||||
0) :
|
||||
normType == NORM_L2 || normType == NORM_L2SQR ?
|
||||
(
|
||||
#if !IPP_DISABLE_NORM_8U
|
||||
type == CV_8UC1 ? (ippiNormFuncNoHint)ippiNorm_L2_8u_C1R :
|
||||
#endif
|
||||
type == CV_16UC1 ? (ippiNormFuncNoHint)ippiNorm_L2_16u_C1R :
|
||||
type == CV_16SC1 ? (ippiNormFuncNoHint)ippiNorm_L2_16s_C1R :
|
||||
0) : 0;
|
||||
if( ippiNormHint || ippiNorm )
|
||||
{
|
||||
Ipp64f norm;
|
||||
IppStatus ret = ippiNormHint ? CV_INSTRUMENT_FUN_IPP(ippiNormHint, src.ptr(), (int)src.step[0], sz, &norm, ippAlgHintAccurate) :
|
||||
CV_INSTRUMENT_FUN_IPP(ippiNorm, src.ptr(), (int)src.step[0], sz, &norm);
|
||||
if( ret >= 0 )
|
||||
{
|
||||
result = (normType == NORM_L2SQR) ? norm * norm : norm;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
CV_UNUSED(src); CV_UNUSED(normType); CV_UNUSED(mask); CV_UNUSED(result);
|
||||
#endif
|
||||
return false;
|
||||
} // ipp_norm()
|
||||
#endif // HAVE_IPP
|
||||
|
||||
static NormFunc getNormFunc(int normType, int depth) {
|
||||
CV_INSTRUMENT_REGION();
|
||||
CV_CPU_DISPATCH(getNormFunc, (normType, depth), CV_CPU_DISPATCH_MODES_ALL);
|
||||
@@ -423,7 +292,7 @@ double norm( InputArray _src, int normType, InputArray _mask )
|
||||
normType == NORM_L2 || normType == NORM_L2SQR ||
|
||||
((normType == NORM_HAMMING || normType == NORM_HAMMING2) && _src.type() == CV_8U) );
|
||||
|
||||
#if defined HAVE_OPENCL || defined HAVE_IPP
|
||||
#if defined HAVE_OPENCL
|
||||
double _result = 0;
|
||||
#endif
|
||||
|
||||
@@ -446,8 +315,6 @@ double norm( InputArray _src, int normType, InputArray _mask )
|
||||
CALL_HAL_RET(norm, cv_hal_norm, result, src.data, 0, mask.data, 0, (int)src.total(), 1, src.type(), normType);
|
||||
}
|
||||
|
||||
CV_IPP_RUN(IPP_VERSION_X100 >= 700, ipp_norm(src, normType, mask, _result), _result);
|
||||
|
||||
NormFunc func = getNormFunc(normType >> 1, depth);
|
||||
CV_Assert( func != 0 );
|
||||
|
||||
@@ -651,244 +518,6 @@ static bool ocl_norm( InputArray _src1, InputArray _src2, int normType, InputArr
|
||||
} // ocl_norm()
|
||||
#endif // HAVE_OPENCL
|
||||
|
||||
#ifdef HAVE_IPP
|
||||
static bool ipp_norm(InputArray _src1, InputArray _src2, int normType, InputArray _mask, double &result)
|
||||
{
|
||||
CV_INSTRUMENT_REGION_IPP();
|
||||
|
||||
#if IPP_VERSION_X100 >= 700
|
||||
Mat src1 = _src1.getMat(), src2 = _src2.getMat(), mask = _mask.getMat();
|
||||
|
||||
if( normType & NORM_RELATIVE )
|
||||
{
|
||||
normType &= NORM_TYPE_MASK;
|
||||
|
||||
size_t total_size = src1.total();
|
||||
int rows = src1.size[0], cols = rows ? (int)(total_size/rows) : 0;
|
||||
if( (src1.dims <= 2 || (src1.isContinuous() && src2.isContinuous() && mask.isContinuous()))
|
||||
&& cols > 0 && (size_t)rows*cols == total_size )
|
||||
{
|
||||
if( !mask.empty() )
|
||||
{
|
||||
IppiSize sz = { cols, rows };
|
||||
int type = src1.type();
|
||||
|
||||
typedef IppStatus (CV_STDCALL* ippiMaskNormDiffFuncC1)(const void *, int, const void *, int, const void *, int, IppiSize, Ipp64f *);
|
||||
ippiMaskNormDiffFuncC1 ippiNormRel_C1MR =
|
||||
normType == NORM_INF ?
|
||||
(type == CV_8UC1 ? (ippiMaskNormDiffFuncC1)ippiNormRel_Inf_8u_C1MR :
|
||||
type == CV_16UC1 ? (ippiMaskNormDiffFuncC1)ippiNormRel_Inf_16u_C1MR :
|
||||
type == CV_32FC1 ? (ippiMaskNormDiffFuncC1)ippiNormRel_Inf_32f_C1MR :
|
||||
0) :
|
||||
normType == NORM_L1 ?
|
||||
(type == CV_8UC1 ? (ippiMaskNormDiffFuncC1)ippiNormRel_L1_8u_C1MR :
|
||||
type == CV_16UC1 ? (ippiMaskNormDiffFuncC1)ippiNormRel_L1_16u_C1MR :
|
||||
type == CV_32FC1 ? (ippiMaskNormDiffFuncC1)ippiNormRel_L1_32f_C1MR :
|
||||
0) :
|
||||
normType == NORM_L2 || normType == NORM_L2SQR ?
|
||||
(type == CV_8UC1 ? (ippiMaskNormDiffFuncC1)ippiNormRel_L2_8u_C1MR :
|
||||
type == CV_16UC1 ? (ippiMaskNormDiffFuncC1)ippiNormRel_L2_16u_C1MR :
|
||||
type == CV_32FC1 ? (ippiMaskNormDiffFuncC1)ippiNormRel_L2_32f_C1MR :
|
||||
0) : 0;
|
||||
if( ippiNormRel_C1MR )
|
||||
{
|
||||
Ipp64f norm;
|
||||
if( CV_INSTRUMENT_FUN_IPP(ippiNormRel_C1MR, src1.ptr(), (int)src1.step[0], src2.ptr(), (int)src2.step[0], mask.ptr(), (int)mask.step[0], sz, &norm) >= 0 )
|
||||
{
|
||||
result = (normType == NORM_L2SQR ? (double)(norm * norm) : (double)norm);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
IppiSize sz = { cols*src1.channels(), rows };
|
||||
int type = src1.depth();
|
||||
|
||||
typedef IppStatus (CV_STDCALL* ippiNormRelFuncHint)(const void *, int, const void *, int, IppiSize, Ipp64f *, IppHintAlgorithm hint);
|
||||
typedef IppStatus (CV_STDCALL* ippiNormRelFuncNoHint)(const void *, int, const void *, int, IppiSize, Ipp64f *);
|
||||
ippiNormRelFuncHint ippiNormRelHint =
|
||||
normType == NORM_L1 ?
|
||||
(type == CV_32F ? (ippiNormRelFuncHint)ippiNormRel_L1_32f_C1R :
|
||||
0) :
|
||||
normType == NORM_L2 || normType == NORM_L2SQR ?
|
||||
(type == CV_32F ? (ippiNormRelFuncHint)ippiNormRel_L2_32f_C1R :
|
||||
0) : 0;
|
||||
ippiNormRelFuncNoHint ippiNormRel =
|
||||
normType == NORM_INF ?
|
||||
(
|
||||
#if !IPP_DISABLE_NORM_8U
|
||||
type == CV_8U ? (ippiNormRelFuncNoHint)ippiNormRel_Inf_8u_C1R :
|
||||
#endif
|
||||
type == CV_16U ? (ippiNormRelFuncNoHint)ippiNormRel_Inf_16u_C1R :
|
||||
type == CV_16S ? (ippiNormRelFuncNoHint)ippiNormRel_Inf_16s_C1R :
|
||||
type == CV_32F ? (ippiNormRelFuncNoHint)ippiNormRel_Inf_32f_C1R :
|
||||
0) :
|
||||
normType == NORM_L1 ?
|
||||
(
|
||||
#if !IPP_DISABLE_NORM_8U
|
||||
type == CV_8U ? (ippiNormRelFuncNoHint)ippiNormRel_L1_8u_C1R :
|
||||
#endif
|
||||
type == CV_16U ? (ippiNormRelFuncNoHint)ippiNormRel_L1_16u_C1R :
|
||||
type == CV_16S ? (ippiNormRelFuncNoHint)ippiNormRel_L1_16s_C1R :
|
||||
0) :
|
||||
normType == NORM_L2 || normType == NORM_L2SQR ?
|
||||
(
|
||||
#if !IPP_DISABLE_NORM_8U
|
||||
type == CV_8U ? (ippiNormRelFuncNoHint)ippiNormRel_L2_8u_C1R :
|
||||
#endif
|
||||
type == CV_16U ? (ippiNormRelFuncNoHint)ippiNormRel_L2_16u_C1R :
|
||||
type == CV_16S ? (ippiNormRelFuncNoHint)ippiNormRel_L2_16s_C1R :
|
||||
0) : 0;
|
||||
if( ippiNormRelHint || ippiNormRel )
|
||||
{
|
||||
Ipp64f norm;
|
||||
IppStatus ret = ippiNormRelHint ? CV_INSTRUMENT_FUN_IPP(ippiNormRelHint, src1.ptr(), (int)src1.step[0], src2.ptr(), (int)src2.step[0], sz, &norm, ippAlgHintAccurate) :
|
||||
CV_INSTRUMENT_FUN_IPP(ippiNormRel, src1.ptr(), (int)src1.step[0], src2.ptr(), (int)src2.step[0], sz, &norm);
|
||||
if( ret >= 0 )
|
||||
{
|
||||
result = (normType == NORM_L2SQR) ? norm * norm : norm;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
normType &= NORM_TYPE_MASK;
|
||||
|
||||
size_t total_size = src1.total();
|
||||
int rows = src1.size[0], cols = rows ? (int)(total_size/rows) : 0;
|
||||
if( (src1.dims <= 2 || (src1.isContinuous() && src2.isContinuous() && mask.isContinuous()))
|
||||
&& cols > 0 && (size_t)rows*cols == total_size )
|
||||
{
|
||||
if( !mask.empty() )
|
||||
{
|
||||
IppiSize sz = { cols, rows };
|
||||
int type = src1.type();
|
||||
|
||||
typedef IppStatus (CV_STDCALL* ippiMaskNormDiffFuncC1)(const void *, int, const void *, int, const void *, int, IppiSize, Ipp64f *);
|
||||
ippiMaskNormDiffFuncC1 ippiNormDiff_C1MR =
|
||||
normType == NORM_INF ?
|
||||
(type == CV_8UC1 ? (ippiMaskNormDiffFuncC1)ippiNormDiff_Inf_8u_C1MR :
|
||||
type == CV_16UC1 ? (ippiMaskNormDiffFuncC1)ippiNormDiff_Inf_16u_C1MR :
|
||||
type == CV_32FC1 ? (ippiMaskNormDiffFuncC1)ippiNormDiff_Inf_32f_C1MR :
|
||||
0) :
|
||||
normType == NORM_L1 ?
|
||||
(type == CV_8UC1 ? (ippiMaskNormDiffFuncC1)ippiNormDiff_L1_8u_C1MR :
|
||||
type == CV_16UC1 ? (ippiMaskNormDiffFuncC1)ippiNormDiff_L1_16u_C1MR :
|
||||
type == CV_32FC1 ? (ippiMaskNormDiffFuncC1)ippiNormDiff_L1_32f_C1MR :
|
||||
0) :
|
||||
normType == NORM_L2 || normType == NORM_L2SQR ?
|
||||
(type == CV_8UC1 ? (ippiMaskNormDiffFuncC1)ippiNormDiff_L2_8u_C1MR :
|
||||
type == CV_16UC1 ? (ippiMaskNormDiffFuncC1)ippiNormDiff_L2_16u_C1MR :
|
||||
type == CV_32FC1 ? (ippiMaskNormDiffFuncC1)ippiNormDiff_L2_32f_C1MR :
|
||||
0) : 0;
|
||||
if( ippiNormDiff_C1MR )
|
||||
{
|
||||
Ipp64f norm;
|
||||
if( CV_INSTRUMENT_FUN_IPP(ippiNormDiff_C1MR, src1.ptr(), (int)src1.step[0], src2.ptr(), (int)src2.step[0], mask.ptr(), (int)mask.step[0], sz, &norm) >= 0 )
|
||||
{
|
||||
result = (normType == NORM_L2SQR ? (double)(norm * norm) : (double)norm);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
typedef IppStatus (CV_STDCALL* ippiMaskNormDiffFuncC3)(const void *, int, const void *, int, const void *, int, IppiSize, int, Ipp64f *);
|
||||
ippiMaskNormDiffFuncC3 ippiNormDiff_C3CMR =
|
||||
normType == NORM_INF ?
|
||||
(type == CV_8UC3 ? (ippiMaskNormDiffFuncC3)ippiNormDiff_Inf_8u_C3CMR :
|
||||
type == CV_16UC3 ? (ippiMaskNormDiffFuncC3)ippiNormDiff_Inf_16u_C3CMR :
|
||||
type == CV_32FC3 ? (ippiMaskNormDiffFuncC3)ippiNormDiff_Inf_32f_C3CMR :
|
||||
0) :
|
||||
normType == NORM_L1 ?
|
||||
(type == CV_8UC3 ? (ippiMaskNormDiffFuncC3)ippiNormDiff_L1_8u_C3CMR :
|
||||
type == CV_16UC3 ? (ippiMaskNormDiffFuncC3)ippiNormDiff_L1_16u_C3CMR :
|
||||
type == CV_32FC3 ? (ippiMaskNormDiffFuncC3)ippiNormDiff_L1_32f_C3CMR :
|
||||
0) :
|
||||
normType == NORM_L2 || normType == NORM_L2SQR ?
|
||||
(type == CV_8UC3 ? (ippiMaskNormDiffFuncC3)ippiNormDiff_L2_8u_C3CMR :
|
||||
type == CV_16UC3 ? (ippiMaskNormDiffFuncC3)ippiNormDiff_L2_16u_C3CMR :
|
||||
type == CV_32FC3 ? (ippiMaskNormDiffFuncC3)ippiNormDiff_L2_32f_C3CMR :
|
||||
0) : 0;
|
||||
if( ippiNormDiff_C3CMR )
|
||||
{
|
||||
Ipp64f norm1, norm2, norm3;
|
||||
if( CV_INSTRUMENT_FUN_IPP(ippiNormDiff_C3CMR, src1.data, (int)src1.step[0], src2.data, (int)src2.step[0], mask.data, (int)mask.step[0], sz, 1, &norm1) >= 0 &&
|
||||
CV_INSTRUMENT_FUN_IPP(ippiNormDiff_C3CMR, src1.data, (int)src1.step[0], src2.data, (int)src2.step[0], mask.data, (int)mask.step[0], sz, 2, &norm2) >= 0 &&
|
||||
CV_INSTRUMENT_FUN_IPP(ippiNormDiff_C3CMR, src1.data, (int)src1.step[0], src2.data, (int)src2.step[0], mask.data, (int)mask.step[0], sz, 3, &norm3) >= 0)
|
||||
{
|
||||
Ipp64f norm =
|
||||
normType == NORM_INF ? std::max(std::max(norm1, norm2), norm3) :
|
||||
normType == NORM_L1 ? norm1 + norm2 + norm3 :
|
||||
normType == NORM_L2 || normType == NORM_L2SQR ? std::sqrt(norm1 * norm1 + norm2 * norm2 + norm3 * norm3) :
|
||||
0;
|
||||
result = (normType == NORM_L2SQR ? (double)(norm * norm) : (double)norm);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
IppiSize sz = { cols*src1.channels(), rows };
|
||||
int type = src1.depth();
|
||||
|
||||
typedef IppStatus (CV_STDCALL* ippiNormDiffFuncHint)(const void *, int, const void *, int, IppiSize, Ipp64f *, IppHintAlgorithm hint);
|
||||
typedef IppStatus (CV_STDCALL* ippiNormDiffFuncNoHint)(const void *, int, const void *, int, IppiSize, Ipp64f *);
|
||||
ippiNormDiffFuncHint ippiNormDiffHint =
|
||||
normType == NORM_L1 ?
|
||||
(type == CV_32F ? (ippiNormDiffFuncHint)ippiNormDiff_L1_32f_C1R :
|
||||
0) :
|
||||
normType == NORM_L2 || normType == NORM_L2SQR ?
|
||||
(type == CV_32F ? (ippiNormDiffFuncHint)ippiNormDiff_L2_32f_C1R :
|
||||
0) : 0;
|
||||
ippiNormDiffFuncNoHint ippiNormDiff =
|
||||
normType == NORM_INF ?
|
||||
(
|
||||
#if !IPP_DISABLE_NORM_8U
|
||||
type == CV_8U ? (ippiNormDiffFuncNoHint)ippiNormDiff_Inf_8u_C1R :
|
||||
#endif
|
||||
type == CV_16U ? (ippiNormDiffFuncNoHint)ippiNormDiff_Inf_16u_C1R :
|
||||
type == CV_16S ? (ippiNormDiffFuncNoHint)ippiNormDiff_Inf_16s_C1R :
|
||||
type == CV_32F ? (ippiNormDiffFuncNoHint)ippiNormDiff_Inf_32f_C1R :
|
||||
0) :
|
||||
normType == NORM_L1 ?
|
||||
(
|
||||
#if !IPP_DISABLE_NORM_8U
|
||||
type == CV_8U ? (ippiNormDiffFuncNoHint)ippiNormDiff_L1_8u_C1R :
|
||||
#endif
|
||||
type == CV_16U ? (ippiNormDiffFuncNoHint)ippiNormDiff_L1_16u_C1R :
|
||||
type == CV_16S ? (ippiNormDiffFuncNoHint)ippiNormDiff_L1_16s_C1R :
|
||||
0) :
|
||||
normType == NORM_L2 || normType == NORM_L2SQR ?
|
||||
(
|
||||
#if !IPP_DISABLE_NORM_8U
|
||||
type == CV_8U ? (ippiNormDiffFuncNoHint)ippiNormDiff_L2_8u_C1R :
|
||||
#endif
|
||||
type == CV_16U ? (ippiNormDiffFuncNoHint)ippiNormDiff_L2_16u_C1R :
|
||||
type == CV_16S ? (ippiNormDiffFuncNoHint)ippiNormDiff_L2_16s_C1R :
|
||||
0) : 0;
|
||||
if( ippiNormDiffHint || ippiNormDiff )
|
||||
{
|
||||
Ipp64f norm;
|
||||
IppStatus ret = ippiNormDiffHint ? CV_INSTRUMENT_FUN_IPP(ippiNormDiffHint, src1.ptr(), (int)src1.step[0], src2.ptr(), (int)src2.step[0], sz, &norm, ippAlgHintAccurate) :
|
||||
CV_INSTRUMENT_FUN_IPP(ippiNormDiff, src1.ptr(), (int)src1.step[0], src2.ptr(), (int)src2.step[0], sz, &norm);
|
||||
if( ret >= 0 )
|
||||
{
|
||||
result = (normType == NORM_L2SQR) ? norm * norm : norm;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
CV_UNUSED(_src1); CV_UNUSED(_src2); CV_UNUSED(normType); CV_UNUSED(_mask); CV_UNUSED(result);
|
||||
#endif
|
||||
return false;
|
||||
} // ipp_norm
|
||||
#endif // HAVE_IPP
|
||||
|
||||
|
||||
double norm( InputArray _src1, InputArray _src2, int normType, InputArray _mask )
|
||||
{
|
||||
CV_INSTRUMENT_REGION();
|
||||
@@ -896,7 +525,7 @@ double norm( InputArray _src1, InputArray _src2, int normType, InputArray _mask
|
||||
CV_CheckTypeEQ(_src1.type(), _src2.type(), "Input type mismatch");
|
||||
CV_Assert(_src1.sameSize(_src2));
|
||||
|
||||
#if defined HAVE_OPENCL || defined HAVE_IPP
|
||||
#if defined HAVE_OPENCL
|
||||
double _result = 0;
|
||||
#endif
|
||||
|
||||
@@ -919,8 +548,6 @@ double norm( InputArray _src1, InputArray _src2, int normType, InputArray _mask
|
||||
CALL_HAL_RET(normDiff, cv_hal_normDiff, result, src1.data, 0, src2.data, 0, mask.data, 0, (int)src1.total(), 1, src1.type(), normType);
|
||||
}
|
||||
|
||||
CV_IPP_RUN(IPP_VERSION_X100 >= 700, ipp_norm(_src1, _src2, normType, _mask, _result), _result);
|
||||
|
||||
if( normType & NORM_RELATIVE )
|
||||
{
|
||||
return norm(_src1, _src2, normType & ~NORM_RELATIVE, _mask)/(norm(_src2, normType, _mask) + DBL_EPSILON);
|
||||
|
||||
Reference in New Issue
Block a user