mirror of
https://github.com/opencv/opencv.git
synced 2026-07-21 19:33:03 +04:00
Merge pull request #27324 from eplankin:warp_hal_4x
* Moved IPP impl of warpAffine to HAL Co-authored-by: victorget <victor.getmanskiy@intel.com>
This commit is contained in:
@@ -5,6 +5,7 @@ set(IPP_HAL_LIBRARIES "ipphal" CACHE INTERNAL "")
|
||||
set(IPP_HAL_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/include" CACHE INTERNAL "")
|
||||
set(IPP_HAL_HEADERS
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/ipp_hal_core.hpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/ipp_hal_imgproc.hpp"
|
||||
CACHE INTERNAL "")
|
||||
|
||||
add_library(ipphal STATIC
|
||||
@@ -13,6 +14,7 @@ add_library(ipphal STATIC
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/norm_ipp.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/cart_polar_ipp.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/transforms_ipp.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/warp_ipp.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/sum_ipp.cpp"
|
||||
)
|
||||
|
||||
@@ -34,6 +36,7 @@ ocv_warnings_disable(CMAKE_CXX_FLAGS -Wno-suggest-override)
|
||||
target_include_directories(ipphal PRIVATE
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src"
|
||||
${CMAKE_SOURCE_DIR}/modules/core/include
|
||||
${CMAKE_SOURCE_DIR}/modules/imgproc/include
|
||||
${IPP_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
// 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
|
||||
|
||||
#ifndef __IPP_HAL_IMGPROC_HPP__
|
||||
#define __IPP_HAL_IMGPROC_HPP__
|
||||
|
||||
#include <opencv2/core/base.hpp>
|
||||
#include "ipp_utils.hpp"
|
||||
|
||||
#ifdef HAVE_IPP_IW
|
||||
|
||||
int ipp_hal_warpAffine(int src_type, const uchar *src_data, size_t src_step, int src_width, int src_height, uchar *dst_data, size_t dst_step, int dst_width,
|
||||
int dst_height, const double M[6], int interpolation, int borderType, const double borderValue[4]);
|
||||
|
||||
#undef cv_hal_warpAffine
|
||||
#define cv_hal_warpAffine ipp_hal_warpAffine
|
||||
#endif
|
||||
|
||||
#if IPP_VERSION_X100 >= 810
|
||||
int ipp_hal_warpPerspective(int src_type, const uchar *src_data, size_t src_step, int src_width, int src_height, uchar *dst_data, size_t dst_step, int dst_width,
|
||||
int dst_height, const double M[9], int interpolation, int borderType, const double borderValue[4]);
|
||||
#undef cv_hal_warpPerspective
|
||||
#define cv_hal_warpPerspective ipp_hal_warpPerspective
|
||||
#endif
|
||||
|
||||
#endif //__IPP_HAL_IMGPROC_HPP__
|
||||
@@ -0,0 +1,71 @@
|
||||
// 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
|
||||
|
||||
#ifndef __PRECOMP_IPP_HPP__
|
||||
#define __PRECOMP_IPP_HPP__
|
||||
|
||||
#include <opencv2/imgproc.hpp>
|
||||
|
||||
#ifdef HAVE_IPP_IW
|
||||
#include "iw++/iw.hpp"
|
||||
#endif
|
||||
|
||||
static inline IppDataType ippiGetDataType(int depth)
|
||||
{
|
||||
depth = CV_MAT_DEPTH(depth);
|
||||
return depth == CV_8U ? ipp8u :
|
||||
depth == CV_8S ? ipp8s :
|
||||
depth == CV_16U ? ipp16u :
|
||||
depth == CV_16S ? ipp16s :
|
||||
depth == CV_32S ? ipp32s :
|
||||
depth == CV_32F ? ipp32f :
|
||||
depth == CV_64F ? ipp64f :
|
||||
(IppDataType)-1;
|
||||
}
|
||||
|
||||
static inline IppiInterpolationType ippiGetInterpolation(int inter)
|
||||
{
|
||||
inter &= cv::InterpolationFlags::INTER_MAX;
|
||||
return inter == cv::InterpolationFlags::INTER_NEAREST ? ippNearest :
|
||||
inter == cv::InterpolationFlags::INTER_LINEAR ? ippLinear :
|
||||
inter == cv::InterpolationFlags::INTER_CUBIC ? ippCubic :
|
||||
inter == cv::InterpolationFlags::INTER_LANCZOS4 ? ippLanczos :
|
||||
inter == cv::InterpolationFlags::INTER_AREA ? ippSuper :
|
||||
(IppiInterpolationType)-1;
|
||||
}
|
||||
|
||||
static inline IppiBorderType ippiGetBorderType(int borderTypeNI)
|
||||
{
|
||||
return borderTypeNI == cv::BorderTypes::BORDER_CONSTANT ? ippBorderConst :
|
||||
borderTypeNI == cv::BorderTypes::BORDER_TRANSPARENT ? ippBorderTransp :
|
||||
borderTypeNI == cv::BorderTypes::BORDER_REPLICATE ? ippBorderRepl :
|
||||
(IppiBorderType)-1;
|
||||
}
|
||||
|
||||
static inline int ippiSuggestThreadsNum(size_t width, size_t height, size_t elemSize, double multiplier)
|
||||
{
|
||||
int threads = cv::getNumThreads();
|
||||
if(threads > 1 && height >= 64)
|
||||
{
|
||||
size_t opMemory = (int)(width*height*elemSize*multiplier);
|
||||
int l2cache = 0;
|
||||
#if IPP_VERSION_X100 >= 201700
|
||||
ippGetL2CacheSize(&l2cache);
|
||||
#endif
|
||||
if(!l2cache)
|
||||
l2cache = 1 << 18;
|
||||
|
||||
return IPP_MAX(1, (IPP_MIN((int)(opMemory/l2cache), threads)));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef HAVE_IPP_IW
|
||||
static inline int ippiSuggestThreadsNum(const ::ipp::IwiImage &image, double multiplier)
|
||||
{
|
||||
return ippiSuggestThreadsNum(image.m_size.width, image.m_size.height, image.m_typeSize*image.m_channels, multiplier);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //__PRECOMP_IPP_HPP__
|
||||
@@ -3,6 +3,7 @@
|
||||
// of this distribution and at http://opencv.org/license.html
|
||||
|
||||
#include "ipp_hal_core.hpp"
|
||||
#include "precomp_ipp.hpp"
|
||||
|
||||
#include <opencv2/core.hpp>
|
||||
#include <opencv2/core/base.hpp>
|
||||
@@ -72,19 +73,6 @@ int ipp_hal_transpose2d(const uchar* src_data, size_t src_step, uchar* dst_data,
|
||||
|
||||
#ifdef HAVE_IPP_IW
|
||||
|
||||
static inline IppDataType ippiGetDataType(int depth)
|
||||
{
|
||||
depth = CV_MAT_DEPTH(depth);
|
||||
return depth == CV_8U ? ipp8u :
|
||||
depth == CV_8S ? ipp8s :
|
||||
depth == CV_16U ? ipp16u :
|
||||
depth == CV_16S ? ipp16s :
|
||||
depth == CV_32S ? ipp32s :
|
||||
depth == CV_32F ? ipp32f :
|
||||
depth == CV_64F ? ipp64f :
|
||||
(IppDataType)-1;
|
||||
}
|
||||
|
||||
static inline ::ipp::IwiImage ippiGetImage(int src_type, const uchar* src_data, size_t src_step, int src_width, int src_height)
|
||||
{
|
||||
::ipp::IwiImage dst;
|
||||
|
||||
@@ -0,0 +1,367 @@
|
||||
// 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 "ipp_hal_imgproc.hpp"
|
||||
|
||||
#include <opencv2/core.hpp>
|
||||
#include <opencv2/core/base.hpp>
|
||||
#include "precomp_ipp.hpp"
|
||||
|
||||
#ifdef HAVE_IPP_IW
|
||||
#include "iw++/iw.hpp"
|
||||
#endif
|
||||
|
||||
#define IPP_WARPAFFINE_PARALLEL 1
|
||||
#define CV_TYPE(src_type) (src_type & (CV_DEPTH_MAX - 1))
|
||||
#ifdef HAVE_IPP_IW
|
||||
|
||||
class ipp_warpAffineParallel: public cv::ParallelLoopBody
|
||||
{
|
||||
public:
|
||||
ipp_warpAffineParallel(::ipp::IwiImage &src, ::ipp::IwiImage &dst, IppiInterpolationType _inter, double (&_coeffs)[2][3], ::ipp::IwiBorderType _borderType, IwTransDirection _iwTransDirection, bool *_ok):m_src(src), m_dst(dst)
|
||||
{
|
||||
pOk = _ok;
|
||||
|
||||
inter = _inter;
|
||||
borderType = _borderType;
|
||||
iwTransDirection = _iwTransDirection;
|
||||
|
||||
for( int i = 0; i < 2; i++ )
|
||||
for( int j = 0; j < 3; j++ )
|
||||
coeffs[i][j] = _coeffs[i][j];
|
||||
|
||||
*pOk = true;
|
||||
}
|
||||
~ipp_warpAffineParallel() {}
|
||||
|
||||
virtual void operator() (const cv::Range& range) const CV_OVERRIDE
|
||||
{
|
||||
//CV_INSTRUMENT_REGION_IPP();
|
||||
|
||||
if(*pOk == false)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
::ipp::IwiTile tile = ::ipp::IwiRoi(0, range.start, m_dst.m_size.width, range.end - range.start);
|
||||
CV_INSTRUMENT_FUN_IPP(::ipp::iwiWarpAffine, m_src, m_dst, coeffs, iwTransDirection, inter, ::ipp::IwiWarpAffineParams(), borderType, tile);
|
||||
}
|
||||
catch(const ::ipp::IwException &)
|
||||
{
|
||||
*pOk = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
private:
|
||||
::ipp::IwiImage &m_src;
|
||||
::ipp::IwiImage &m_dst;
|
||||
|
||||
IppiInterpolationType inter;
|
||||
double coeffs[2][3];
|
||||
::ipp::IwiBorderType borderType;
|
||||
IwTransDirection iwTransDirection;
|
||||
|
||||
bool *pOk;
|
||||
const ipp_warpAffineParallel& operator= (const ipp_warpAffineParallel&);
|
||||
};
|
||||
|
||||
#if (IPP_VERSION_X100 >= 700)
|
||||
int ipp_hal_warpAffine(int src_type, const uchar *src_data, size_t src_step, int src_width, int src_height, uchar *dst_data, size_t dst_step, int dst_width,
|
||||
int dst_height, const double M[6], int interpolation, int borderType, const double borderValue[4])
|
||||
{
|
||||
//CV_INSTRUMENT_REGION_IPP();
|
||||
|
||||
IppiInterpolationType ippInter = ippiGetInterpolation(interpolation);
|
||||
if((int)ippInter < 0 || interpolation > 2)
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
/* C1 C2 C3 C4 */
|
||||
char impl[CV_DEPTH_MAX][4][3]={{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, //8U
|
||||
{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, //8S
|
||||
{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {1, 0, 0}}, //16U
|
||||
{{1, 0, 0}, {0, 0, 0}, {1, 0, 0}, {1, 0, 0}}, //16S
|
||||
{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, //32S
|
||||
{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, //32F
|
||||
{{1, 0, 0}, {0, 0, 0}, {1, 0, 0}, {1, 0, 0}}}; //64F
|
||||
|
||||
if(impl[CV_TYPE(src_type)][CV_MAT_CN(src_type)-1][interpolation] == 0)
|
||||
{
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
// Acquire data and begin processing
|
||||
try
|
||||
{
|
||||
::ipp::IwiImage iwSrc;
|
||||
iwSrc.Init({src_width, src_height}, ippiGetDataType(src_type), CV_MAT_CN(src_type), NULL, src_data, IwSize(src_step));
|
||||
::ipp::IwiImage iwDst({dst_width, dst_height}, ippiGetDataType(src_type), CV_MAT_CN(src_type), NULL, dst_data, dst_step);
|
||||
::ipp::IwiBorderType ippBorder(ippiGetBorderType(borderType), {borderValue[0], borderValue[1], borderValue[2], borderValue[3]});
|
||||
IwTransDirection iwTransDirection = iwTransForward;
|
||||
|
||||
if((int)ippBorder == -1)
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
double coeffs[2][3];
|
||||
for( int i = 0; i < 2; i++ )
|
||||
for( int j = 0; j < 3; j++ )
|
||||
coeffs[i][j] = M[i*3 + j];
|
||||
|
||||
const int threads = ippiSuggestThreadsNum(iwDst, 2);
|
||||
|
||||
if(IPP_WARPAFFINE_PARALLEL && threads > 1)
|
||||
{
|
||||
bool ok = true;
|
||||
cv::Range range(0, (int)iwDst.m_size.height);
|
||||
ipp_warpAffineParallel invoker(iwSrc, iwDst, ippInter, coeffs, ippBorder, iwTransDirection, &ok);
|
||||
if(!ok)
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
parallel_for_(range, invoker, threads*4);
|
||||
|
||||
if(!ok)
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
} else {
|
||||
CV_INSTRUMENT_FUN_IPP(::ipp::iwiWarpAffine, iwSrc, iwDst, coeffs, iwTransDirection, ippInter, ::ipp::IwiWarpAffineParams(), ippBorder);
|
||||
}
|
||||
}
|
||||
catch (const ::ipp::IwException &)
|
||||
{
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
typedef IppStatus (CV_STDCALL* ippiSetFunc)(const void*, void *, int, IppiSize);
|
||||
|
||||
template <int channels, typename Type>
|
||||
bool IPPSetSimple(cv::Scalar value, void *dataPointer, int step, IppiSize &size, ippiSetFunc func)
|
||||
{
|
||||
//CV_INSTRUMENT_REGION_IPP();
|
||||
|
||||
Type values[channels];
|
||||
for( int i = 0; i < channels; i++ )
|
||||
values[i] = cv::saturate_cast<Type>(value[i]);
|
||||
return func(values, dataPointer, step, size) >= 0;
|
||||
}
|
||||
|
||||
static bool IPPSet(const cv::Scalar &value, void *dataPointer, int step, IppiSize &size, int channels, int depth)
|
||||
{
|
||||
//CV_INSTRUMENT_REGION_IPP();
|
||||
|
||||
if( channels == 1 )
|
||||
{
|
||||
switch( depth )
|
||||
{
|
||||
case CV_8U:
|
||||
return CV_INSTRUMENT_FUN_IPP(ippiSet_8u_C1R, cv::saturate_cast<Ipp8u>(value[0]), (Ipp8u *)dataPointer, step, size) >= 0;
|
||||
case CV_16U:
|
||||
return CV_INSTRUMENT_FUN_IPP(ippiSet_16u_C1R, cv::saturate_cast<Ipp16u>(value[0]), (Ipp16u *)dataPointer, step, size) >= 0;
|
||||
case CV_32F:
|
||||
return CV_INSTRUMENT_FUN_IPP(ippiSet_32f_C1R, cv::saturate_cast<Ipp32f>(value[0]), (Ipp32f *)dataPointer, step, size) >= 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( channels == 3 )
|
||||
{
|
||||
switch( depth )
|
||||
{
|
||||
case CV_8U:
|
||||
return IPPSetSimple<3, Ipp8u>(value, dataPointer, step, size, (ippiSetFunc)ippiSet_8u_C3R);
|
||||
case CV_16U:
|
||||
return IPPSetSimple<3, Ipp16u>(value, dataPointer, step, size, (ippiSetFunc)ippiSet_16u_C3R);
|
||||
case CV_32F:
|
||||
return IPPSetSimple<3, Ipp32f>(value, dataPointer, step, size, (ippiSetFunc)ippiSet_32f_C3R);
|
||||
}
|
||||
}
|
||||
else if( channels == 4 )
|
||||
{
|
||||
switch( depth )
|
||||
{
|
||||
case CV_8U:
|
||||
return IPPSetSimple<4, Ipp8u>(value, dataPointer, step, size, (ippiSetFunc)ippiSet_8u_C4R);
|
||||
case CV_16U:
|
||||
return IPPSetSimple<4, Ipp16u>(value, dataPointer, step, size, (ippiSetFunc)ippiSet_16u_C4R);
|
||||
case CV_32F:
|
||||
return IPPSetSimple<4, Ipp32f>(value, dataPointer, step, size, (ippiSetFunc)ippiSet_32f_C4R);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#if (IPP_VERSION_X100 >= 810)
|
||||
typedef IppStatus (CV_STDCALL* ippiWarpPerspectiveFunc)(const Ipp8u*, int, Ipp8u*, int,IppiPoint, IppiSize, const IppiWarpSpec*,Ipp8u*);
|
||||
|
||||
class IPPWarpPerspectiveInvoker :
|
||||
public cv::ParallelLoopBody
|
||||
{
|
||||
public:
|
||||
IPPWarpPerspectiveInvoker(int _src_type, cv::Mat &_src, size_t _src_step, cv::Mat &_dst, size_t _dst_step, IppiInterpolationType _interpolation,
|
||||
double (&_coeffs)[3][3], int &_borderType, const double _borderValue[4], ippiWarpPerspectiveFunc _func,
|
||||
bool *_ok) :
|
||||
ParallelLoopBody(), src_type(_src_type), src(_src), src_step(_src_step), dst(_dst), dst_step(_dst_step), inter(_interpolation), coeffs(_coeffs),
|
||||
borderType(_borderType), func(_func), ok(_ok)
|
||||
{
|
||||
memcpy(this->borderValue, _borderValue, sizeof(this->borderValue));
|
||||
*ok = true;
|
||||
}
|
||||
|
||||
virtual void operator() (const cv::Range& range) const CV_OVERRIDE
|
||||
{
|
||||
//CV_INSTRUMENT_REGION_IPP();
|
||||
IppiWarpSpec* pSpec = 0;
|
||||
int specSize = 0, initSize = 0, bufSize = 0; Ipp8u* pBuffer = 0;
|
||||
IppiPoint dstRoiOffset = {0, 0};
|
||||
IppiWarpDirection direction = ippWarpBackward; //fixed for IPP
|
||||
const Ipp32u numChannels = CV_MAT_CN(src_type);
|
||||
|
||||
IppiSize srcsize = {src.cols, src.rows};
|
||||
IppiSize dstsize = {dst.cols, dst.rows};
|
||||
IppiRect srcroi = {0, 0, src.cols, src.rows};
|
||||
|
||||
/* Spec and init buffer sizes */
|
||||
IppStatus status = ippiWarpPerspectiveGetSize(srcsize, srcroi, dstsize, ippiGetDataType(src_type), coeffs, inter, ippWarpBackward, ippiGetBorderType(borderType), &specSize, &initSize);
|
||||
|
||||
pSpec = (IppiWarpSpec*)ippMalloc_L(specSize);
|
||||
|
||||
if (inter == ippLinear)
|
||||
{
|
||||
status = ippiWarpPerspectiveLinearInit(srcsize, srcroi, dstsize, ippiGetDataType(src_type), coeffs, direction, numChannels, ippiGetBorderType(borderType),
|
||||
borderValue, 0, pSpec);
|
||||
} else
|
||||
{
|
||||
status = ippiWarpPerspectiveNearestInit(srcsize, srcroi, dstsize, ippiGetDataType(src_type), coeffs, direction, numChannels, ippiGetBorderType(borderType),
|
||||
borderValue, 0, pSpec);
|
||||
}
|
||||
|
||||
status = ippiWarpGetBufferSize(pSpec, dstsize, &bufSize);
|
||||
pBuffer = (Ipp8u*)ippMalloc_L(bufSize);
|
||||
IppiSize dstRoiSize = dstsize;
|
||||
|
||||
int cnn = src.channels();
|
||||
|
||||
if( borderType == cv::BorderTypes::BORDER_CONSTANT )
|
||||
{
|
||||
IppiSize setSize = {dst.cols, range.end - range.start};
|
||||
void *dataPointer = dst.ptr(range.start);
|
||||
if( !IPPSet( cv::Scalar(borderValue[0], borderValue[1], borderValue[2], borderValue[3]), dataPointer, (int)dst.step[0], setSize, cnn, src.depth() ) )
|
||||
{
|
||||
*ok = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
status = CV_INSTRUMENT_FUN_IPP(func, src.ptr(), (int)src_step, dst.ptr(), (int)dst_step, dstRoiOffset, dstRoiSize, pSpec, pBuffer);
|
||||
if (status != ippStsNoErr)
|
||||
*ok = false;
|
||||
else
|
||||
{
|
||||
CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT);
|
||||
}
|
||||
}
|
||||
private:
|
||||
int src_type;
|
||||
cv::Mat &src;
|
||||
size_t src_step;
|
||||
cv::Mat &dst;
|
||||
size_t dst_step;
|
||||
IppiInterpolationType inter;
|
||||
double (&coeffs)[3][3];
|
||||
int borderType;
|
||||
double borderValue[4];
|
||||
ippiWarpPerspectiveFunc func;
|
||||
bool *ok;
|
||||
|
||||
const IPPWarpPerspectiveInvoker& operator= (const IPPWarpPerspectiveInvoker&);
|
||||
};
|
||||
|
||||
int ipp_hal_warpPerspective(int src_type, const uchar *src_data, size_t src_step, int src_width, int src_height, uchar * dst_data, size_t dst_step,
|
||||
int dst_width, int dst_height, const double M[9], int interpolation, int borderType, const double borderValue[4])
|
||||
{
|
||||
//CV_INSTRUMENT_REGION_IPP();
|
||||
ippiWarpPerspectiveFunc ippFunc = 0;
|
||||
if (interpolation == cv::InterpolationFlags::INTER_NEAREST)
|
||||
{
|
||||
ippFunc = src_type == CV_8UC1 ? (ippiWarpPerspectiveFunc)ippiWarpPerspectiveNearest_8u_C1R :
|
||||
src_type == CV_8UC3 ? (ippiWarpPerspectiveFunc)ippiWarpPerspectiveNearest_8u_C3R :
|
||||
src_type == CV_8UC4 ? (ippiWarpPerspectiveFunc)ippiWarpPerspectiveNearest_8u_C4R :
|
||||
src_type == CV_16UC1 ? (ippiWarpPerspectiveFunc)ippiWarpPerspectiveNearest_16u_C1R :
|
||||
src_type == CV_16UC3 ? (ippiWarpPerspectiveFunc)ippiWarpPerspectiveNearest_16u_C3R :
|
||||
src_type == CV_16UC4 ? (ippiWarpPerspectiveFunc)ippiWarpPerspectiveNearest_16u_C4R :
|
||||
src_type == CV_16SC1 ? (ippiWarpPerspectiveFunc)ippiWarpPerspectiveNearest_16s_C1R :
|
||||
src_type == CV_16SC3 ? (ippiWarpPerspectiveFunc)ippiWarpPerspectiveNearest_16s_C3R :
|
||||
src_type == CV_16SC4 ? (ippiWarpPerspectiveFunc)ippiWarpPerspectiveNearest_16s_C4R :
|
||||
src_type == CV_32FC1 ? (ippiWarpPerspectiveFunc)ippiWarpPerspectiveNearest_32f_C1R :
|
||||
src_type == CV_32FC3 ? (ippiWarpPerspectiveFunc)ippiWarpPerspectiveNearest_32f_C3R :
|
||||
src_type == CV_32FC4 ? (ippiWarpPerspectiveFunc)ippiWarpPerspectiveNearest_32f_C4R : 0;
|
||||
}
|
||||
else if (interpolation == cv::InterpolationFlags::INTER_LINEAR)
|
||||
{
|
||||
ippFunc = src_type == CV_8UC1 ? (ippiWarpPerspectiveFunc)ippiWarpPerspectiveLinear_8u_C1R :
|
||||
src_type == CV_8UC3 ? (ippiWarpPerspectiveFunc)ippiWarpPerspectiveLinear_8u_C3R :
|
||||
src_type == CV_8UC4 ? (ippiWarpPerspectiveFunc)ippiWarpPerspectiveLinear_8u_C4R :
|
||||
src_type == CV_16UC1 ? (ippiWarpPerspectiveFunc)ippiWarpPerspectiveLinear_16u_C1R :
|
||||
src_type == CV_16UC3 ? (ippiWarpPerspectiveFunc)ippiWarpPerspectiveLinear_16u_C3R :
|
||||
src_type == CV_16UC4 ? (ippiWarpPerspectiveFunc)ippiWarpPerspectiveLinear_16u_C4R :
|
||||
src_type == CV_16SC1 ? (ippiWarpPerspectiveFunc)ippiWarpPerspectiveLinear_16s_C1R :
|
||||
src_type == CV_16SC3 ? (ippiWarpPerspectiveFunc)ippiWarpPerspectiveLinear_16s_C3R :
|
||||
src_type == CV_16SC4 ? (ippiWarpPerspectiveFunc)ippiWarpPerspectiveLinear_16s_C4R :
|
||||
src_type == CV_32FC1 ? (ippiWarpPerspectiveFunc)ippiWarpPerspectiveLinear_32f_C1R :
|
||||
src_type == CV_32FC3 ? (ippiWarpPerspectiveFunc)ippiWarpPerspectiveLinear_32f_C3R :
|
||||
src_type == CV_32FC4 ? (ippiWarpPerspectiveFunc)ippiWarpPerspectiveLinear_32f_C4R : 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
if(src_height == 1 || src_width == 1) return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
int mode =
|
||||
interpolation == cv::InterpolationFlags::INTER_NEAREST ? IPPI_INTER_NN :
|
||||
interpolation == cv::InterpolationFlags::INTER_LINEAR ? IPPI_INTER_LINEAR : 0;
|
||||
|
||||
if (mode == 0 || ippFunc == 0)
|
||||
{
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* C1 C2 C3 C4 */
|
||||
char impl[CV_DEPTH_MAX][4][2]={{{0, 0}, {1, 1}, {0, 0}, {0, 0}}, //8U
|
||||
{{1, 1}, {1, 1}, {1, 1}, {1, 1}}, //8S
|
||||
{{0, 0}, {1, 1}, {0, 1}, {0, 1}}, //16U
|
||||
{{1, 1}, {1, 1}, {1, 1}, {1, 1}}, //16S
|
||||
{{1, 1}, {1, 1}, {1, 0}, {1, 1}}, //32S
|
||||
{{1, 0}, {1, 0}, {0, 0}, {1, 0}}, //32F
|
||||
{{1, 1}, {1, 1}, {1, 1}, {1, 1}}}; //64F
|
||||
|
||||
if(impl[CV_TYPE(src_type)][CV_MAT_CN(src_type)-1][interpolation] == 0)
|
||||
{
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
double coeffs[3][3];
|
||||
for( int i = 0; i < 3; i++ )
|
||||
for( int j = 0; j < 3; j++ )
|
||||
coeffs[i][j] = M[i*3 + j];
|
||||
|
||||
bool ok;
|
||||
cv::Range range(0, dst_height);
|
||||
cv::Mat src(cv::Size(src_width, src_height), src_type, const_cast<uchar*>(src_data), src_step);
|
||||
cv::Mat dst(cv::Size(dst_width, dst_height), src_type, dst_data, dst_step);
|
||||
IppiInterpolationType ippInter = ippiGetInterpolation(interpolation);
|
||||
IPPWarpPerspectiveInvoker invoker(src_type, src, src_step, dst, dst_step, ippInter, coeffs, borderType, borderValue, ippFunc, &ok);
|
||||
parallel_for_(range, invoker, dst.total()/(double)(1<<16));
|
||||
|
||||
if( ok )
|
||||
{
|
||||
CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT);
|
||||
}
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -197,8 +197,6 @@ T* allocSingletonNew() { return new(allocSingletonNewBuffer(sizeof(T))) T(); }
|
||||
#define IPP_DISABLE_PYRAMIDS_UP 1 // Different results
|
||||
#define IPP_DISABLE_PYRAMIDS_DOWN 1 // Different results
|
||||
#define IPP_DISABLE_PYRAMIDS_BUILD 1 // Different results
|
||||
#define IPP_DISABLE_WARPAFFINE 1 // Different results
|
||||
#define IPP_DISABLE_WARPPERSPECTIVE 1 // Different results
|
||||
#define IPP_DISABLE_REMAP 1 // Different results
|
||||
#define IPP_DISABLE_YUV_RGB 1 // accuracy difference
|
||||
#define IPP_DISABLE_RGB_YUV 1 // breaks OCL accuracy tests
|
||||
|
||||
@@ -60,7 +60,7 @@ using namespace cv;
|
||||
namespace cv
|
||||
{
|
||||
|
||||
#if defined (HAVE_IPP) && (!IPP_DISABLE_WARPAFFINE || !IPP_DISABLE_WARPPERSPECTIVE || !IPP_DISABLE_REMAP)
|
||||
#if defined (HAVE_IPP) && (!IPP_DISABLE_REMAP)
|
||||
typedef IppStatus (CV_STDCALL* ippiSetFunc)(const void*, void *, int, IppiSize);
|
||||
|
||||
template <int channels, typename Type>
|
||||
@@ -2207,62 +2207,6 @@ private:
|
||||
const double *M;
|
||||
};
|
||||
|
||||
|
||||
#if defined (HAVE_IPP) && IPP_VERSION_X100 >= 810 && !IPP_DISABLE_WARPAFFINE
|
||||
typedef IppStatus (CV_STDCALL* ippiWarpAffineBackFunc)(const void*, IppiSize, int, IppiRect, void *, int, IppiRect, double [2][3], int);
|
||||
|
||||
class IPPWarpAffineInvoker :
|
||||
public ParallelLoopBody
|
||||
{
|
||||
public:
|
||||
IPPWarpAffineInvoker(Mat &_src, Mat &_dst, double (&_coeffs)[2][3], int &_interpolation, int _borderType,
|
||||
const Scalar &_borderValue, ippiWarpAffineBackFunc _func, bool *_ok) :
|
||||
ParallelLoopBody(), src(_src), dst(_dst), mode(_interpolation), coeffs(_coeffs),
|
||||
borderType(_borderType), borderValue(_borderValue), func(_func), ok(_ok)
|
||||
{
|
||||
*ok = true;
|
||||
}
|
||||
|
||||
virtual void operator() (const Range& range) const CV_OVERRIDE
|
||||
{
|
||||
IppiSize srcsize = { src.cols, src.rows };
|
||||
IppiRect srcroi = { 0, 0, src.cols, src.rows };
|
||||
IppiRect dstroi = { 0, range.start, dst.cols, range.end - range.start };
|
||||
int cnn = src.channels();
|
||||
if( borderType == BORDER_CONSTANT )
|
||||
{
|
||||
IppiSize setSize = { dst.cols, range.end - range.start };
|
||||
void *dataPointer = dst.ptr(range.start);
|
||||
if( !IPPSet( borderValue, dataPointer, (int)dst.step[0], setSize, cnn, src.depth() ) )
|
||||
{
|
||||
*ok = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Aug 2013: problem in IPP 7.1, 8.0 : sometimes function return ippStsCoeffErr
|
||||
IppStatus status = CV_INSTRUMENT_FUN_IPP(func,( src.ptr(), srcsize, (int)src.step[0], srcroi, dst.ptr(),
|
||||
(int)dst.step[0], dstroi, coeffs, mode ));
|
||||
if( status < 0)
|
||||
*ok = false;
|
||||
else
|
||||
{
|
||||
CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT);
|
||||
}
|
||||
}
|
||||
private:
|
||||
Mat &src;
|
||||
Mat &dst;
|
||||
int mode;
|
||||
double (&coeffs)[2][3];
|
||||
int borderType;
|
||||
Scalar borderValue;
|
||||
ippiWarpAffineBackFunc func;
|
||||
bool *ok;
|
||||
const IPPWarpAffineInvoker& operator= (const IPPWarpAffineInvoker&);
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPENCL
|
||||
|
||||
enum { OCL_OP_PERSPECTIVE = 1, OCL_OP_AFFINE = 0 };
|
||||
@@ -2452,132 +2396,6 @@ static bool ocl_warpTransform(InputArray _src, OutputArray _dst, InputArray _M0,
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_IPP
|
||||
#define IPP_WARPAFFINE_PARALLEL 1
|
||||
|
||||
#ifdef HAVE_IPP_IW
|
||||
|
||||
class ipp_warpAffineParallel: public ParallelLoopBody
|
||||
{
|
||||
public:
|
||||
ipp_warpAffineParallel(::ipp::IwiImage &src, ::ipp::IwiImage &dst, IppiInterpolationType _inter, double (&_coeffs)[2][3], ::ipp::IwiBorderType _borderType, IwTransDirection _iwTransDirection, bool *_ok):m_src(src), m_dst(dst)
|
||||
{
|
||||
pOk = _ok;
|
||||
|
||||
inter = _inter;
|
||||
borderType = _borderType;
|
||||
iwTransDirection = _iwTransDirection;
|
||||
|
||||
for( int i = 0; i < 2; i++ )
|
||||
for( int j = 0; j < 3; j++ )
|
||||
coeffs[i][j] = _coeffs[i][j];
|
||||
|
||||
*pOk = true;
|
||||
}
|
||||
~ipp_warpAffineParallel() {}
|
||||
|
||||
virtual void operator() (const Range& range) const CV_OVERRIDE
|
||||
{
|
||||
CV_INSTRUMENT_REGION_IPP();
|
||||
|
||||
if(*pOk == false)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
::ipp::IwiTile tile = ::ipp::IwiRoi(0, range.start, m_dst.m_size.width, range.end - range.start);
|
||||
CV_INSTRUMENT_FUN_IPP(::ipp::iwiWarpAffine, m_src, m_dst, coeffs, iwTransDirection, inter, ::ipp::IwiWarpAffineParams(), borderType, tile);
|
||||
}
|
||||
catch(const ::ipp::IwException &)
|
||||
{
|
||||
*pOk = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
private:
|
||||
::ipp::IwiImage &m_src;
|
||||
::ipp::IwiImage &m_dst;
|
||||
|
||||
IppiInterpolationType inter;
|
||||
double coeffs[2][3];
|
||||
::ipp::IwiBorderType borderType;
|
||||
IwTransDirection iwTransDirection;
|
||||
|
||||
bool *pOk;
|
||||
const ipp_warpAffineParallel& operator= (const ipp_warpAffineParallel&);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
static bool ipp_warpAffine( InputArray _src, OutputArray _dst, int interpolation, int borderType, const Scalar & borderValue, InputArray _M, int flags )
|
||||
{
|
||||
#ifdef HAVE_IPP_IW
|
||||
CV_INSTRUMENT_REGION_IPP();
|
||||
|
||||
if (!cv::ipp::useIPP_NotExact())
|
||||
return false;
|
||||
|
||||
IppiInterpolationType ippInter = ippiGetInterpolation(interpolation);
|
||||
if((int)ippInter < 0)
|
||||
return false;
|
||||
|
||||
// Acquire data and begin processing
|
||||
try
|
||||
{
|
||||
Mat src = _src.getMat();
|
||||
Mat dst = _dst.getMat();
|
||||
::ipp::IwiImage iwSrc = ippiGetImage(src);
|
||||
::ipp::IwiImage iwDst = ippiGetImage(dst);
|
||||
::ipp::IwiBorderType ippBorder(ippiGetBorderType(borderType), ippiGetValue(borderValue));
|
||||
IwTransDirection iwTransDirection;
|
||||
if(!ippBorder)
|
||||
return false;
|
||||
|
||||
if( !(flags & WARP_INVERSE_MAP) )
|
||||
iwTransDirection = iwTransForward;
|
||||
else
|
||||
iwTransDirection = iwTransInverse;
|
||||
|
||||
Mat M = _M.getMat();
|
||||
double coeffs[2][3];
|
||||
for( int i = 0; i < 2; i++ )
|
||||
for( int j = 0; j < 3; j++ )
|
||||
coeffs[i][j] = M.at<double>(i, j);
|
||||
|
||||
const int threads = ippiSuggestThreadsNum(iwDst, 2);
|
||||
|
||||
if(IPP_WARPAFFINE_PARALLEL && threads > 1)
|
||||
{
|
||||
bool ok = true;
|
||||
Range range(0, (int)iwDst.m_size.height);
|
||||
ipp_warpAffineParallel invoker(iwSrc, iwDst, ippInter, coeffs, ippBorder, iwTransDirection, &ok);
|
||||
if(!ok)
|
||||
return false;
|
||||
|
||||
parallel_for_(range, invoker, threads*4);
|
||||
|
||||
if(!ok)
|
||||
return false;
|
||||
} else {
|
||||
CV_INSTRUMENT_FUN_IPP(::ipp::iwiWarpAffine, iwSrc, iwDst, coeffs, iwTransDirection, ippInter, ::ipp::IwiWarpAffineParams(), ippBorder);
|
||||
}
|
||||
|
||||
}
|
||||
catch (const ::ipp::IwException &)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
#else
|
||||
CV_UNUSED(_src); CV_UNUSED(_dst); CV_UNUSED(interpolation);
|
||||
CV_UNUSED(borderType); CV_UNUSED(borderValue); CV_UNUSED(_M); CV_UNUSED(flags);
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
namespace hal {
|
||||
|
||||
void warpAffine(int src_type,
|
||||
@@ -2729,8 +2547,6 @@ void cv::warpAffine( InputArray _src, OutputArray _dst,
|
||||
CV_Assert( (M0.type() == CV_32F || M0.type() == CV_64F) && M0.rows == 2 && M0.cols == 3 );
|
||||
M0.convertTo(matM, matM.type());
|
||||
|
||||
CV_IPP_RUN_FAST(ipp_warpAffine(src, dst, interpolation, borderType, borderValue, matM, flags));
|
||||
|
||||
if( !(flags & WARP_INVERSE_MAP) )
|
||||
{
|
||||
double D = M[0]*M[4] - M[1]*M[3];
|
||||
@@ -2743,70 +2559,6 @@ void cv::warpAffine( InputArray _src, OutputArray _dst,
|
||||
M[2] = b1; M[5] = b2;
|
||||
}
|
||||
|
||||
#if defined (HAVE_IPP) && IPP_VERSION_X100 >= 810 && !IPP_DISABLE_WARPAFFINE
|
||||
CV_IPP_CHECK()
|
||||
{
|
||||
int type = src.type(), depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
|
||||
if( ( depth == CV_8U || depth == CV_16U || depth == CV_32F ) &&
|
||||
( cn == 1 || cn == 3 || cn == 4 ) &&
|
||||
( interpolation == INTER_NEAREST || interpolation == INTER_LINEAR || interpolation == INTER_CUBIC) &&
|
||||
( borderType == cv::BORDER_TRANSPARENT || borderType == cv::BORDER_CONSTANT) )
|
||||
{
|
||||
ippiWarpAffineBackFunc ippFunc = 0;
|
||||
if ((flags & WARP_INVERSE_MAP) != 0)
|
||||
{
|
||||
ippFunc =
|
||||
type == CV_8UC1 ? (ippiWarpAffineBackFunc)ippiWarpAffineBack_8u_C1R :
|
||||
type == CV_8UC3 ? (ippiWarpAffineBackFunc)ippiWarpAffineBack_8u_C3R :
|
||||
type == CV_8UC4 ? (ippiWarpAffineBackFunc)ippiWarpAffineBack_8u_C4R :
|
||||
type == CV_16UC1 ? (ippiWarpAffineBackFunc)ippiWarpAffineBack_16u_C1R :
|
||||
type == CV_16UC3 ? (ippiWarpAffineBackFunc)ippiWarpAffineBack_16u_C3R :
|
||||
type == CV_16UC4 ? (ippiWarpAffineBackFunc)ippiWarpAffineBack_16u_C4R :
|
||||
type == CV_32FC1 ? (ippiWarpAffineBackFunc)ippiWarpAffineBack_32f_C1R :
|
||||
type == CV_32FC3 ? (ippiWarpAffineBackFunc)ippiWarpAffineBack_32f_C3R :
|
||||
type == CV_32FC4 ? (ippiWarpAffineBackFunc)ippiWarpAffineBack_32f_C4R :
|
||||
0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ippFunc =
|
||||
type == CV_8UC1 ? (ippiWarpAffineBackFunc)ippiWarpAffine_8u_C1R :
|
||||
type == CV_8UC3 ? (ippiWarpAffineBackFunc)ippiWarpAffine_8u_C3R :
|
||||
type == CV_8UC4 ? (ippiWarpAffineBackFunc)ippiWarpAffine_8u_C4R :
|
||||
type == CV_16UC1 ? (ippiWarpAffineBackFunc)ippiWarpAffine_16u_C1R :
|
||||
type == CV_16UC3 ? (ippiWarpAffineBackFunc)ippiWarpAffine_16u_C3R :
|
||||
type == CV_16UC4 ? (ippiWarpAffineBackFunc)ippiWarpAffine_16u_C4R :
|
||||
type == CV_32FC1 ? (ippiWarpAffineBackFunc)ippiWarpAffine_32f_C1R :
|
||||
type == CV_32FC3 ? (ippiWarpAffineBackFunc)ippiWarpAffine_32f_C3R :
|
||||
type == CV_32FC4 ? (ippiWarpAffineBackFunc)ippiWarpAffine_32f_C4R :
|
||||
0;
|
||||
}
|
||||
int mode =
|
||||
interpolation == INTER_LINEAR ? IPPI_INTER_LINEAR :
|
||||
interpolation == INTER_NEAREST ? IPPI_INTER_NN :
|
||||
interpolation == INTER_CUBIC ? IPPI_INTER_CUBIC :
|
||||
0;
|
||||
CV_Assert(mode && ippFunc);
|
||||
|
||||
double coeffs[2][3];
|
||||
for( int i = 0; i < 2; i++ )
|
||||
for( int j = 0; j < 3; j++ )
|
||||
coeffs[i][j] = matM.at<double>(i, j);
|
||||
|
||||
bool ok;
|
||||
Range range(0, dst.rows);
|
||||
IPPWarpAffineInvoker invoker(src, dst, coeffs, mode, borderType, borderValue, ippFunc, &ok);
|
||||
parallel_for_(range, invoker, dst.total()/(double)(1<<16));
|
||||
if( ok )
|
||||
{
|
||||
CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT);
|
||||
return;
|
||||
}
|
||||
setIppErrorStatus();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
hal::warpAffine(src.type(), src.data, src.step, src.cols, src.rows, dst.data, dst.step, dst.cols, dst.rows,
|
||||
M, interpolation, borderType, borderValue.val);
|
||||
}
|
||||
@@ -3135,60 +2887,6 @@ private:
|
||||
Scalar borderValue;
|
||||
};
|
||||
|
||||
#if defined (HAVE_IPP) && IPP_VERSION_X100 >= 810 && !IPP_DISABLE_WARPPERSPECTIVE
|
||||
typedef IppStatus (CV_STDCALL* ippiWarpPerspectiveFunc)(const void*, IppiSize, int, IppiRect, void *, int, IppiRect, double [3][3], int);
|
||||
|
||||
class IPPWarpPerspectiveInvoker :
|
||||
public ParallelLoopBody
|
||||
{
|
||||
public:
|
||||
IPPWarpPerspectiveInvoker(Mat &_src, Mat &_dst, double (&_coeffs)[3][3], int &_interpolation,
|
||||
int &_borderType, const Scalar &_borderValue, ippiWarpPerspectiveFunc _func, bool *_ok) :
|
||||
ParallelLoopBody(), src(_src), dst(_dst), mode(_interpolation), coeffs(_coeffs),
|
||||
borderType(_borderType), borderValue(_borderValue), func(_func), ok(_ok)
|
||||
{
|
||||
*ok = true;
|
||||
}
|
||||
|
||||
virtual void operator() (const Range& range) const CV_OVERRIDE
|
||||
{
|
||||
IppiSize srcsize = {src.cols, src.rows};
|
||||
IppiRect srcroi = {0, 0, src.cols, src.rows};
|
||||
IppiRect dstroi = {0, range.start, dst.cols, range.end - range.start};
|
||||
int cnn = src.channels();
|
||||
|
||||
if( borderType == BORDER_CONSTANT )
|
||||
{
|
||||
IppiSize setSize = {dst.cols, range.end - range.start};
|
||||
void *dataPointer = dst.ptr(range.start);
|
||||
if( !IPPSet( borderValue, dataPointer, (int)dst.step[0], setSize, cnn, src.depth() ) )
|
||||
{
|
||||
*ok = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
IppStatus status = CV_INSTRUMENT_FUN_IPP(func,(src.ptr();, srcsize, (int)src.step[0], srcroi, dst.ptr(), (int)dst.step[0], dstroi, coeffs, mode));
|
||||
if (status != ippStsNoErr)
|
||||
*ok = false;
|
||||
else
|
||||
{
|
||||
CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT);
|
||||
}
|
||||
}
|
||||
private:
|
||||
Mat &src;
|
||||
Mat &dst;
|
||||
int mode;
|
||||
double (&coeffs)[3][3];
|
||||
int borderType;
|
||||
const Scalar borderValue;
|
||||
ippiWarpPerspectiveFunc func;
|
||||
bool *ok;
|
||||
|
||||
const IPPWarpPerspectiveInvoker& operator= (const IPPWarpPerspectiveInvoker&);
|
||||
};
|
||||
#endif
|
||||
|
||||
namespace hal {
|
||||
|
||||
@@ -3309,65 +3007,6 @@ void cv::warpPerspective( InputArray _src, OutputArray _dst, InputArray _M0,
|
||||
CV_Assert( (M0.type() == CV_32F || M0.type() == CV_64F) && M0.rows == 3 && M0.cols == 3 );
|
||||
M0.convertTo(matM, matM.type());
|
||||
|
||||
#if defined (HAVE_IPP) && IPP_VERSION_X100 >= 810 && !IPP_DISABLE_WARPPERSPECTIVE
|
||||
CV_IPP_CHECK()
|
||||
{
|
||||
int type = src.type(), depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
|
||||
if( (depth == CV_8U || depth == CV_16U || depth == CV_32F) &&
|
||||
(cn == 1 || cn == 3 || cn == 4) &&
|
||||
( borderType == cv::BORDER_TRANSPARENT || borderType == cv::BORDER_CONSTANT ) &&
|
||||
(interpolation == INTER_NEAREST || interpolation == INTER_LINEAR || interpolation == INTER_CUBIC))
|
||||
{
|
||||
ippiWarpPerspectiveFunc ippFunc = 0;
|
||||
if ((flags & WARP_INVERSE_MAP) != 0)
|
||||
{
|
||||
ippFunc = type == CV_8UC1 ? (ippiWarpPerspectiveFunc)ippiWarpPerspectiveBack_8u_C1R :
|
||||
type == CV_8UC3 ? (ippiWarpPerspectiveFunc)ippiWarpPerspectiveBack_8u_C3R :
|
||||
type == CV_8UC4 ? (ippiWarpPerspectiveFunc)ippiWarpPerspectiveBack_8u_C4R :
|
||||
type == CV_16UC1 ? (ippiWarpPerspectiveFunc)ippiWarpPerspectiveBack_16u_C1R :
|
||||
type == CV_16UC3 ? (ippiWarpPerspectiveFunc)ippiWarpPerspectiveBack_16u_C3R :
|
||||
type == CV_16UC4 ? (ippiWarpPerspectiveFunc)ippiWarpPerspectiveBack_16u_C4R :
|
||||
type == CV_32FC1 ? (ippiWarpPerspectiveFunc)ippiWarpPerspectiveBack_32f_C1R :
|
||||
type == CV_32FC3 ? (ippiWarpPerspectiveFunc)ippiWarpPerspectiveBack_32f_C3R :
|
||||
type == CV_32FC4 ? (ippiWarpPerspectiveFunc)ippiWarpPerspectiveBack_32f_C4R : 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ippFunc = type == CV_8UC1 ? (ippiWarpPerspectiveFunc)ippiWarpPerspective_8u_C1R :
|
||||
type == CV_8UC3 ? (ippiWarpPerspectiveFunc)ippiWarpPerspective_8u_C3R :
|
||||
type == CV_8UC4 ? (ippiWarpPerspectiveFunc)ippiWarpPerspective_8u_C4R :
|
||||
type == CV_16UC1 ? (ippiWarpPerspectiveFunc)ippiWarpPerspective_16u_C1R :
|
||||
type == CV_16UC3 ? (ippiWarpPerspectiveFunc)ippiWarpPerspective_16u_C3R :
|
||||
type == CV_16UC4 ? (ippiWarpPerspectiveFunc)ippiWarpPerspective_16u_C4R :
|
||||
type == CV_32FC1 ? (ippiWarpPerspectiveFunc)ippiWarpPerspective_32f_C1R :
|
||||
type == CV_32FC3 ? (ippiWarpPerspectiveFunc)ippiWarpPerspective_32f_C3R :
|
||||
type == CV_32FC4 ? (ippiWarpPerspectiveFunc)ippiWarpPerspective_32f_C4R : 0;
|
||||
}
|
||||
int mode =
|
||||
interpolation == INTER_NEAREST ? IPPI_INTER_NN :
|
||||
interpolation == INTER_LINEAR ? IPPI_INTER_LINEAR :
|
||||
interpolation == INTER_CUBIC ? IPPI_INTER_CUBIC : 0;
|
||||
CV_Assert(mode && ippFunc);
|
||||
|
||||
double coeffs[3][3];
|
||||
for( int i = 0; i < 3; i++ )
|
||||
for( int j = 0; j < 3; j++ )
|
||||
coeffs[i][j] = matM.at<double>(i, j);
|
||||
|
||||
bool ok;
|
||||
Range range(0, dst.rows);
|
||||
IPPWarpPerspectiveInvoker invoker(src, dst, coeffs, mode, borderType, borderValue, ippFunc, &ok);
|
||||
parallel_for_(range, invoker, dst.total()/(double)(1<<16));
|
||||
if( ok )
|
||||
{
|
||||
CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT);
|
||||
return;
|
||||
}
|
||||
setIppErrorStatus();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if( !(flags & WARP_INVERSE_MAP) )
|
||||
invert(matM, matM);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user