mirror of
https://github.com/opencv/opencv.git
synced 2025-06-12 20:42:53 +08:00
Added OpenVX based processing to remap
This commit is contained in:
parent
53f72f18f5
commit
f8b4d28745
207
3rdparty/openvx/include/ivx.hpp
vendored
207
3rdparty/openvx/include/ivx.hpp
vendored
@ -352,6 +352,15 @@ template <> struct RefTypeTraits <vx_distribution>
|
|||||||
static vx_status release(vxType& ref) { return vxReleaseDistribution(&ref); }
|
static vx_status release(vxType& ref) { return vxReleaseDistribution(&ref); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class Remap;
|
||||||
|
template <> struct RefTypeTraits <vx_remap>
|
||||||
|
{
|
||||||
|
typedef vx_remap vxType;
|
||||||
|
typedef Remap wrapperType;
|
||||||
|
static const vx_enum vxTypeEnum = VX_TYPE_REMAP;
|
||||||
|
static vx_status release(vxType& ref) { return vxReleaseRemap(&ref); }
|
||||||
|
};
|
||||||
|
|
||||||
#ifdef IVX_USE_CXX98
|
#ifdef IVX_USE_CXX98
|
||||||
|
|
||||||
/// Casting to vx_reference with compile-time check
|
/// Casting to vx_reference with compile-time check
|
||||||
@ -909,6 +918,34 @@ public:
|
|||||||
void setImmediateBorder(vx_enum mode, const vx_pixel_value_t& val)
|
void setImmediateBorder(vx_enum mode, const vx_pixel_value_t& val)
|
||||||
{ border_t bm = {mode, val}; setImmediateBorder(bm); }
|
{ border_t bm = {mode, val}; setImmediateBorder(bm); }
|
||||||
|
|
||||||
|
/// vxSetContextAttribute(BORDER) wrapper
|
||||||
|
template <typename T>
|
||||||
|
void setImmediateBorder(vx_enum mode, const T& _val)
|
||||||
|
{
|
||||||
|
vx_pixel_value_t val;
|
||||||
|
switch (TypeToEnum<T>::value)
|
||||||
|
{
|
||||||
|
case VX_TYPE_UINT8:
|
||||||
|
val.U8 = _val;
|
||||||
|
break;
|
||||||
|
case VX_TYPE_INT16:
|
||||||
|
val.S16 = _val;
|
||||||
|
break;
|
||||||
|
case VX_TYPE_UINT16:
|
||||||
|
val.U16 = _val;
|
||||||
|
break;
|
||||||
|
case VX_TYPE_INT32:
|
||||||
|
val.S32 = _val;
|
||||||
|
break;
|
||||||
|
case VX_TYPE_UINT32:
|
||||||
|
val.U32 = _val;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw WrapperError("Unsupported constant border value type");
|
||||||
|
}
|
||||||
|
setImmediateBorder(mode, val);
|
||||||
|
}
|
||||||
|
|
||||||
/// vxSetContextAttribute(BORDER) wrapper
|
/// vxSetContextAttribute(BORDER) wrapper
|
||||||
void setImmediateBorder(vx_enum mode)
|
void setImmediateBorder(vx_enum mode)
|
||||||
{ vx_pixel_value_t val = {}; setImmediateBorder(mode, val); }
|
{ vx_pixel_value_t val = {}; setImmediateBorder(mode, val); }
|
||||||
@ -1264,6 +1301,34 @@ static const vx_enum
|
|||||||
void setBorder(vx_enum mode, const vx_pixel_value_t& val)
|
void setBorder(vx_enum mode, const vx_pixel_value_t& val)
|
||||||
{ vx_border_t bm = {mode, val}; setBorder(bm); }
|
{ vx_border_t bm = {mode, val}; setBorder(bm); }
|
||||||
|
|
||||||
|
/// vxSetNodeAttribute(BORDER) wrapper
|
||||||
|
template <typename T>
|
||||||
|
void setBorder(vx_enum mode, const T& _val)
|
||||||
|
{
|
||||||
|
vx_pixel_value_t val;
|
||||||
|
switch (TypeToEnum<T>::value)
|
||||||
|
{
|
||||||
|
case VX_TYPE_UINT8:
|
||||||
|
val.U8 = _val;
|
||||||
|
break;
|
||||||
|
case VX_TYPE_INT16:
|
||||||
|
val.S16 = _val;
|
||||||
|
break;
|
||||||
|
case VX_TYPE_UINT16:
|
||||||
|
val.U16 = _val;
|
||||||
|
break;
|
||||||
|
case VX_TYPE_INT32:
|
||||||
|
val.S32 = _val;
|
||||||
|
break;
|
||||||
|
case VX_TYPE_UINT32:
|
||||||
|
val.U32 = _val;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw WrapperError("Unsupported constant border value type");
|
||||||
|
}
|
||||||
|
setBorder(mode, val);
|
||||||
|
}
|
||||||
|
|
||||||
/// vxSetNodeAttribute(BORDER) wrapper
|
/// vxSetNodeAttribute(BORDER) wrapper
|
||||||
void setBorder(vx_enum mode)
|
void setBorder(vx_enum mode)
|
||||||
{ vx_pixel_value_t val = {}; setBorder(mode, val); }
|
{ vx_pixel_value_t val = {}; setBorder(mode, val); }
|
||||||
@ -2914,6 +2979,148 @@ public:
|
|||||||
#endif //IVX_USE_OPENCV
|
#endif //IVX_USE_OPENCV
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Remap
|
||||||
|
*/
|
||||||
|
class Remap : public RefWrapper<vx_remap>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IVX_REF_STD_CTORS_AND_ASSIGNMENT(Remap);
|
||||||
|
|
||||||
|
static Remap create(vx_context context, vx_uint32 src_width, vx_uint32 src_height, vx_uint32 dst_width, vx_uint32 dst_height)
|
||||||
|
{
|
||||||
|
return Remap(vxCreateRemap(context, src_width, src_height, dst_width, dst_height));
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef VX_VERSION_1_1
|
||||||
|
static const vx_enum
|
||||||
|
VX_REMAP_SOURCE_WIDTH = VX_REMAP_ATTRIBUTE_SOURCE_WIDTH,
|
||||||
|
VX_REMAP_SOURCE_HEIGHT = VX_REMAP_ATTRIBUTE_SOURCE_HEIGHT,
|
||||||
|
VX_REMAP_DESTINATION_WIDTH = VX_REMAP_ATTRIBUTE_DESTINATION_WIDTH,
|
||||||
|
VX_REMAP_DESTINATION_HEIGHT = VX_REMAP_ATTRIBUTE_DESTINATION_HEIGHT;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void query(vx_enum att, T& value) const
|
||||||
|
{ IVX_CHECK_STATUS(vxQueryRemap(ref, att, &value, sizeof(value))); }
|
||||||
|
|
||||||
|
vx_uint32 srcWidth() const
|
||||||
|
{
|
||||||
|
vx_uint32 v;
|
||||||
|
query(VX_REMAP_SOURCE_WIDTH, v);
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
vx_uint32 srcHeight() const
|
||||||
|
{
|
||||||
|
vx_uint32 v;
|
||||||
|
query(VX_REMAP_SOURCE_HEIGHT, v);
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
vx_uint32 dstWidth() const
|
||||||
|
{
|
||||||
|
vx_uint32 v;
|
||||||
|
query(VX_REMAP_DESTINATION_WIDTH, v);
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
vx_uint32 dstHeight() const
|
||||||
|
{
|
||||||
|
vx_uint32 v;
|
||||||
|
query(VX_REMAP_DESTINATION_HEIGHT, v);
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
vx_uint32 srcCoordType() const
|
||||||
|
{ return VX_TYPE_FLOAT32; }
|
||||||
|
|
||||||
|
vx_uint32 dstCoordType() const
|
||||||
|
{ return VX_TYPE_UINT32; }
|
||||||
|
|
||||||
|
void setMapping(vx_uint32 dst_x, vx_uint32 dst_y, vx_float32 src_x, vx_float32 src_y)
|
||||||
|
{ IVX_CHECK_STATUS(vxSetRemapPoint(ref, dst_x, dst_y, src_x, src_y)); }
|
||||||
|
|
||||||
|
void getMapping(vx_uint32 dst_x, vx_uint32 dst_y, vx_float32 &src_x, vx_float32 &src_y) const
|
||||||
|
{ IVX_CHECK_STATUS(vxGetRemapPoint(ref, dst_x, dst_y, &src_x, &src_y)); }
|
||||||
|
|
||||||
|
#ifdef IVX_USE_OPENCV
|
||||||
|
void setMappings(const cv::Mat& map_x, const cv::Mat& map_y)
|
||||||
|
{
|
||||||
|
if (map_x.type() != enumToCVType(srcCoordType()) || map_y.type() != enumToCVType(srcCoordType()))
|
||||||
|
throw WrapperError(std::string(__func__) + "(): mapping type is wrong");
|
||||||
|
if ((vx_uint32)(map_x.rows) != dstHeight() || (vx_uint32)(map_x.cols) != dstWidth())
|
||||||
|
throw WrapperError(std::string(__func__) + "(): x mapping size is wrong");
|
||||||
|
if ((vx_uint32)(map_y.rows) != dstHeight() || (vx_uint32)(map_y.cols) != dstWidth())
|
||||||
|
throw WrapperError(std::string(__func__) + "(): y mapping size is wrong");
|
||||||
|
|
||||||
|
for (vx_uint32 y = 0; y < dstHeight(); y++)
|
||||||
|
{
|
||||||
|
const vx_float32* map_x_line = map_x.ptr<vx_float32>(y);
|
||||||
|
const vx_float32* map_y_line = map_y.ptr<vx_float32>(y);
|
||||||
|
for (vx_uint32 x = 0; x < dstWidth(); x++)
|
||||||
|
setMapping(x, y, map_x_line[x], map_y_line[x]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setMappings(const cv::Mat& map)
|
||||||
|
{
|
||||||
|
if (map.depth() != CV_MAT_DEPTH(enumToCVType(srcCoordType())) || map.channels() != 2)
|
||||||
|
throw WrapperError(std::string(__func__) + "(): mapping type is wrong");
|
||||||
|
if ((vx_uint32)(map.rows) != dstHeight() || (vx_uint32)(map.cols) != dstWidth())
|
||||||
|
throw WrapperError(std::string(__func__) + "(): x mapping size is wrong");
|
||||||
|
|
||||||
|
for (vx_uint32 y = 0; y < dstHeight(); y++)
|
||||||
|
{
|
||||||
|
const vx_float32* map_line = map.ptr<vx_float32>(y);
|
||||||
|
for (vx_uint32 x = 0; x < 2*dstWidth(); x+=2)
|
||||||
|
setMapping(x, y, map_line[x], map_line[x+1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void getMappings(cv::Mat& map_x, cv::Mat& map_y) const
|
||||||
|
{
|
||||||
|
if (map_x.type() != enumToCVType(srcCoordType()) || map_y.type() != enumToCVType(srcCoordType()))
|
||||||
|
throw WrapperError(std::string(__func__) + "(): mapping type is wrong");
|
||||||
|
if (((vx_uint32)(map_x.rows) != dstHeight() || (vx_uint32)(map_x.cols) != dstWidth()) && !map_x.empty())
|
||||||
|
throw WrapperError(std::string(__func__) + "(): x mapping size is wrong");
|
||||||
|
if (((vx_uint32)(map_y.rows) != dstHeight() || (vx_uint32)(map_y.cols) != dstWidth()) && !map_y.empty())
|
||||||
|
throw WrapperError(std::string(__func__) + "(): y mapping size is wrong");
|
||||||
|
|
||||||
|
if (map_x.empty())
|
||||||
|
map_x = cv::Mat((int)dstHeight(), (int)dstWidth(), enumToCVType(srcCoordType()));
|
||||||
|
if (map_y.empty())
|
||||||
|
map_y = cv::Mat((int)dstHeight(), (int)dstWidth(), enumToCVType(srcCoordType()));
|
||||||
|
|
||||||
|
for (vx_uint32 y = 0; y < dstHeight(); y++)
|
||||||
|
{
|
||||||
|
vx_float32* map_x_line = map_x.ptr<vx_float32>(y);
|
||||||
|
vx_float32* map_y_line = map_y.ptr<vx_float32>(y);
|
||||||
|
for (vx_uint32 x = 0; x < dstWidth(); x++)
|
||||||
|
getMapping(x, y, map_x_line[x], map_y_line[x]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void getMappings(cv::Mat& map) const
|
||||||
|
{
|
||||||
|
if (map.depth() != CV_MAT_DEPTH(enumToCVType(srcCoordType())) || map.channels() != 2)
|
||||||
|
throw WrapperError(std::string(__func__) + "(): mapping type is wrong");
|
||||||
|
if (((vx_uint32)(map.rows) != dstHeight() || (vx_uint32)(map.cols) != dstWidth()) && !map.empty())
|
||||||
|
throw WrapperError(std::string(__func__) + "(): x mapping size is wrong");
|
||||||
|
|
||||||
|
if (map.empty())
|
||||||
|
map = cv::Mat((int)dstHeight(), (int)dstWidth(), CV_MAKETYPE(CV_MAT_DEPTH(enumToCVType(srcCoordType())),2));
|
||||||
|
|
||||||
|
for (vx_uint32 y = 0; y < dstHeight(); y++)
|
||||||
|
{
|
||||||
|
vx_float32* map_line = map.ptr<vx_float32>(y);
|
||||||
|
for (vx_uint32 x = 0; x < 2*dstWidth(); x+=2)
|
||||||
|
getMapping(x, y, map_line[x], map_line[x+1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif //IVX_USE_OPENCV
|
||||||
|
};
|
||||||
|
|
||||||
/// Standard nodes
|
/// Standard nodes
|
||||||
namespace nodes {
|
namespace nodes {
|
||||||
|
|
||||||
|
@ -51,6 +51,8 @@
|
|||||||
#include "opencl_kernels_imgproc.hpp"
|
#include "opencl_kernels_imgproc.hpp"
|
||||||
#include "hal_replacement.hpp"
|
#include "hal_replacement.hpp"
|
||||||
|
|
||||||
|
#include "opencv2/core/openvx/ovx_defs.hpp"
|
||||||
|
|
||||||
using namespace cv;
|
using namespace cv;
|
||||||
|
|
||||||
namespace cv
|
namespace cv
|
||||||
@ -4750,6 +4752,78 @@ static bool ocl_logPolar(InputArray _src, OutputArray _dst,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_OPENVX
|
||||||
|
static bool openvx_remap(Mat src, Mat dst, Mat map1, Mat map2, int interpolation, const Scalar& borderValue)
|
||||||
|
{
|
||||||
|
vx_interpolation_type_e inter_type;
|
||||||
|
switch (interpolation)
|
||||||
|
{
|
||||||
|
case INTER_LINEAR:
|
||||||
|
#if VX_VERSION > VX_VERSION_1_0
|
||||||
|
inter_type = VX_INTERPOLATION_BILINEAR;
|
||||||
|
#else
|
||||||
|
inter_type = VX_INTERPOLATION_TYPE_BILINEAR;
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
case INTER_NEAREST:
|
||||||
|
#if VX_VERSION > VX_VERSION_1_0
|
||||||
|
inter_type = VX_INTERPOLATION_NEAREST_NEIGHBOR;
|
||||||
|
#else
|
||||||
|
inter_type = VX_INTERPOLATION_TYPE_NEAREST_NEIGHBOR;
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
case INTER_AREA://AREA interpolation mode is unsupported
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ivx::Context ctx = ivx::Context::create();
|
||||||
|
|
||||||
|
Mat a;
|
||||||
|
if (dst.data != src.data)
|
||||||
|
a = src;
|
||||||
|
else
|
||||||
|
src.copyTo(a);
|
||||||
|
|
||||||
|
ivx::Image
|
||||||
|
ia = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8,
|
||||||
|
ivx::Image::createAddressing(a.cols, a.rows, 1, (vx_int32)(a.step)), a.data),
|
||||||
|
ib = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8,
|
||||||
|
ivx::Image::createAddressing(dst.cols, dst.rows, 1, (vx_int32)(dst.step)), dst.data);
|
||||||
|
|
||||||
|
//ATTENTION: VX_CONTEXT_IMMEDIATE_BORDER attribute change could lead to strange issues in multi-threaded environments
|
||||||
|
//since OpenVX standart says nothing about thread-safety for now
|
||||||
|
ivx::border_t prevBorder = ctx.immediateBorder();
|
||||||
|
ctx.setImmediateBorder(VX_BORDER_CONSTANT, (vx_uint8)(borderValue[0]));
|
||||||
|
|
||||||
|
ivx::Remap map = ivx::Remap::create(ctx, src.cols, src.rows, dst.cols, dst.rows);
|
||||||
|
if (map1.empty()) map.setMappings(map2);
|
||||||
|
else if (map2.empty()) map.setMappings(map1);
|
||||||
|
else map.setMappings(map1, map2);
|
||||||
|
ivx::IVX_CHECK_STATUS(vxuRemap(ctx, ia, map, inter_type, ib));
|
||||||
|
#ifdef VX_VERSION_1_1
|
||||||
|
ib.swapHandle();
|
||||||
|
ia.swapHandle();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ctx.setImmediateBorder(prevBorder);
|
||||||
|
}
|
||||||
|
catch (ivx::RuntimeError & e)
|
||||||
|
{
|
||||||
|
CV_Error(CV_StsInternal, e.what());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
catch (ivx::WrapperError & e)
|
||||||
|
{
|
||||||
|
CV_Error(CV_StsInternal, e.what());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined HAVE_IPP && IPP_DISABLE_BLOCK
|
#if defined HAVE_IPP && IPP_DISABLE_BLOCK
|
||||||
|
|
||||||
typedef IppStatus (CV_STDCALL * ippiRemap)(const void * pSrc, IppiSize srcSize, int srcStep, IppiRect srcRoi,
|
typedef IppStatus (CV_STDCALL * ippiRemap)(const void * pSrc, IppiSize srcSize, int srcStep, IppiRect srcRoi,
|
||||||
@ -4852,6 +4926,17 @@ void cv::remap( InputArray _src, OutputArray _dst,
|
|||||||
Mat src = _src.getMat(), map1 = _map1.getMat(), map2 = _map2.getMat();
|
Mat src = _src.getMat(), map1 = _map1.getMat(), map2 = _map2.getMat();
|
||||||
_dst.create( map1.size(), src.type() );
|
_dst.create( map1.size(), src.type() );
|
||||||
Mat dst = _dst.getMat();
|
Mat dst = _dst.getMat();
|
||||||
|
|
||||||
|
|
||||||
|
CV_OVX_RUN(
|
||||||
|
src.type() == CV_8UC1 && dst.type() == CV_8UC1 &&
|
||||||
|
(borderType& ~BORDER_ISOLATED) == BORDER_CONSTANT &&
|
||||||
|
((map1.type() == CV_32FC2 && map2.empty() && map1.size == dst.size) ||
|
||||||
|
(map1.type() == CV_32FC1 && map2.type() == CV_32FC1 && map1.size == dst.size && map2.size == dst.size) ||
|
||||||
|
(map1.empty() && map2.type() == CV_32FC2 && map2.size == dst.size)) &&
|
||||||
|
((borderType & BORDER_ISOLATED) != 0 || !src.isSubmatrix()),
|
||||||
|
openvx_remap(src, dst, map1, map2, interpolation, borderValue));
|
||||||
|
|
||||||
CV_Assert( dst.cols < SHRT_MAX && dst.rows < SHRT_MAX && src.cols < SHRT_MAX && src.rows < SHRT_MAX );
|
CV_Assert( dst.cols < SHRT_MAX && dst.rows < SHRT_MAX && src.cols < SHRT_MAX && src.rows < SHRT_MAX );
|
||||||
|
|
||||||
if( dst.data == src.data )
|
if( dst.data == src.data )
|
||||||
|
Loading…
Reference in New Issue
Block a user