static vx_status release(vxType& ref) { return vxReleaseLUT(&ref); }
};
+class Distribution;
+template <> struct RefTypeTraits <vx_distribution>
+{
+ typedef vx_distribution vxType;
+ typedef Distribution wrapperType;
+ static const vx_enum vxTypeEnum = VX_TYPE_DISTRIBUTION;
+ static vx_status release(vxType& ref) { return vxReleaseDistribution(&ref); }
+};
+
#ifdef IVX_USE_CXX98
/// Casting to vx_reference with compile-time check
#endif //IVX_USE_OPENCV
};
+/*
+* Distribution
+*/
+class Distribution : public RefWrapper<vx_distribution>
+{
+public:
+ IVX_REF_STD_CTORS_AND_ASSIGNMENT(Distribution);
+
+ static Distribution create(vx_context context, vx_size numBins, vx_int32 offset, vx_uint32 range)
+ {
+ return Distribution(vxCreateDistribution(context, numBins, offset, range));
+ }
+
+#ifndef VX_VERSION_1_1
+ static const vx_enum
+ VX_MEMORY_TYPE_HOST = VX_IMPORT_TYPE_HOST,
+ VX_DISTRIBUTION_DIMENSIONS = VX_DISTRIBUTION_ATTRIBUTE_DIMENSIONS,
+ VX_DISTRIBUTION_OFFSET = VX_DISTRIBUTION_ATTRIBUTE_OFFSET,
+ VX_DISTRIBUTION_RANGE = VX_DISTRIBUTION_ATTRIBUTE_RANGE,
+ VX_DISTRIBUTION_BINS = VX_DISTRIBUTION_ATTRIBUTE_BINS,
+ VX_DISTRIBUTION_WINDOW = VX_DISTRIBUTION_ATTRIBUTE_WINDOW,
+ VX_DISTRIBUTION_SIZE = VX_DISTRIBUTION_ATTRIBUTE_SIZE;
+#endif
+
+ template<typename T>
+ void query(vx_enum att, T& value) const
+ {
+ IVX_CHECK_STATUS(vxQueryDistribution(ref, att, &value, sizeof(value)));
+ }
+
+ vx_size dimensions() const
+ {
+ vx_size v;
+ query(VX_DISTRIBUTION_DIMENSIONS, v);
+ return v;
+ }
+
+ vx_int32 offset() const
+ {
+ vx_int32 v;
+ query(VX_DISTRIBUTION_OFFSET, v);
+ return v;
+ }
+
+ vx_uint32 range() const
+ {
+ vx_uint32 v;
+ query(VX_DISTRIBUTION_RANGE, v);
+ return v;
+ }
+
+ vx_size bins() const
+ {
+ vx_size v;
+ query(VX_DISTRIBUTION_BINS, v);
+ return v;
+ }
+
+ vx_uint32 window() const
+ {
+ vx_uint32 v;
+ query(VX_DISTRIBUTION_WINDOW, v);
+ return v;
+ }
+
+ vx_size size() const
+ {
+ vx_size v;
+ query(VX_DISTRIBUTION_SIZE, v);
+ return v;
+ }
+
+ vx_size dataType() const
+ {
+ return VX_TYPE_UINT32;
+ }
+
+ void copyTo(void* data)
+ {
+ if (!data) throw WrapperError(std::string(__func__) + "(): output pointer is 0");
+#ifdef VX_VERSION_1_1
+ IVX_CHECK_STATUS(vxCopyDistribution(ref, data, VX_READ_ONLY, VX_MEMORY_TYPE_HOST));
+#else
+ IVX_CHECK_STATUS(vxAccessDistribution(ref, &data, VX_READ_ONLY));
+ IVX_CHECK_STATUS(vxCommitDistribution(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(vxCopyDistribution(ref, const_cast<void*>(data), VX_WRITE_ONLY, VX_MEMORY_TYPE_HOST));
+#else
+ IVX_CHECK_STATUS(vxAccessDistribution(ref, const_cast<void**>(&data), VX_WRITE_ONLY));
+ IVX_CHECK_STATUS(vxCommitDistribution(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(vxCopyDistribution(ref, data, usage, memType));
+#else
+ IVX_CHECK_STATUS(vxAccessDistribution(ref, const_cast<void**>(&data), usage));
+ IVX_CHECK_STATUS(vxCommitDistribution(ref, data));
+ (void)memType;
+#endif
+ }
+
+ template<typename T> void copyTo(std::vector<T>& data)
+ {
+ if (TypeToEnum<T>::value != dataType()) throw WrapperError(std::string(__func__) + "(): destination type is wrong");
+ if (data.size() != bins())
+ {
+ if (data.size() == 0)
+ data.resize(bins());
+ else
+ throw WrapperError(std::string(__func__) + "(): destination size is wrong");
+ }
+ copyTo(&data[0]);
+ }
+
+ template<typename T> void copyFrom(const std::vector<T>& data)
+ {
+ if (TypeToEnum<T>::value != dataType()) throw WrapperError(std::string(__func__) + "(): source type is wrong");
+ if (data.size() != bins()) 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) == bins() && m.cols == 1) ||
+ ((vx_size)(m.cols) == bins() && m.rows == 1)
+ ) && !m.empty())
+ throw WrapperError(std::string(__func__) + "(): destination size is wrong");
+
+ if (m.isContinuous() && (vx_size)(m.total()) == bins())
+ {
+ copyTo(m.ptr());
+ }
+ else
+ {
+ cv::Mat tmp(1, (int)bins(), 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) == bins() && m.cols == 1) ||
+ ((vx_size)(m.cols) == bins() && 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 {
#include "precomp.hpp"
#include "opencl_kernels_imgproc.hpp"
-#ifdef HAVE_OPENVX
-#define IVX_USE_OPENCV
-#define IVX_HIDE_INFO_WARNINGS
-#include "ivx.hpp"
-#endif
+#include "opencv2/core/openvx/ovx_defs.hpp"
namespace cv
{
}
+#ifdef HAVE_OPENVX
+namespace cv
+{
+ static bool openvx_calchist(const Mat& image, OutputArray _hist, const int histSize,
+ const float* _range)
+ {
+ vx_int32 offset = (vx_int32)(_range[0]);
+ vx_uint32 range = (vx_uint32)(_range[1] - _range[0]);
+ if (float(offset) != _range[0] || float(range) != (_range[1] - _range[0]))
+ return false;
+
+ size_t total_size = image.total();
+ int rows = image.dims > 1 ? image.size[0] : 1, cols = rows ? (int)(total_size / rows) : 0;
+ if (image.dims > 2 && !(image.isContinuous() && cols > 0 && (size_t)rows*cols == total_size))
+ return false;
+
+ try
+ {
+ ivx::Context ctx = ivx::Context::create();
+#if VX_VERSION <= VX_VERSION_1_0
+ if (ctx.vendorID() == VX_ID_KHRONOS && (range % histSize))
+ return false;
+#endif
+
+ ivx::Image
+ img = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8,
+ ivx::Image::createAddressing(cols, rows, 1, (vx_int32)(image.step[0])), image.data);
+
+ ivx::Distribution vxHist = ivx::Distribution::create(ctx, histSize, offset, range);
+ ivx::IVX_CHECK_STATUS(vxuHistogram(ctx, img, vxHist));
+
+ _hist.create(1, &histSize, CV_32F);
+ Mat hist = _hist.getMat(), ihist = hist;
+ ihist.flags = (ihist.flags & ~CV_MAT_TYPE_MASK) | CV_32S;
+ vxHist.copyTo(ihist);
+ ihist.convertTo(hist, CV_32F);
+
+#ifdef VX_VERSION_1_1
+ img.swapHandle();
+#endif
+ }
+ 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 cv
{
{
CV_INSTRUMENT_REGION()
+ CV_OVX_RUN(
+ images && histSize &&
+ nimages == 1 && images[0].type() == CV_8UC1 && dims == 1 && _mask.getMat().empty() &&
+ (!channels || channels[0] == 0) && !accumulate && uniform &&
+ ranges && ranges[0],
+ openvx_calchist(images[0], _hist, histSize[0], ranges[0]));
+
CV_IPP_RUN(nimages == 1 && images[0].type() == CV_8UC1 && dims == 1 && channels &&
channels[0] == 0 && _mask.getMat().empty() && images[0].dims <= 2 &&
!accumulate && uniform,