Merge pull request #7677 from terfendail:ovx_minmaxloc

pull/7775/head
Vadim Pisarevsky 8 years ago
commit ddc5155a85
  1. 154
      3rdparty/openvx/include/ivx.hpp
  2. 87
      modules/core/src/stat.cpp

@ -1838,6 +1838,160 @@ public:
/// vxCreateVirtualArray() wrapper
static Array createVirtual(vx_graph g, vx_enum type, vx_size capacity)
{ return Array(vxCreateVirtualArray(g, type, capacity)); }
#ifndef VX_VERSION_1_1
static const vx_enum
VX_MEMORY_TYPE_HOST = VX_IMPORT_TYPE_HOST,
VX_ARRAY_ITEMTYPE = VX_ARRAY_ATTRIBUTE_ITEMTYPE,
VX_ARRAY_NUMITEMS = VX_ARRAY_ATTRIBUTE_NUMITEMS,
VX_ARRAY_CAPACITY = VX_ARRAY_ATTRIBUTE_CAPACITY,
VX_ARRAY_ITEMSIZE = VX_ARRAY_ATTRIBUTE_ITEMSIZE;
#endif
template<typename T>
void query(vx_enum att, T& value) const
{ IVX_CHECK_STATUS( vxQueryArray(ref, att, &value, sizeof(value)) ); }
vx_enum itemType() const
{
vx_enum v;
query(VX_ARRAY_ITEMTYPE, v);
return v;
}
vx_size itemSize() const
{
vx_size v;
query(VX_ARRAY_ITEMSIZE, v);
return v;
}
vx_size capacity() const
{
vx_size v;
query(VX_ARRAY_CAPACITY, v);
return v;
}
vx_size itemCount() const
{
vx_size v;
query(VX_ARRAY_NUMITEMS, v);
return v;
}
void copyRangeTo(size_t start, size_t end, void* data)
{
if (!data) throw WrapperError(std::string(__func__) + "(): output pointer is 0");
#ifdef VX_VERSION_1_1
IVX_CHECK_STATUS(vxCopyArrayRange(ref, start, end, itemSize(), data, VX_READ_ONLY, VX_MEMORY_TYPE_HOST));
#else
vx_size stride = itemSize();
IVX_CHECK_STATUS(vxAccessArrayRange(ref, start, end, &stride, &data, VX_READ_ONLY));
IVX_CHECK_STATUS(vxCommitArrayRange(ref, start, end, data));
#endif
}
void copyTo(void* data)
{ copyRangeTo(0, itemCount(), data); }
void copyRangeFrom(size_t start, size_t end, const void* data)
{
if (!data) throw WrapperError(std::string(__func__) + "(): input pointer is 0");
#ifdef VX_VERSION_1_1
IVX_CHECK_STATUS(vxCopyArrayRange(ref, start, end, itemSize(), const_cast<void*>(data), VX_WRITE_ONLY, VX_MEMORY_TYPE_HOST));
#else
vx_size stride = itemSize();
IVX_CHECK_STATUS(vxAccessArrayRange(ref, start, end, &stride, const_cast<void**>(&data), VX_WRITE_ONLY));
IVX_CHECK_STATUS(vxCommitArrayRange(ref, start, end, data));
#endif
}
void copyFrom(const void* data)
{ copyRangeFrom(0, itemCount(), data); }
void copyRange(size_t start, size_t end, void* data, vx_enum usage, vx_enum memType = VX_MEMORY_TYPE_HOST)
{
if (!data) throw WrapperError(std::string(__func__) + "(): data pointer is 0");
#ifdef VX_VERSION_1_1
IVX_CHECK_STATUS(vxCopyArrayRange(ref, start, end, itemSize(), data, usage, memType));
#else
vx_size stride = itemSize();
IVX_CHECK_STATUS(vxAccessArrayRange(ref, start, end, &stride, &data, usage));
IVX_CHECK_STATUS(vxCommitArrayRange(ref, start, end, data));
(void)memType;
#endif
}
void copy(void* data, vx_enum usage, vx_enum memType = VX_MEMORY_TYPE_HOST)
{ copyRange(0, itemCount(), data, usage, memType); }
template<typename T> void copyRangeTo(size_t start, size_t end, std::vector<T>& data)
{
if (TypeToEnum<T>::value != itemType()) throw WrapperError(std::string(__func__) + "(): destination type is wrong");
if (data.size() != (end - start))
{
if (data.size() == 0)
data.resize((end - start));
else
throw WrapperError(std::string(__func__) + "(): destination size is wrong");
}
copyRangeTo(start, end, &data[0]);
}
template<typename T> void copyTo(std::vector<T>& data)
{ copyRangeTo(0, itemCount(), data); }
template<typename T> void copyRangeFrom(size_t start, size_t end, const std::vector<T>& data)
{
if (TypeToEnum<T>::value != itemType()) throw WrapperError(std::string(__func__) + "(): source type is wrong");
if (data.size() != (end - start)) throw WrapperError(std::string(__func__) + "(): source size is wrong");
copyRangeFrom(start, end, &data[0]);
}
template<typename T> void copyFrom(std::vector<T>& data)
{ copyRangeFrom(0, itemCount(), data); }
#ifdef IVX_USE_OPENCV
void copyRangeTo(size_t start, size_t end, cv::Mat& m)
{
if (m.type() != enumToCVType(itemType())) throw WrapperError(std::string(__func__) + "(): destination type is wrong");
if (!(
((vx_size)(m.rows) == (end - start) && m.cols == 1) ||
((vx_size)(m.cols) == (end - start) && m.rows == 1)
) && !m.empty()) throw WrapperError(std::string(__func__) + "(): destination size is wrong");
if (m.isContinuous() && (vx_size)(m.total()) == (end - start))
{
copyRangeTo(start, end, m.ptr());
}
else
{
cv::Mat tmp(1, (int)(end - start), enumToCVType(itemType()));
copyRangeTo(start, end, tmp.ptr());
if (m.empty())
m = tmp;
else
tmp.copyTo(m);
}
}
void copyTo(cv::Mat& m)
{ copyRangeTo(0, itemCount(), m); }
void copyRangeFrom(size_t start, size_t end, const cv::Mat& m)
{
if (!(
((vx_size)(m.rows) == (end - start) && m.cols == 1) ||
((vx_size)(m.cols) == (end - start) && m.rows == 1)
)) throw WrapperError(std::string(__func__) + "(): source size is wrong");
if (m.type() != enumToCVType(itemType())) throw WrapperError(std::string(__func__) + "(): source type is wrong");
copyFrom(m.isContinuous() ? m.ptr() : m.clone().ptr());
}
void copyFrom(const cv::Mat& m)
{ copyRangeFrom(0, itemCount(), m); }
#endif //IVX_USE_OPENCV
};
/*

@ -47,6 +47,12 @@
#include "opencl_kernels_core.hpp"
#ifdef HAVE_OPENVX
#define IVX_HIDE_INFO_WARNINGS
#define IVX_USE_OPENCV
#include "ivx.hpp"
#endif
namespace cv
{
@ -2226,6 +2232,81 @@ static bool ocl_minMaxIdx( InputArray _src, double* minVal, double* maxVal, int*
#endif
#ifdef HAVE_OPENVX
static bool openvx_minMaxIdx(Mat &src, double* minVal, double* maxVal, int* minIdx, int* maxIdx, Mat &mask)
{
int stype = src.type();
size_t total_size = src.total();
int rows = src.size[0], cols = rows ? (int)(total_size / rows) : 0;
if ((stype != CV_8UC1 && stype != CV_16SC1) || !mask.empty() ||
(src.dims != 2 && !(src.isContinuous() && cols > 0 && (size_t)rows*cols == total_size))
)
return false;
try
{
ivx::Context ctx = ivx::Context::create();
ivx::Image
ia = ivx::Image::createFromHandle(ctx, stype == CV_8UC1 ? VX_DF_IMAGE_U8 : VX_DF_IMAGE_S16,
ivx::Image::createAddressing(cols, rows, stype == CV_8UC1 ? 1 : 2, (vx_int32)(src.step[0])), src.ptr());
ivx::Scalar vxMinVal = ivx::Scalar::create(ctx, stype == CV_8UC1 ? VX_TYPE_UINT8 : VX_TYPE_INT16, 0);
ivx::Scalar vxMaxVal = ivx::Scalar::create(ctx, stype == CV_8UC1 ? VX_TYPE_UINT8 : VX_TYPE_INT16, 0);
ivx::Array vxMinInd, vxMaxInd;
ivx::Scalar vxMinCount, vxMaxCount;
if (minIdx)
{
vxMinInd = ivx::Array::create(ctx, VX_TYPE_COORDINATES2D, 1);
vxMinCount = ivx::Scalar::create(ctx, VX_TYPE_UINT32, 0);
}
if (maxIdx)
{
vxMaxInd = ivx::Array::create(ctx, VX_TYPE_COORDINATES2D, 1);
vxMaxCount = ivx::Scalar::create(ctx, VX_TYPE_UINT32, 0);
}
ivx::IVX_CHECK_STATUS(vxuMinMaxLoc(ctx, ia, vxMinVal, vxMaxVal, vxMinInd, vxMaxInd, vxMinCount, vxMaxCount));
if (minVal)
{
*minVal = stype == CV_8UC1 ? vxMinVal.getValue<vx_uint8>() : vxMinVal.getValue<vx_int16>();
}
if (maxVal)
{
*maxVal = stype == CV_8UC1 ? vxMaxVal.getValue<vx_uint8>() : vxMaxVal.getValue<vx_int16>();
}
if (minIdx)
{
if(vxMinCount.getValue<vx_uint32>()<1) throw ivx::RuntimeError(VX_ERROR_INVALID_VALUE, std::string(__func__) + "(): minimum value location not found");
vx_coordinates2d_t loc;
vxMinInd.copyRangeTo(0, 1, &loc);
size_t minidx = loc.y * cols + loc.x + 1;
ofs2idx(src, minidx, minIdx);
}
if (maxIdx)
{
if (vxMaxCount.getValue<vx_uint32>()<1) throw ivx::RuntimeError(VX_ERROR_INVALID_VALUE, std::string(__func__) + "(): maximum value location not found");
vx_coordinates2d_t loc;
vxMaxInd.copyRangeTo(0, 1, &loc);
size_t maxidx = loc.y * cols + loc.x + 1;
ofs2idx(src, maxidx, maxIdx);
}
return true;
}
catch (ivx::RuntimeError & e)
{
CV_Error(CV_StsInternal, e.what());
return false;
}
catch (ivx::WrapperError & e)
{
CV_Error(CV_StsInternal, e.what());
return false;
}
}
#endif
#ifdef HAVE_IPP
static bool ipp_minMaxIdx( Mat &src, double* minVal, double* maxVal, int* minIdx, int* maxIdx, Mat &mask)
{
@ -2349,6 +2430,12 @@ void cv::minMaxIdx(InputArray _src, double* minVal,
ocl_minMaxIdx(_src, minVal, maxVal, minIdx, maxIdx, _mask))
Mat src = _src.getMat(), mask = _mask.getMat();
#ifdef HAVE_OPENVX
if (openvx_minMaxIdx(src, minVal, maxVal, minIdx, maxIdx, mask))
return;
#endif
CV_IPP_RUN(IPP_VERSION_X100 >= 700, ipp_minMaxIdx(src, minVal, maxVal, minIdx, maxIdx, mask))
MinMaxIdxFunc func = getMinmaxTab(depth);

Loading…
Cancel
Save