mirror of
https://github.com/opencv/opencv.git
synced 2025-06-11 03:33:28 +08:00
Merge pull request #7677 from terfendail:ovx_minmaxloc
This commit is contained in:
commit
ddc5155a85
154
3rdparty/openvx/include/ivx.hpp
vendored
154
3rdparty/openvx/include/ivx.hpp
vendored
@ -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…
Reference in New Issue
Block a user