From ced81f72bc83650b16bc6eec5584e369caa78c93 Mon Sep 17 00:00:00 2001 From: Vitaly Tuzov Date: Tue, 1 Nov 2016 21:14:21 +0300 Subject: [PATCH] Added OpenVX based processing to LUT --- 3rdparty/openvx/include/ivx.hpp | 166 ++++++++++++++++++++++++++++++++++++++++ modules/core/src/convert.cpp | 40 ++++++++++ 2 files changed, 206 insertions(+) diff --git a/3rdparty/openvx/include/ivx.hpp b/3rdparty/openvx/include/ivx.hpp index a578b14..8c982c4 100644 --- a/3rdparty/openvx/include/ivx.hpp +++ b/3rdparty/openvx/include/ivx.hpp @@ -322,6 +322,15 @@ template <> struct RefTypeTraits static vx_status release(vxType& ref) { return vxReleaseMatrix(&ref); } }; +class LUT; +template <> struct RefTypeTraits +{ + typedef vx_lut vxType; + typedef LUT wrapperType; + static const vx_enum vxTypeEnum = VX_TYPE_LUT; + static vx_status release(vxType& ref) { return vxReleaseLUT(&ref); } +}; + #ifdef IVX_USE_CXX98 /// Casting to vx_reference with compile-time check @@ -2321,6 +2330,163 @@ public: #endif //IVX_USE_OPENCV }; +/* +* LUT +*/ +class LUT : public RefWrapper +{ +public: + IVX_REF_STD_CTORS_AND_ASSIGNMENT(LUT); + +#ifdef VX_VERSION_1_1 + static LUT create(vx_context context, vx_enum dataType = VX_TYPE_UINT8, vx_size count = 256) + { +#else + static LUT create(vx_context context) + { + vx_enum dataType = VX_TYPE_UINT8; + vx_size count = 256; +#endif + return LUT(vxCreateLUT(context, dataType, count)); + } + +#ifndef VX_VERSION_1_1 + static const vx_enum VX_MEMORY_TYPE_HOST = VX_IMPORT_TYPE_HOST; +#endif + + template + void query(vx_enum att, T& value) const + { + IVX_CHECK_STATUS(vxQueryLUT(ref, att, &value, sizeof(value))); + } + +#ifndef VX_VERSION_1_1 + static const vx_enum + VX_LUT_TYPE = VX_LUT_ATTRIBUTE_TYPE, + VX_LUT_COUNT = VX_LUT_ATTRIBUTE_COUNT, + VX_LUT_SIZE = VX_LUT_ATTRIBUTE_SIZE; +#endif + + vx_enum dataType() const + { + vx_enum v; + query(VX_LUT_TYPE, v); + return v; + } + + vx_size count() const + { + vx_size v; + query(VX_LUT_COUNT, v); + return v; + } + + vx_size size() const + { + vx_size v; + query(VX_LUT_SIZE, v); + return v; + } + +#ifdef VX_VERSION_1_1 + vx_uint32 offset() const + { + vx_enum v; + query(VX_LUT_OFFSET, v); + return v; + } +#endif // VX_VERSION_1_1 + + void copyTo(void* data) + { + if (!data) throw WrapperError(std::string(__func__) + "(): output pointer is 0"); +#ifdef VX_VERSION_1_1 + IVX_CHECK_STATUS(vxCopyLUT(ref, data, VX_READ_ONLY, VX_MEMORY_TYPE_HOST)); +#else + IVX_CHECK_STATUS(vxAccessLUT(ref, &data, VX_READ_ONLY)); + IVX_CHECK_STATUS(vxCommitLUT(ref, data)); +#endif + } + + void copyFrom(const void* data) + { + if (!data) throw WrapperError(std::string(__func__) + "(): input pointer is 0"); +#ifdef VX_VERSION_1_1 + IVX_CHECK_STATUS(vxCopyLUT(ref, const_cast(data), VX_WRITE_ONLY, VX_MEMORY_TYPE_HOST)); +#else + IVX_CHECK_STATUS(vxAccessLUT(ref, const_cast(&data), VX_WRITE_ONLY)); + IVX_CHECK_STATUS(vxCommitLUT(ref, data)); +#endif + } + + void copy(void* data, vx_enum usage, vx_enum memType = VX_MEMORY_TYPE_HOST) + { +#ifdef VX_VERSION_1_1 + IVX_CHECK_STATUS(vxCopyLUT(ref, data, usage, memType)); +#else + IVX_CHECK_STATUS(vxAccessLUT(ref, const_cast(&data), usage)); + IVX_CHECK_STATUS(vxCommitLUT(ref, data)); + (void)memType; +#endif + } + + template void copyTo(std::vector& data) + { + if (TypeToEnum::value != dataType()) throw WrapperError(std::string(__func__) + "(): destination type is wrong"); + if (data.size() != count()) + { + if (data.size() == 0) + data.resize(count()); + else + throw WrapperError(std::string(__func__) + "(): destination size is wrong"); + } + copyTo(&data[0]); + } + + template void copyFrom(const std::vector& data) + { + if (TypeToEnum::value != dataType()) throw WrapperError(std::string(__func__) + "(): source type is wrong"); + if (data.size() != count()) throw WrapperError(std::string(__func__) + "(): source size is wrong"); + copyFrom(&data[0]); + } + +#ifdef IVX_USE_OPENCV + void copyTo(cv::Mat& m) + { + if (m.type() != enumToCVType(dataType())) throw WrapperError(std::string(__func__) + "(): destination type is wrong"); + if (!( + ((vx_size)(m.rows) == count() && m.cols == 1) || + ((vx_size)(m.cols) == count() && m.rows == 1) + ) && !m.empty()) + throw WrapperError(std::string(__func__) + "(): destination size is wrong"); + + if (m.isContinuous() && (vx_size)(m.total()) == count()) + { + copyTo(m.ptr()); + } + else + { + cv::Mat tmp(1, (int)count(), enumToCVType(dataType())); + copyTo(tmp.ptr()); + if (m.empty()) + m = tmp; + else + tmp.copyTo(m); + } + } + + void copyFrom(const cv::Mat& m) + { + if (!( + ((vx_size)(m.rows) == count() && m.cols == 1) || + ((vx_size)(m.cols) == count() && m.rows == 1) + )) throw WrapperError(std::string(__func__) + "(): source size is wrong"); + if (m.type() != enumToCVType(dataType())) throw WrapperError(std::string(__func__) + "(): source type is wrong"); + copyFrom(m.isContinuous() ? m.ptr() : m.clone().ptr()); + } +#endif //IVX_USE_OPENCV +}; + /// Standard nodes namespace nodes { diff --git a/modules/core/src/convert.cpp b/modules/core/src/convert.cpp index 7dc8e89..f02ca05 100644 --- a/modules/core/src/convert.cpp +++ b/modules/core/src/convert.cpp @@ -5374,6 +5374,41 @@ static bool ocl_LUT(InputArray _src, InputArray _lut, OutputArray _dst) #endif +#ifdef HAVE_OPENVX +static bool openvx_LUT(Mat src, Mat dst, Mat _lut) +{ + if (src.type() != CV_8UC1 || dst.type() != src.type() || _lut.type() != src.type() || !_lut.isContinuous()) + return false; + + try + { + ivx::Context ctx = ivx::Context::create(); + + ivx::Image + ia = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8, + ivx::Image::createAddressing(src.cols, src.rows, 1, (vx_int32)(src.step)), src.data), + ib = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8, + ivx::Image::createAddressing(dst.cols, dst.rows, 1, (vx_int32)(dst.step)), dst.data); + + ivx::LUT lut = ivx::LUT::create(ctx); + lut.copyFrom(_lut); + ivx::IVX_CHECK_STATUS(vxuTableLookup(ctx, ia, lut, ib)); + } + 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) namespace ipp { @@ -5639,6 +5674,11 @@ void cv::LUT( InputArray _src, InputArray _lut, OutputArray _dst ) _dst.create(src.dims, src.size, CV_MAKETYPE(_lut.depth(), cn)); Mat dst = _dst.getMat(); +#ifdef HAVE_OPENVX + if (openvx_LUT(src, dst, lut)) + return; +#endif + CV_IPP_RUN(_src.dims() <= 2, ipp_lut(src, lut, dst)); if (_src.dims() <= 2) -- 2.7.4