mirror of
https://github.com/opencv/opencv.git
synced 2026-09-25 04:09:57 +03:00
Merge pull request #25197 from invarrow:invbranch-cleanup
Remove OpenVX #25197 resolves https://github.com/opencv/opencv/issues/24995 OpenCV cleanup https://github.com/opencv/opencv/issues/25007
This commit is contained in:
Vendored
-7
@@ -1,7 +0,0 @@
|
||||
if(NOT HAVE_OPENVX)
|
||||
message(STATUS "OpenVX is not available, disabling openvx-related HAL and stuff")
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(OPENCV_3P_OPENVX_DIR ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
add_subdirectory(hal)
|
||||
Vendored
-97
@@ -1,97 +0,0 @@
|
||||
# C++ wrappers for OpenVX-1.x C API
|
||||
|
||||
## Core ideas:
|
||||
|
||||
* lightweight - minimal overhead vs standard C API
|
||||
* automatic references counting
|
||||
* exceptions instead of return codes
|
||||
* object-oriented design
|
||||
* (NYI) helpers for user-defined kernels & nodes
|
||||
* C++ 11 friendly
|
||||
|
||||
## Quick start sample
|
||||
|
||||
The following short sample gives basic knowledges on the wrappers usage:
|
||||
|
||||
```cpp
|
||||
#include "ivx.hpp"
|
||||
#include "ivx_lib_debug.hpp" // ivx::debug::*
|
||||
|
||||
int main()
|
||||
{
|
||||
vx_uint32 width = 640, height = 480;
|
||||
try
|
||||
{
|
||||
ivx::Context context = ivx::Context::create();
|
||||
ivx::Graph graph = ivx::Graph::create(context);
|
||||
ivx::Image
|
||||
gray = ivx::Image::create(context, width, height, VX_DF_IMAGE_U8),
|
||||
gb = ivx::Image::createVirtual(graph),
|
||||
res = ivx::Image::create(context, width, height, VX_DF_IMAGE_U8);
|
||||
|
||||
context.loadKernels("openvx-debug"); // ivx::debug::*
|
||||
|
||||
ivx::debug::fReadImage(context, inputPath, gray);
|
||||
|
||||
ivx::Node::create(graph, VX_KERNEL_GAUSSIAN_3x3, gray, gb);
|
||||
ivx::Node::create(
|
||||
graph,
|
||||
VX_KERNEL_THRESHOLD,
|
||||
gb,
|
||||
ivx::Threshold::createBinary(context, VX_TYPE_UINT8, 50),
|
||||
res
|
||||
);
|
||||
|
||||
graph.verify();
|
||||
graph.process();
|
||||
|
||||
ivx::debug::fWriteImage(context, res, "ovx-res-cpp.pgm");
|
||||
}
|
||||
catch (const ivx::RuntimeError& e)
|
||||
{
|
||||
printf("ErrorRuntime: code = %d(%x), message = %s\n", e.status(), e.status(), e.what());
|
||||
return e.status();
|
||||
}
|
||||
catch (const ivx::WrapperError& e)
|
||||
{
|
||||
printf("ErrorWrapper: message = %s\n", e.what());
|
||||
return -1;
|
||||
}
|
||||
catch(const std::exception& e)
|
||||
{
|
||||
printf("runtime_error: message = %s\n", e.what());
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
```
|
||||
## C++ API overview
|
||||
|
||||
The wrappers have **header-only** implementation that simplifies their integration to projects.
|
||||
All the API is inside `ivx` namespace (E.g. `class ivx::Graph`).
|
||||
|
||||
While the C++ API is pretty much the same for underlying OpenVX version **1.0** and **1.1**, there are alternative code branches for some features implementation that are selected at **compile time** via `#ifdef` preprocessor directives.
|
||||
E.g. external ref-counting is implemented for 1.0 version and native OpenVX one is used (via `vxRetainReference()` and `vxReleaseXYZ()`) for version 1.1.
|
||||
|
||||
Also there are some **C++ 11** features are used (e.g. rvalue ref-s) when their availability is detected at ***compile time***.
|
||||
|
||||
C++ exceptions are used for errors indication instead of return codes. There are two types of exceptions are defined: `RuntimeError` is thrown when OpenVX C call returned unsuccessful result and `WrapperError` is thrown when a problem is occurred in the wrappers code. Both exception calsses are derived from `std::exception` (actually from its inheritants).
|
||||
|
||||
The so called **OpenVX objects** (e.g. `vx_image`) are represented as C++ classes in wrappers.
|
||||
All these classes use automatic ref-counting that allows development of exception-safe code.
|
||||
All these classes have `create()` or `createXYZ()` `static` methods for instances creation. (E.g. `Image::create()`, `Image::createVirtual()` and `Image::createFromHandle()`)
|
||||
Most of the wrapped OpenVX functions are represented as methods of the corresponding C++ classes, but in most cases they still accept C "object" types (e.g. `vx_image` or `vx_context`) that allows mixing of C and C++ OpenVX API use.
|
||||
E.g.:
|
||||
```cpp
|
||||
class Image
|
||||
{
|
||||
static Image create(vx_context context, vx_uint32 width, vx_uint32 height, vx_df_image format);
|
||||
static Image createVirtual(vx_graph graph, vx_uint32 width = 0, vx_uint32 height = 0, vx_df_image format = VX_DF_IMAGE_VIRT);
|
||||
// ...
|
||||
}
|
||||
```
|
||||
All the classes instances can automatically be converted to the corresponding C "object" types.
|
||||
|
||||
For more details please refer to C++ wrappers reference manual or directly to their source code.
|
||||
Vendored
-18
@@ -1,18 +0,0 @@
|
||||
add_library(openvx_hal STATIC openvx_hal.cpp openvx_hal.hpp ${OPENCV_3P_OPENVX_DIR}/include/ivx.hpp ${OPENCV_3P_OPENVX_DIR}/include/ivx_lib_debug.hpp)
|
||||
target_include_directories(openvx_hal PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${OPENCV_3P_OPENVX_DIR}/include
|
||||
${CMAKE_SOURCE_DIR}/modules/core/include
|
||||
${CMAKE_SOURCE_DIR}/modules/imgproc/include
|
||||
${OPENVX_INCLUDE_DIR})
|
||||
target_link_libraries(openvx_hal PUBLIC ${OPENVX_LIBRARIES})
|
||||
set_target_properties(openvx_hal PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${3P_LIBRARY_OUTPUT_PATH})
|
||||
if(NOT BUILD_SHARED_LIBS)
|
||||
ocv_install_target(openvx_hal EXPORT OpenCVModules ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT dev)
|
||||
endif()
|
||||
|
||||
set(OPENVX_HAL_FOUND TRUE CACHE INTERNAL "")
|
||||
set(OPENVX_HAL_VERSION 0.0.1 CACHE INTERNAL "")
|
||||
set(OPENVX_HAL_LIBRARIES "openvx_hal" CACHE INTERNAL "")
|
||||
set(OPENVX_HAL_HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/openvx_hal.hpp" CACHE INTERNAL "")
|
||||
set(OPENVX_HAL_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}" "${OPENCV_3P_OPENVX_DIR}/include" "${OPENVX_INCLUDE_DIR}" CACHE INTERNAL "")
|
||||
Vendored
-4
@@ -1,4 +0,0 @@
|
||||
#OpenVX-based HAL implementation.
|
||||
It's built when OpenVX is available (`HAVE_OPENVX`).
|
||||
To build OpenCV with OpenVX support add the following **cmake** options:
|
||||
`-DOPENVX_ROOT=/path/to/prebuilt/openvx -DWITH_OPENVX=YES`
|
||||
Vendored
-1147
@@ -1,1147 +0,0 @@
|
||||
#include "openvx_hal.hpp"
|
||||
#include "opencv2/imgproc/hal/interface.h"
|
||||
|
||||
#define IVX_HIDE_INFO_WARNINGS
|
||||
#include "ivx.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cfloat>
|
||||
#include <climits>
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
|
||||
//==================================================================================================
|
||||
// utility
|
||||
// ...
|
||||
|
||||
#if 0
|
||||
#include <cstdio>
|
||||
#define PRINT(...) printf(__VA_ARGS__)
|
||||
#define PRINT_HALERR_MSG(type) PRINT("OpenVX HAL impl "#type" error: %s\n", e.what())
|
||||
#else
|
||||
#define PRINT(...)
|
||||
#define PRINT_HALERR_MSG(type) (void)e
|
||||
#endif
|
||||
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
#include <chrono>
|
||||
struct Tick
|
||||
{
|
||||
typedef std::chrono::time_point<std::chrono::steady_clock> point_t;
|
||||
point_t start;
|
||||
point_t point;
|
||||
Tick()
|
||||
{
|
||||
start = std::chrono::steady_clock::now();
|
||||
point = std::chrono::steady_clock::now();
|
||||
}
|
||||
inline int one()
|
||||
{
|
||||
point_t old = point;
|
||||
point = std::chrono::steady_clock::now();
|
||||
return std::chrono::duration_cast<std::chrono::microseconds>(point - old).count();
|
||||
}
|
||||
inline int total()
|
||||
{
|
||||
return std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() - start).count();
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
inline ivx::Context& getOpenVXHALContext()
|
||||
{
|
||||
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
|
||||
//CXX11
|
||||
static thread_local ivx::Context instance = ivx::Context::create();
|
||||
#else //__cplusplus >= 201103L || _MSC_VER >= 1800
|
||||
//CXX98
|
||||
#ifdef _WIN32
|
||||
static __declspec(thread) ivx::Context instance = ivx::Context::create();
|
||||
#else
|
||||
static __thread ivx::Context instance = ivx::Context::create();
|
||||
#endif
|
||||
#endif
|
||||
return instance;
|
||||
}
|
||||
|
||||
inline bool dimTooBig(int size)
|
||||
{
|
||||
static vx_uint16 current_vendor = getOpenVXHALContext().vendorID();
|
||||
|
||||
if (current_vendor == VX_ID_KHRONOS || current_vendor == VX_ID_DEFAULT)
|
||||
{
|
||||
//OpenVX use uint32_t for image addressing
|
||||
return ((unsigned)size > (UINT_MAX / VX_SCALE_UNITY));
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
//OpenVX calls have essential overhead so it make sense to skip them for small images
|
||||
template <int kernel_id> inline bool skipSmallImages(int w, int h) { return w*h < 7680 * 4320; }
|
||||
template <> inline bool skipSmallImages<VX_KERNEL_MULTIPLY>(int w, int h) { return w*h < 640 * 480; }
|
||||
template <> inline bool skipSmallImages<VX_KERNEL_COLOR_CONVERT>(int w, int h) { return w*h < 2048 * 1536; }
|
||||
template <> inline bool skipSmallImages<VX_KERNEL_INTEGRAL_IMAGE>(int w, int h) { return w*h < 640 * 480; }
|
||||
template <> inline bool skipSmallImages<VX_KERNEL_WARP_AFFINE>(int w, int h) { return w*h < 1280 * 720; }
|
||||
template <> inline bool skipSmallImages<VX_KERNEL_WARP_PERSPECTIVE>(int w, int h) { return w*h < 320 * 240; }
|
||||
template <> inline bool skipSmallImages<VX_KERNEL_CUSTOM_CONVOLUTION>(int w, int h) { return w*h < 320 * 240; }
|
||||
|
||||
inline void setConstantBorder(ivx::border_t &border, vx_uint8 val)
|
||||
{
|
||||
border.mode = VX_BORDER_CONSTANT;
|
||||
#if VX_VERSION > VX_VERSION_1_0
|
||||
border.constant_value.U8 = val;
|
||||
#else
|
||||
border.constant_value = val;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void refineStep(int w, int h, int imgType, size_t& step)
|
||||
{
|
||||
if (h == 1)
|
||||
step = w * ((imgType == VX_DF_IMAGE_RGBX ||
|
||||
imgType == VX_DF_IMAGE_U32 || imgType == VX_DF_IMAGE_S32) ? 4 :
|
||||
imgType == VX_DF_IMAGE_RGB ? 3 :
|
||||
(imgType == VX_DF_IMAGE_U16 || imgType == VX_DF_IMAGE_S16 ||
|
||||
imgType == VX_DF_IMAGE_UYVY || imgType == VX_DF_IMAGE_YUYV) ? 2 : 1);
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
// ivx::Image wrapped to simplify call to swapHandle prior to release
|
||||
// TODO update ivx::Image to handle swapHandle prior to release on the own
|
||||
|
||||
class vxImage: public ivx::Image
|
||||
{
|
||||
public:
|
||||
vxImage(const ivx::Image &_img) : ivx::Image(_img) {}
|
||||
|
||||
~vxImage()
|
||||
{
|
||||
#if VX_VERSION > VX_VERSION_1_0
|
||||
swapHandle();
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
// real code starts here
|
||||
// ...
|
||||
|
||||
#define OVX_BINARY_OP(hal_func, ovx_call, kernel_id) \
|
||||
template <typename T> \
|
||||
int ovx_hal_##hal_func(const T *a, size_t astep, const T *b, size_t bstep, T *c, size_t cstep, int w, int h) \
|
||||
{ \
|
||||
if(skipSmallImages<kernel_id>(w, h)) \
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED; \
|
||||
if(dimTooBig(w) || dimTooBig(h)) \
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED; \
|
||||
refineStep(w, h, ivx::TypeToEnum<T>::imgType, astep); \
|
||||
refineStep(w, h, ivx::TypeToEnum<T>::imgType, bstep); \
|
||||
refineStep(w, h, ivx::TypeToEnum<T>::imgType, cstep); \
|
||||
try \
|
||||
{ \
|
||||
ivx::Context ctx = getOpenVXHALContext(); \
|
||||
vxImage \
|
||||
ia = ivx::Image::createFromHandle(ctx, ivx::TypeToEnum<T>::imgType, \
|
||||
ivx::Image::createAddressing(w, h, sizeof(T), (vx_int32)(astep)), (void*)a), \
|
||||
ib = ivx::Image::createFromHandle(ctx, ivx::TypeToEnum<T>::imgType, \
|
||||
ivx::Image::createAddressing(w, h, sizeof(T), (vx_int32)(bstep)), (void*)b), \
|
||||
ic = ivx::Image::createFromHandle(ctx, ivx::TypeToEnum<T>::imgType, \
|
||||
ivx::Image::createAddressing(w, h, sizeof(T), (vx_int32)(cstep)), (void*)c); \
|
||||
ovx_call \
|
||||
} \
|
||||
catch (ivx::RuntimeError & e) \
|
||||
{ \
|
||||
PRINT_HALERR_MSG(runtime); \
|
||||
return CV_HAL_ERROR_UNKNOWN; \
|
||||
} \
|
||||
catch (ivx::WrapperError & e) \
|
||||
{ \
|
||||
PRINT_HALERR_MSG(wrapper); \
|
||||
return CV_HAL_ERROR_UNKNOWN; \
|
||||
} \
|
||||
return CV_HAL_ERROR_OK; \
|
||||
}
|
||||
|
||||
OVX_BINARY_OP(add, { ivx::IVX_CHECK_STATUS(vxuAdd(ctx, ia, ib, VX_CONVERT_POLICY_SATURATE, ic)); }, VX_KERNEL_ADD)
|
||||
OVX_BINARY_OP(sub, { ivx::IVX_CHECK_STATUS(vxuSubtract(ctx, ia, ib, VX_CONVERT_POLICY_SATURATE, ic)); }, VX_KERNEL_SUBTRACT)
|
||||
|
||||
OVX_BINARY_OP(absdiff, { ivx::IVX_CHECK_STATUS(vxuAbsDiff(ctx, ia, ib, ic)); }, VX_KERNEL_ABSDIFF)
|
||||
|
||||
OVX_BINARY_OP(and, { ivx::IVX_CHECK_STATUS(vxuAnd(ctx, ia, ib, ic)); }, VX_KERNEL_AND)
|
||||
OVX_BINARY_OP(or , { ivx::IVX_CHECK_STATUS(vxuOr(ctx, ia, ib, ic)); }, VX_KERNEL_OR)
|
||||
OVX_BINARY_OP(xor, { ivx::IVX_CHECK_STATUS(vxuXor(ctx, ia, ib, ic)); }, VX_KERNEL_XOR)
|
||||
|
||||
template <typename T>
|
||||
int ovx_hal_mul(const T *a, size_t astep, const T *b, size_t bstep, T *c, size_t cstep, int w, int h, double scale)
|
||||
{
|
||||
if(scale == 1.0 || sizeof(T) > 1 ?
|
||||
skipSmallImages<VX_KERNEL_ADD>(w, h) : /*actually it could be any kernel with generic minimum size*/
|
||||
skipSmallImages<VX_KERNEL_MULTIPLY>(w, h) )
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
if (dimTooBig(w) || dimTooBig(h))
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
refineStep(w, h, ivx::TypeToEnum<T>::imgType, astep);
|
||||
refineStep(w, h, ivx::TypeToEnum<T>::imgType, bstep);
|
||||
refineStep(w, h, ivx::TypeToEnum<T>::imgType, cstep);
|
||||
#ifdef _WIN32
|
||||
const float MAGIC_SCALE = 0x0.01010102p0;
|
||||
#else
|
||||
const float MAGIC_SCALE = 0x1.010102p-8;
|
||||
#endif
|
||||
try
|
||||
{
|
||||
int rounding_policy = VX_ROUND_POLICY_TO_ZERO;
|
||||
float fscale = (float)scale;
|
||||
if (fabs(fscale - MAGIC_SCALE) > FLT_EPSILON)
|
||||
{
|
||||
int exp = 0;
|
||||
double significand = frexp(fscale, &exp);
|
||||
if ((significand != 0.5) || (exp > 1) || (exp < -14))
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
else
|
||||
{
|
||||
fscale = MAGIC_SCALE;
|
||||
rounding_policy = VX_ROUND_POLICY_TO_NEAREST_EVEN;// That's the only rounding that MUST be supported for 1/255 scale
|
||||
}
|
||||
ivx::Context ctx = getOpenVXHALContext();
|
||||
vxImage
|
||||
ia = ivx::Image::createFromHandle(ctx, ivx::TypeToEnum<T>::imgType,
|
||||
ivx::Image::createAddressing(w, h, sizeof(T), (vx_int32)(astep)), (void*)a),
|
||||
ib = ivx::Image::createFromHandle(ctx, ivx::TypeToEnum<T>::imgType,
|
||||
ivx::Image::createAddressing(w, h, sizeof(T), (vx_int32)(bstep)), (void*)b),
|
||||
ic = ivx::Image::createFromHandle(ctx, ivx::TypeToEnum<T>::imgType,
|
||||
ivx::Image::createAddressing(w, h, sizeof(T), (vx_int32)(cstep)), (void*)c);
|
||||
ivx::IVX_CHECK_STATUS(vxuMultiply(ctx, ia, ib, fscale, VX_CONVERT_POLICY_SATURATE, rounding_policy, ic));
|
||||
}
|
||||
catch (ivx::RuntimeError & e)
|
||||
{
|
||||
PRINT_HALERR_MSG(runtime);
|
||||
return CV_HAL_ERROR_UNKNOWN;
|
||||
}
|
||||
catch (ivx::WrapperError & e)
|
||||
{
|
||||
PRINT_HALERR_MSG(wrapper);
|
||||
return CV_HAL_ERROR_UNKNOWN;
|
||||
}
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
|
||||
template int ovx_hal_add<uchar>(const uchar *a, size_t astep, const uchar *b, size_t bstep, uchar *c, size_t cstep, int w, int h);
|
||||
template int ovx_hal_add<short>(const short *a, size_t astep, const short *b, size_t bstep, short *c, size_t cstep, int w, int h);
|
||||
template int ovx_hal_sub<uchar>(const uchar *a, size_t astep, const uchar *b, size_t bstep, uchar *c, size_t cstep, int w, int h);
|
||||
template int ovx_hal_sub<short>(const short *a, size_t astep, const short *b, size_t bstep, short *c, size_t cstep, int w, int h);
|
||||
|
||||
template int ovx_hal_absdiff<uchar>(const uchar *a, size_t astep, const uchar *b, size_t bstep, uchar *c, size_t cstep, int w, int h);
|
||||
template int ovx_hal_absdiff<short>(const short *a, size_t astep, const short *b, size_t bstep, short *c, size_t cstep, int w, int h);
|
||||
|
||||
template int ovx_hal_and<uchar>(const uchar *a, size_t astep, const uchar *b, size_t bstep, uchar *c, size_t cstep, int w, int h);
|
||||
template int ovx_hal_or<uchar>(const uchar *a, size_t astep, const uchar *b, size_t bstep, uchar *c, size_t cstep, int w, int h);
|
||||
template int ovx_hal_xor<uchar>(const uchar *a, size_t astep, const uchar *b, size_t bstep, uchar *c, size_t cstep, int w, int h);
|
||||
|
||||
template int ovx_hal_mul<uchar>(const uchar *a, size_t astep, const uchar *b, size_t bstep, uchar *c, size_t cstep, int w, int h, double scale);
|
||||
template int ovx_hal_mul<short>(const short *a, size_t astep, const short *b, size_t bstep, short *c, size_t cstep, int w, int h, double scale);
|
||||
|
||||
int ovx_hal_not(const uchar *a, size_t astep, uchar *c, size_t cstep, int w, int h)
|
||||
{
|
||||
if (skipSmallImages<VX_KERNEL_NOT>(w, h))
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
if (dimTooBig(w) || dimTooBig(h))
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
refineStep(w, h, VX_DF_IMAGE_U8, astep);
|
||||
refineStep(w, h, VX_DF_IMAGE_U8, cstep);
|
||||
try
|
||||
{
|
||||
ivx::Context ctx = getOpenVXHALContext();
|
||||
vxImage
|
||||
ia = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8,
|
||||
ivx::Image::createAddressing(w, h, 1, (vx_int32)(astep)), (void*)a),
|
||||
ic = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8,
|
||||
ivx::Image::createAddressing(w, h, 1, (vx_int32)(cstep)), (void*)c);
|
||||
ivx::IVX_CHECK_STATUS(vxuNot(ctx, ia, ic));
|
||||
}
|
||||
catch (ivx::RuntimeError & e)
|
||||
{
|
||||
PRINT_HALERR_MSG(runtime);
|
||||
return CV_HAL_ERROR_UNKNOWN;
|
||||
}
|
||||
catch (ivx::WrapperError & e)
|
||||
{
|
||||
PRINT_HALERR_MSG(wrapper);
|
||||
return CV_HAL_ERROR_UNKNOWN;
|
||||
}
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
|
||||
int ovx_hal_merge8u(const uchar **src_data, uchar *dst_data, int len, int cn)
|
||||
{
|
||||
if (skipSmallImages<VX_KERNEL_CHANNEL_COMBINE>(len, 1))
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
if (dimTooBig(len))
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
if (cn != 3 && cn != 4)
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
try
|
||||
{
|
||||
ivx::Context ctx = getOpenVXHALContext();
|
||||
vxImage
|
||||
ia = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8,
|
||||
ivx::Image::createAddressing(len, 1, 1, (vx_int32)(len)), (void*)src_data[0]),
|
||||
ib = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8,
|
||||
ivx::Image::createAddressing(len, 1, 1, (vx_int32)(len)), (void*)src_data[1]),
|
||||
ic = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8,
|
||||
ivx::Image::createAddressing(len, 1, 1, (vx_int32)(len)), (void*)src_data[2]),
|
||||
id = ivx::Image::createFromHandle(ctx, cn == 4 ? VX_DF_IMAGE_RGBX : VX_DF_IMAGE_RGB,
|
||||
ivx::Image::createAddressing(len, 1, cn, (vx_int32)(len*cn)), (void*)dst_data);
|
||||
ivx::IVX_CHECK_STATUS(vxuChannelCombine(ctx, ia, ib, ic,
|
||||
cn == 4 ? (vx_image)(ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8,
|
||||
ivx::Image::createAddressing(len, 1, 1, (vx_int32)(len)), (void*)src_data[3])) : NULL,
|
||||
id));
|
||||
}
|
||||
catch (ivx::RuntimeError & e)
|
||||
{
|
||||
PRINT_HALERR_MSG(runtime);
|
||||
return CV_HAL_ERROR_UNKNOWN;
|
||||
}
|
||||
catch (ivx::WrapperError & e)
|
||||
{
|
||||
PRINT_HALERR_MSG(wrapper);
|
||||
return CV_HAL_ERROR_UNKNOWN;
|
||||
}
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
|
||||
int ovx_hal_resize(int atype, const uchar *a, size_t astep, int aw, int ah, uchar *b, size_t bstep, int bw, int bh, double inv_scale_x, double inv_scale_y, int interpolation)
|
||||
{
|
||||
if (skipSmallImages<VX_KERNEL_SCALE_IMAGE>(aw, ah))
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
if (dimTooBig(aw) || dimTooBig(ah) || dimTooBig(bw) || dimTooBig(bh))
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
refineStep(aw, ah, VX_DF_IMAGE_U8, astep);
|
||||
refineStep(bw, bh, VX_DF_IMAGE_U8, bstep);
|
||||
try
|
||||
{
|
||||
ivx::Context ctx = getOpenVXHALContext();
|
||||
vxImage
|
||||
ia = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8,
|
||||
ivx::Image::createAddressing(aw, ah, 1, (vx_int32)(astep)), (void*)a),
|
||||
ib = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8,
|
||||
ivx::Image::createAddressing(bw, bh, 1, (vx_int32)(bstep)), (void*)b);
|
||||
|
||||
if (!((atype == CV_8UC1 || atype == CV_8SC1) &&
|
||||
inv_scale_x > 0 && inv_scale_y > 0 &&
|
||||
(bw - 0.5) / inv_scale_x - 0.5 < aw && (bh - 0.5) / inv_scale_y - 0.5 < ah &&
|
||||
(bw + 0.5) / inv_scale_x + 0.5 >= aw && (bh + 0.5) / inv_scale_y + 0.5 >= ah &&
|
||||
std::abs(bw / inv_scale_x - aw) < 0.1 && std::abs(bh / inv_scale_y - ah) < 0.1))
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
int mode;
|
||||
if (interpolation == CV_HAL_INTER_LINEAR)
|
||||
{
|
||||
mode = VX_INTERPOLATION_BILINEAR;
|
||||
if (inv_scale_x > 1 || inv_scale_y > 1)
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
else if (interpolation == CV_HAL_INTER_AREA)
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED; //mode = VX_INTERPOLATION_AREA;
|
||||
else if (interpolation == CV_HAL_INTER_NEAREST)
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED; //mode = VX_INTERPOLATION_NEAREST_NEIGHBOR;
|
||||
else
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
ivx::IVX_CHECK_STATUS(vxuScaleImage(ctx, ia, ib, mode));
|
||||
}
|
||||
catch (ivx::RuntimeError & e)
|
||||
{
|
||||
PRINT_HALERR_MSG(runtime);
|
||||
return CV_HAL_ERROR_UNKNOWN;
|
||||
}
|
||||
catch (ivx::WrapperError & e)
|
||||
{
|
||||
PRINT_HALERR_MSG(wrapper);
|
||||
return CV_HAL_ERROR_UNKNOWN;
|
||||
}
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
|
||||
int ovx_hal_warpAffine(int atype, const uchar *a, size_t astep, int aw, int ah, uchar *b, size_t bstep, int bw, int bh, const double M[6], int interpolation, int borderType, const double borderValue[4])
|
||||
{
|
||||
if (skipSmallImages<VX_KERNEL_WARP_AFFINE>(aw, ah))
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
if (dimTooBig(aw) || dimTooBig(ah) || dimTooBig(bw) || dimTooBig(bh))
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
refineStep(aw, ah, VX_DF_IMAGE_U8, astep);
|
||||
refineStep(bw, bh, VX_DF_IMAGE_U8, bstep);
|
||||
try
|
||||
{
|
||||
ivx::Context ctx = getOpenVXHALContext();
|
||||
vxImage
|
||||
ia = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8,
|
||||
ivx::Image::createAddressing(aw, ah, 1, (vx_int32)(astep)), (void*)a),
|
||||
ib = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8,
|
||||
ivx::Image::createAddressing(bw, bh, 1, (vx_int32)(bstep)), (void*)b);
|
||||
|
||||
if (!(atype == CV_8UC1 || atype == CV_8SC1))
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
if(borderType != CV_HAL_BORDER_CONSTANT) // Neither 1.0 nor 1.1 OpenVX support BORDER_REPLICATE for warpings
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
int mode;
|
||||
if (interpolation == CV_HAL_INTER_LINEAR)
|
||||
mode = VX_INTERPOLATION_BILINEAR;
|
||||
//AREA interpolation is unsupported
|
||||
//else if (interpolation == CV_HAL_INTER_AREA)
|
||||
// mode = VX_INTERPOLATION_AREA;
|
||||
else if (interpolation == CV_HAL_INTER_NEAREST)
|
||||
mode = VX_INTERPOLATION_NEAREST_NEIGHBOR;
|
||||
else
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
std::vector<float> data;
|
||||
data.reserve(6);
|
||||
for (int j = 0; j < 3; ++j)
|
||||
for (int i = 0; i < 2; ++i)
|
||||
data.push_back((float)(M[i * 3 + j]));
|
||||
|
||||
ivx::Matrix mtx = ivx::Matrix::create(ctx, VX_TYPE_FLOAT32, 2, 3);
|
||||
mtx.copyFrom(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::IVX_CHECK_STATUS(vxuWarpAffine(ctx, ia, mtx, mode, ib));
|
||||
ctx.setImmediateBorder(prevBorder);
|
||||
}
|
||||
catch (ivx::RuntimeError & e)
|
||||
{
|
||||
PRINT_HALERR_MSG(runtime);
|
||||
return CV_HAL_ERROR_UNKNOWN;
|
||||
}
|
||||
catch (ivx::WrapperError & e)
|
||||
{
|
||||
PRINT_HALERR_MSG(wrapper);
|
||||
return CV_HAL_ERROR_UNKNOWN;
|
||||
}
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
|
||||
int ovx_hal_warpPerspective(int atype, const uchar *a, size_t astep, int aw, int ah, uchar *b, size_t bstep, int bw, int bh, const double M[9], int interpolation, int borderType, const double borderValue[4])
|
||||
{
|
||||
if (skipSmallImages<VX_KERNEL_WARP_PERSPECTIVE>(aw, ah))
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
if (dimTooBig(aw) || dimTooBig(ah) || dimTooBig(bw) || dimTooBig(bh))
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
refineStep(aw, ah, VX_DF_IMAGE_U8, astep);
|
||||
refineStep(bw, bh, VX_DF_IMAGE_U8, bstep);
|
||||
try
|
||||
{
|
||||
ivx::Context ctx = getOpenVXHALContext();
|
||||
vxImage
|
||||
ia = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8,
|
||||
ivx::Image::createAddressing(aw, ah, 1, (vx_int32)(astep)), (void*)a),
|
||||
ib = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8,
|
||||
ivx::Image::createAddressing(bw, bh, 1, (vx_int32)(bstep)), (void*)b);
|
||||
|
||||
if (!(atype == CV_8UC1 || atype == CV_8SC1))
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
if (borderType != CV_HAL_BORDER_CONSTANT) // Neither 1.0 nor 1.1 OpenVX support BORDER_REPLICATE for warpings
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
int mode;
|
||||
if (interpolation == CV_HAL_INTER_LINEAR)
|
||||
mode = VX_INTERPOLATION_BILINEAR;
|
||||
//AREA interpolation is unsupported
|
||||
//else if (interpolation == CV_HAL_INTER_AREA)
|
||||
// mode = VX_INTERPOLATION_AREA;
|
||||
else if (interpolation == CV_HAL_INTER_NEAREST)
|
||||
mode = VX_INTERPOLATION_NEAREST_NEIGHBOR;
|
||||
else
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
std::vector<float> data;
|
||||
data.reserve(9);
|
||||
for (int j = 0; j < 3; ++j)
|
||||
for (int i = 0; i < 3; ++i)
|
||||
data.push_back((float)(M[i * 3 + j]));
|
||||
|
||||
ivx::Matrix mtx = ivx::Matrix::create(ctx, VX_TYPE_FLOAT32, 3, 3);
|
||||
mtx.copyFrom(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::IVX_CHECK_STATUS(vxuWarpPerspective(ctx, ia, mtx, mode, ib));
|
||||
ctx.setImmediateBorder(prevBorder);
|
||||
}
|
||||
catch (ivx::RuntimeError & e)
|
||||
{
|
||||
PRINT_HALERR_MSG(runtime);
|
||||
return CV_HAL_ERROR_UNKNOWN;
|
||||
}
|
||||
catch (ivx::WrapperError & e)
|
||||
{
|
||||
PRINT_HALERR_MSG(wrapper);
|
||||
return CV_HAL_ERROR_UNKNOWN;
|
||||
}
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
|
||||
struct cvhalFilter2D;
|
||||
|
||||
struct FilterCtx
|
||||
{
|
||||
ivx::Convolution cnv;
|
||||
int dst_type;
|
||||
ivx::border_t border;
|
||||
FilterCtx(ivx::Context &ctx, const std::vector<short> data, int w, int h, int _dst_type, ivx::border_t & _border) :
|
||||
cnv(ivx::Convolution::create(ctx, w, h)), dst_type(_dst_type), border(_border) {
|
||||
cnv.copyFrom(data);
|
||||
}
|
||||
};
|
||||
|
||||
int ovx_hal_filterInit(cvhalFilter2D **filter_context, uchar *kernel_data, size_t kernel_step, int kernel_type, int kernel_width, int kernel_height,
|
||||
int, int, int src_type, int dst_type, int borderType, double delta, int anchor_x, int anchor_y, bool allowSubmatrix, bool allowInplace)
|
||||
{
|
||||
if (!filter_context || !kernel_data || allowSubmatrix || allowInplace || delta != 0 ||
|
||||
src_type != CV_8UC1 || (dst_type != CV_8UC1 && dst_type != CV_16SC1) ||
|
||||
kernel_width % 2 == 0 || kernel_height % 2 == 0 || anchor_x != kernel_width / 2 || anchor_y != kernel_height / 2)
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
ivx::border_t border;
|
||||
switch (borderType)
|
||||
{
|
||||
case CV_HAL_BORDER_CONSTANT:
|
||||
setConstantBorder(border, 0);
|
||||
break;
|
||||
case CV_HAL_BORDER_REPLICATE:
|
||||
border.mode = VX_BORDER_REPLICATE;
|
||||
break;
|
||||
default:
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
ivx::Context ctx = getOpenVXHALContext();
|
||||
|
||||
std::vector<short> data;
|
||||
data.reserve(kernel_width*kernel_height);
|
||||
switch (kernel_type)
|
||||
{
|
||||
case CV_8UC1:
|
||||
for (int j = 0; j < kernel_height; ++j)
|
||||
{
|
||||
uchar * row = (uchar*)(kernel_data + kernel_step*j);
|
||||
for (int i = 0; i < kernel_width; ++i)
|
||||
data.push_back(row[i]);
|
||||
}
|
||||
break;
|
||||
case CV_8SC1:
|
||||
for (int j = 0; j < kernel_height; ++j)
|
||||
{
|
||||
schar * row = (schar*)(kernel_data + kernel_step*j);
|
||||
for (int i = 0; i < kernel_width; ++i)
|
||||
data.push_back(row[i]);
|
||||
}
|
||||
break;
|
||||
case CV_16SC1:
|
||||
for (int j = 0; j < kernel_height; ++j)
|
||||
{
|
||||
short * row = (short*)(kernel_data + kernel_step*j);
|
||||
for (int i = 0; i < kernel_width; ++i)
|
||||
data.push_back(row[i]);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
FilterCtx* cnv = new FilterCtx(ctx, data, kernel_width, kernel_height, dst_type, border);
|
||||
if (!cnv)
|
||||
return CV_HAL_ERROR_UNKNOWN;
|
||||
|
||||
*filter_context = (cvhalFilter2D*)(cnv);
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
|
||||
int ovx_hal_filterFree(cvhalFilter2D *filter_context)
|
||||
{
|
||||
if (filter_context)
|
||||
{
|
||||
delete (FilterCtx*)filter_context;
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return CV_HAL_ERROR_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
int ovx_hal_filter(cvhalFilter2D *filter_context, uchar *a, size_t astep, uchar *b, size_t bstep, int w, int h, int, int, int, int)
|
||||
{
|
||||
if (skipSmallImages<VX_KERNEL_CUSTOM_CONVOLUTION>(w, h))
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
if (dimTooBig(w) || dimTooBig(h))
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
try
|
||||
{
|
||||
FilterCtx* cnv = (FilterCtx*)filter_context;
|
||||
if (!cnv)
|
||||
throw ivx::WrapperError("Bad HAL context");
|
||||
refineStep(w, h, VX_DF_IMAGE_U8, astep);
|
||||
refineStep(w, h, cnv->dst_type == CV_16SC1 ? VX_DF_IMAGE_S16 : VX_DF_IMAGE_U8, bstep);
|
||||
|
||||
ivx::Context ctx = getOpenVXHALContext();
|
||||
vxImage
|
||||
ia = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8,
|
||||
ivx::Image::createAddressing(w, h, 1, (vx_int32)(astep)), (void*)a),
|
||||
ib = ivx::Image::createFromHandle(ctx, cnv->dst_type == CV_16SC1 ? VX_DF_IMAGE_S16 : VX_DF_IMAGE_U8,
|
||||
ivx::Image::createAddressing(w, h, cnv->dst_type == CV_16SC1 ? 2 : 1, (vx_int32)(bstep)), (void*)b);
|
||||
|
||||
//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(cnv->border);
|
||||
ivx::IVX_CHECK_STATUS(vxuConvolve(ctx, ia, cnv->cnv, ib));
|
||||
ctx.setImmediateBorder(prevBorder);
|
||||
}
|
||||
catch (ivx::RuntimeError & e)
|
||||
{
|
||||
PRINT_HALERR_MSG(runtime);
|
||||
return CV_HAL_ERROR_UNKNOWN;
|
||||
}
|
||||
catch (ivx::WrapperError & e)
|
||||
{
|
||||
PRINT_HALERR_MSG(wrapper);
|
||||
return CV_HAL_ERROR_UNKNOWN;
|
||||
}
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
|
||||
int ovx_hal_sepFilterInit(cvhalFilter2D **filter_context, int src_type, int dst_type,
|
||||
int kernel_type, uchar *kernelx_data, int kernelx_length, uchar *kernely_data, int kernely_length,
|
||||
int anchor_x, int anchor_y, double delta, int borderType)
|
||||
{
|
||||
if (!filter_context || !kernelx_data || !kernely_data || delta != 0 ||
|
||||
src_type != CV_8UC1 || (dst_type != CV_8UC1 && dst_type != CV_16SC1) ||
|
||||
kernelx_length != 3 || kernely_length != 3 || anchor_x != 1 || anchor_y != 1)
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
ivx::border_t border;
|
||||
switch (borderType)
|
||||
{
|
||||
case CV_HAL_BORDER_CONSTANT:
|
||||
setConstantBorder(border, 0);
|
||||
break;
|
||||
case CV_HAL_BORDER_REPLICATE:
|
||||
border.mode = VX_BORDER_REPLICATE;
|
||||
break;
|
||||
default:
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
ivx::Context ctx = getOpenVXHALContext();
|
||||
|
||||
//At the moment OpenVX doesn't support separable filters natively so combine kernels to generic convolution
|
||||
std::vector<short> data;
|
||||
data.reserve(kernelx_length*kernely_length);
|
||||
switch (kernel_type)
|
||||
{
|
||||
case CV_8UC1:
|
||||
for (int j = 0; j < kernely_length; ++j)
|
||||
for (int i = 0; i < kernelx_length; ++i)
|
||||
data.push_back((short)(kernely_data[j]) * kernelx_data[i]);
|
||||
break;
|
||||
case CV_8SC1:
|
||||
for (int j = 0; j < kernely_length; ++j)
|
||||
for (int i = 0; i < kernelx_length; ++i)
|
||||
data.push_back((short)(((schar*)kernely_data)[j]) * ((schar*)kernelx_data)[i]);
|
||||
break;
|
||||
default:
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
FilterCtx* cnv = new FilterCtx(ctx, data, kernelx_length, kernely_length, dst_type, border);
|
||||
if (!cnv)
|
||||
return CV_HAL_ERROR_UNKNOWN;
|
||||
|
||||
*filter_context = (cvhalFilter2D*)(cnv);
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
|
||||
#if VX_VERSION > VX_VERSION_1_0
|
||||
|
||||
struct MorphCtx
|
||||
{
|
||||
ivx::Matrix mask;
|
||||
int operation;
|
||||
ivx::border_t border;
|
||||
MorphCtx(ivx::Context &ctx, const std::vector<vx_uint8> data, int w, int h, int _operation, ivx::border_t & _border) :
|
||||
mask(ivx::Matrix::create(ctx, ivx::TypeToEnum<vx_uint8>::value, w, h)), operation(_operation), border(_border) {
|
||||
mask.copyFrom(data);
|
||||
}
|
||||
};
|
||||
|
||||
int ovx_hal_morphInit(cvhalFilter2D **filter_context, int operation, int src_type, int dst_type, int, int,
|
||||
int kernel_type, uchar *kernel_data, size_t kernel_step, int kernel_width, int kernel_height, int anchor_x, int anchor_y,
|
||||
int borderType, const double borderValue[4], int iterations, bool allowSubmatrix, bool allowInplace)
|
||||
{
|
||||
if (!filter_context || !kernel_data || allowSubmatrix || allowInplace || iterations != 1 ||
|
||||
src_type != CV_8UC1 || dst_type != CV_8UC1 ||
|
||||
kernel_width % 2 == 0 || kernel_height % 2 == 0 || anchor_x != kernel_width / 2 || anchor_y != kernel_height / 2)
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
ivx::border_t border;
|
||||
switch (borderType)
|
||||
{
|
||||
case CV_HAL_BORDER_CONSTANT:
|
||||
if (borderValue[0] == DBL_MAX && borderValue[1] == DBL_MAX && borderValue[2] == DBL_MAX && borderValue[3] == DBL_MAX)
|
||||
{
|
||||
if (operation == CV_HAL_MORPH_ERODE)
|
||||
setConstantBorder(border, UCHAR_MAX);
|
||||
else
|
||||
setConstantBorder(border, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
int rounded = (int)round(borderValue[0]);
|
||||
setConstantBorder(border, (vx_uint8)((unsigned)rounded <= UCHAR_MAX ? rounded : rounded > 0 ? UCHAR_MAX : 0));
|
||||
}
|
||||
break;
|
||||
case CV_HAL_BORDER_REPLICATE:
|
||||
border.mode = VX_BORDER_REPLICATE;
|
||||
break;
|
||||
default:
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
ivx::Context ctx = getOpenVXHALContext();
|
||||
|
||||
vx_size maxKernelDim = ctx.nonlinearMaxDimension();
|
||||
if ((vx_size)kernel_width > maxKernelDim || (vx_size)kernel_height > maxKernelDim)
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
std::vector<vx_uint8> kernel_mat;
|
||||
kernel_mat.reserve(kernel_width * kernel_height);
|
||||
switch (CV_MAT_DEPTH(kernel_type))
|
||||
{
|
||||
case CV_8U:
|
||||
case CV_8S:
|
||||
for (int j = 0; j < kernel_height; ++j)
|
||||
{
|
||||
uchar * kernel_row = kernel_data + j * kernel_step;
|
||||
for (int i = 0; i < kernel_width; ++i)
|
||||
kernel_mat.push_back(kernel_row[i] ? 255 : 0);
|
||||
}
|
||||
break;
|
||||
case CV_16U:
|
||||
case CV_16S:
|
||||
for (int j = 0; j < kernel_height; ++j)
|
||||
{
|
||||
short * kernel_row = (short*)(kernel_data + j * kernel_step);
|
||||
for (int i = 0; i < kernel_width; ++i)
|
||||
kernel_mat.push_back(kernel_row[i] ? 255 : 0);
|
||||
}
|
||||
break;
|
||||
case CV_32S:
|
||||
for (int j = 0; j < kernel_height; ++j)
|
||||
{
|
||||
int * kernel_row = (int*)(kernel_data + j * kernel_step);
|
||||
for (int i = 0; i < kernel_width; ++i)
|
||||
kernel_mat.push_back(kernel_row[i] ? 255 : 0);
|
||||
}
|
||||
break;
|
||||
case CV_32F:
|
||||
for (int j = 0; j < kernel_height; ++j)
|
||||
{
|
||||
float * kernel_row = (float*)(kernel_data + j * kernel_step);
|
||||
for (int i = 0; i < kernel_width; ++i)
|
||||
kernel_mat.push_back(kernel_row[i] ? 255 : 0);
|
||||
}
|
||||
break;
|
||||
case CV_64F:
|
||||
for (int j = 0; j < kernel_height; ++j)
|
||||
{
|
||||
double * kernel_row = (double*)(kernel_data + j * kernel_step);
|
||||
for (int i = 0; i < kernel_width; ++i)
|
||||
kernel_mat.push_back(kernel_row[i] ? 255 : 0);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
MorphCtx* mat;
|
||||
switch (operation)
|
||||
{
|
||||
case CV_HAL_MORPH_ERODE:
|
||||
mat = new MorphCtx(ctx, kernel_mat, kernel_width, kernel_height, VX_NONLINEAR_FILTER_MIN, border);
|
||||
break;
|
||||
case CV_HAL_MORPH_DILATE:
|
||||
mat = new MorphCtx(ctx, kernel_mat, kernel_width, kernel_height, VX_NONLINEAR_FILTER_MAX, border);
|
||||
break;
|
||||
default:
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
if (!mat)
|
||||
return CV_HAL_ERROR_UNKNOWN;
|
||||
|
||||
*filter_context = (cvhalFilter2D*)(mat);
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
|
||||
int ovx_hal_morphFree(cvhalFilter2D *filter_context)
|
||||
{
|
||||
if (filter_context)
|
||||
{
|
||||
delete (MorphCtx*)filter_context;
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return CV_HAL_ERROR_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
int ovx_hal_morph(cvhalFilter2D *filter_context, uchar *a, size_t astep, uchar *b, size_t bstep, int w, int h, int, int, int, int, int, int, int, int)
|
||||
{
|
||||
if (skipSmallImages<VX_KERNEL_DILATE_3x3>(w, h))//Actually it make sense to separate checks if implementations of dilation and erosion have different performance gain
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
if (dimTooBig(w) || dimTooBig(h))
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
refineStep(w, h, VX_DF_IMAGE_U8, astep);
|
||||
refineStep(w, h, VX_DF_IMAGE_U8, bstep);
|
||||
try
|
||||
{
|
||||
MorphCtx* mat = (MorphCtx*)filter_context;
|
||||
if (!mat)
|
||||
throw ivx::WrapperError("Bad HAL context");
|
||||
|
||||
ivx::Context ctx = getOpenVXHALContext();
|
||||
vxImage
|
||||
ia = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8,
|
||||
ivx::Image::createAddressing(w, h, 1, (vx_int32)(astep)), (void*)a),
|
||||
ib = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8,
|
||||
ivx::Image::createAddressing(w, h, 1, (vx_int32)(bstep)), (void*)b);
|
||||
|
||||
//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(mat->border);
|
||||
ivx::IVX_CHECK_STATUS(vxuNonLinearFilter(ctx, mat->operation, ia, mat->mask, ib));
|
||||
ctx.setImmediateBorder(prevBorder);
|
||||
}
|
||||
catch (ivx::RuntimeError & e)
|
||||
{
|
||||
PRINT_HALERR_MSG(runtime);
|
||||
return CV_HAL_ERROR_UNKNOWN;
|
||||
}
|
||||
catch (ivx::WrapperError & e)
|
||||
{
|
||||
PRINT_HALERR_MSG(wrapper);
|
||||
return CV_HAL_ERROR_UNKNOWN;
|
||||
}
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
|
||||
#endif // 1.0 guard
|
||||
|
||||
int ovx_hal_cvtBGRtoBGR(const uchar * a, size_t astep, uchar * b, size_t bstep, int w, int h, int depth, int acn, int bcn, bool swapBlue)
|
||||
{
|
||||
if (skipSmallImages<VX_KERNEL_COLOR_CONVERT>(w, h))
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
if (dimTooBig(w) || dimTooBig(h))
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
if (depth != CV_8U || swapBlue || acn == bcn || (acn != 3 && acn != 4) || (bcn != 3 && bcn != 4))
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
if (w & 1 || h & 1) // It's strange but sample implementation unable to convert odd sized images
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
refineStep(w, h, acn == 3 ? VX_DF_IMAGE_RGB : VX_DF_IMAGE_RGBX, astep);
|
||||
refineStep(w, h, bcn == 3 ? VX_DF_IMAGE_RGB : VX_DF_IMAGE_RGBX, bstep);
|
||||
try
|
||||
{
|
||||
ivx::Context ctx = getOpenVXHALContext();
|
||||
vxImage
|
||||
ia = ivx::Image::createFromHandle(ctx, acn == 3 ? VX_DF_IMAGE_RGB : VX_DF_IMAGE_RGBX,
|
||||
ivx::Image::createAddressing(w, h, acn, (vx_int32)astep), (void*)a),
|
||||
ib = ivx::Image::createFromHandle(ctx, bcn == 3 ? VX_DF_IMAGE_RGB : VX_DF_IMAGE_RGBX,
|
||||
ivx::Image::createAddressing(w, h, bcn, (vx_int32)bstep), b);
|
||||
ivx::IVX_CHECK_STATUS(vxuColorConvert(ctx, ia, ib));
|
||||
}
|
||||
catch (ivx::RuntimeError & e)
|
||||
{
|
||||
PRINT_HALERR_MSG(runtime);
|
||||
return CV_HAL_ERROR_UNKNOWN;
|
||||
}
|
||||
catch (ivx::WrapperError & e)
|
||||
{
|
||||
PRINT_HALERR_MSG(wrapper);
|
||||
return CV_HAL_ERROR_UNKNOWN;
|
||||
}
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
|
||||
int ovx_hal_cvtGraytoBGR(const uchar * a, size_t astep, uchar * b, size_t bstep, int w, int h, int depth, int bcn)
|
||||
{
|
||||
if (skipSmallImages<VX_KERNEL_CHANNEL_COMBINE>(w, h))
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
if (dimTooBig(w) || dimTooBig(h))
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
if (depth != CV_8U || (bcn != 3 && bcn != 4))
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
refineStep(w, h, VX_DF_IMAGE_U8, astep);
|
||||
refineStep(w, h, bcn == 3 ? VX_DF_IMAGE_RGB : VX_DF_IMAGE_RGBX, bstep);
|
||||
try
|
||||
{
|
||||
ivx::Context ctx = getOpenVXHALContext();
|
||||
ivx::Image
|
||||
ia = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8,
|
||||
ivx::Image::createAddressing(w, h, 1, (vx_int32)astep), const_cast<uchar*>(a)),
|
||||
ib = ivx::Image::createFromHandle(ctx, bcn == 3 ? VX_DF_IMAGE_RGB : VX_DF_IMAGE_RGBX,
|
||||
ivx::Image::createAddressing(w, h, bcn, (vx_int32)bstep), b);
|
||||
ivx::IVX_CHECK_STATUS(vxuChannelCombine(ctx, ia, ia, ia,
|
||||
bcn == 4 ? (vx_image)(ivx::Image::createUniform(ctx, w, h, VX_DF_IMAGE_U8, vx_uint8(255))) : NULL,
|
||||
ib));
|
||||
}
|
||||
catch (ivx::RuntimeError & e)
|
||||
{
|
||||
PRINT_HALERR_MSG(runtime);
|
||||
return CV_HAL_ERROR_UNKNOWN;
|
||||
}
|
||||
catch (ivx::WrapperError & e)
|
||||
{
|
||||
PRINT_HALERR_MSG(wrapper);
|
||||
return CV_HAL_ERROR_UNKNOWN;
|
||||
}
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
|
||||
int ovx_hal_cvtTwoPlaneYUVtoBGR(const uchar * a, size_t astep, uchar * b, size_t bstep, int w, int h, int bcn, bool swapBlue, int uIdx)
|
||||
{
|
||||
return ovx_hal_cvtTwoPlaneYUVtoBGREx(a, astep, a + h * astep, astep, b, bstep, w, h, bcn, swapBlue, uIdx);
|
||||
}
|
||||
|
||||
int ovx_hal_cvtTwoPlaneYUVtoBGREx(const uchar * a, size_t astep, const uchar * b, size_t bstep, uchar * c, size_t cstep, int w, int h, int bcn, bool swapBlue, int uIdx)
|
||||
{
|
||||
if (skipSmallImages<VX_KERNEL_COLOR_CONVERT>(w, h))
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
if (dimTooBig(w) || dimTooBig(h))
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
if (!swapBlue || (bcn != 3 && bcn != 4))
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
if (w & 1 || h & 1) // It's not described in spec but sample implementation unable to convert odd sized images
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
try
|
||||
{
|
||||
ivx::Context ctx = getOpenVXHALContext();
|
||||
|
||||
std::vector<vx_imagepatch_addressing_t> addr;
|
||||
std::vector<void *> ptrs;
|
||||
addr.push_back(ivx::Image::createAddressing(w, h, 1, (vx_int32)astep));
|
||||
ptrs.push_back((void*)a);
|
||||
addr.push_back(ivx::Image::createAddressing(w / 2, h / 2, 2, (vx_int32)bstep));
|
||||
ptrs.push_back((void*)b);
|
||||
|
||||
vxImage
|
||||
ia = ivx::Image::createFromHandle(ctx, uIdx ? VX_DF_IMAGE_NV21 : VX_DF_IMAGE_NV12, addr, ptrs);
|
||||
if (ia.range() == VX_CHANNEL_RANGE_FULL)
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED; // OpenCV store NV12/NV21 as RANGE_RESTRICTED while OpenVX expect RANGE_FULL
|
||||
vxImage
|
||||
ib = ivx::Image::createFromHandle(ctx, bcn == 3 ? VX_DF_IMAGE_RGB : VX_DF_IMAGE_RGBX,
|
||||
ivx::Image::createAddressing(w, h, bcn, (vx_int32)cstep), c);
|
||||
ivx::IVX_CHECK_STATUS(vxuColorConvert(ctx, ia, ib));
|
||||
}
|
||||
catch (ivx::RuntimeError & e)
|
||||
{
|
||||
PRINT_HALERR_MSG(runtime);
|
||||
return CV_HAL_ERROR_UNKNOWN;
|
||||
}
|
||||
catch (ivx::WrapperError & e)
|
||||
{
|
||||
PRINT_HALERR_MSG(wrapper);
|
||||
return CV_HAL_ERROR_UNKNOWN;
|
||||
}
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
|
||||
int ovx_hal_cvtThreePlaneYUVtoBGR(const uchar * a, size_t astep, uchar * b, size_t bstep, int w, int h, int bcn, bool swapBlue, int uIdx)
|
||||
{
|
||||
if (skipSmallImages<VX_KERNEL_COLOR_CONVERT>(w, h))
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
if (dimTooBig(w) || dimTooBig(h))
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
if (!swapBlue || (bcn != 3 && bcn != 4) || uIdx || (size_t)w / 2 != astep - (size_t)w / 2)
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
if (w & 1 || h & 1) // It's not described in spec but sample implementation unable to convert odd sized images
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
refineStep(w, h, VX_DF_IMAGE_IYUV, astep);
|
||||
refineStep(w, h, bcn == 3 ? VX_DF_IMAGE_RGB : VX_DF_IMAGE_RGBX, bstep);
|
||||
try
|
||||
{
|
||||
ivx::Context ctx = getOpenVXHALContext();
|
||||
|
||||
std::vector<vx_imagepatch_addressing_t> addr;
|
||||
std::vector<void *> ptrs;
|
||||
addr.push_back(ivx::Image::createAddressing(w, h, 1, (vx_int32)astep));
|
||||
ptrs.push_back((void*)a);
|
||||
addr.push_back(ivx::Image::createAddressing(w / 2, h / 2, 1, w / 2));
|
||||
ptrs.push_back((void*)(a + h * astep));
|
||||
if (addr[1].dim_x != (astep - addr[1].dim_x))
|
||||
throw ivx::WrapperError("UV planes use variable stride");
|
||||
addr.push_back(ivx::Image::createAddressing(w / 2, h / 2, 1, w / 2));
|
||||
ptrs.push_back((void*)(a + h * astep + addr[1].dim_y * addr[1].stride_y));
|
||||
|
||||
vxImage
|
||||
ia = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_IYUV, addr, ptrs);
|
||||
if (ia.range() == VX_CHANNEL_RANGE_FULL)
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED; // OpenCV store NV12/NV21 as RANGE_RESTRICTED while OpenVX expect RANGE_FULL
|
||||
vxImage
|
||||
ib = ivx::Image::createFromHandle(ctx, bcn == 3 ? VX_DF_IMAGE_RGB : VX_DF_IMAGE_RGBX,
|
||||
ivx::Image::createAddressing(w, h, bcn, (vx_int32)bstep), b);
|
||||
ivx::IVX_CHECK_STATUS(vxuColorConvert(ctx, ia, ib));
|
||||
}
|
||||
catch (ivx::RuntimeError & e)
|
||||
{
|
||||
PRINT_HALERR_MSG(runtime);
|
||||
return CV_HAL_ERROR_UNKNOWN;
|
||||
}
|
||||
catch (ivx::WrapperError & e)
|
||||
{
|
||||
PRINT_HALERR_MSG(wrapper);
|
||||
return CV_HAL_ERROR_UNKNOWN;
|
||||
}
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
|
||||
int ovx_hal_cvtBGRtoThreePlaneYUV(const uchar * a, size_t astep, uchar * b, size_t bstep, int w, int h, int acn, bool swapBlue, int uIdx)
|
||||
{
|
||||
if (skipSmallImages<VX_KERNEL_COLOR_CONVERT>(w, h))
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
if (dimTooBig(w) || dimTooBig(h))
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
if (!swapBlue || (acn != 3 && acn != 4) || uIdx || (size_t)w / 2 != bstep - (size_t)w / 2)
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
if (w & 1 || h & 1) // It's not described in spec but sample implementation unable to convert odd sized images
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
refineStep(w, h, acn == 3 ? VX_DF_IMAGE_RGB : VX_DF_IMAGE_RGBX, astep);
|
||||
refineStep(w, h, VX_DF_IMAGE_IYUV, bstep);
|
||||
try
|
||||
{
|
||||
ivx::Context ctx = getOpenVXHALContext();
|
||||
vxImage
|
||||
ia = ivx::Image::createFromHandle(ctx, acn == 3 ? VX_DF_IMAGE_RGB : VX_DF_IMAGE_RGBX,
|
||||
ivx::Image::createAddressing(w, h, acn, (vx_int32)astep), (void*)a);
|
||||
|
||||
std::vector<vx_imagepatch_addressing_t> addr;
|
||||
std::vector<void *> ptrs;
|
||||
addr.push_back(ivx::Image::createAddressing(w, h, 1, (vx_int32)bstep));
|
||||
ptrs.push_back((void*)b);
|
||||
addr.push_back(ivx::Image::createAddressing(w / 2, h / 2, 1, w / 2));
|
||||
ptrs.push_back((void*)(b + h * bstep));
|
||||
if (addr[1].dim_x != (bstep - addr[1].dim_x))
|
||||
throw ivx::WrapperError("UV planes use variable stride");
|
||||
addr.push_back(ivx::Image::createAddressing(w / 2, h / 2, 1, w / 2));
|
||||
ptrs.push_back((void*)(b + h * bstep + addr[1].dim_y * addr[1].stride_y));
|
||||
|
||||
vxImage
|
||||
ib = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_IYUV, addr, ptrs);
|
||||
ivx::IVX_CHECK_STATUS(vxuColorConvert(ctx, ia, ib));
|
||||
}
|
||||
catch (ivx::RuntimeError & e)
|
||||
{
|
||||
PRINT_HALERR_MSG(runtime);
|
||||
return CV_HAL_ERROR_UNKNOWN;
|
||||
}
|
||||
catch (ivx::WrapperError & e)
|
||||
{
|
||||
PRINT_HALERR_MSG(wrapper);
|
||||
return CV_HAL_ERROR_UNKNOWN;
|
||||
}
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
|
||||
int ovx_hal_cvtOnePlaneYUVtoBGR(const uchar * a, size_t astep, uchar * b, size_t bstep, int w, int h, int bcn, bool swapBlue, int uIdx, int ycn)
|
||||
{
|
||||
if (skipSmallImages<VX_KERNEL_COLOR_CONVERT>(w, h))
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
if (dimTooBig(w) || dimTooBig(h))
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
if (!swapBlue || (bcn != 3 && bcn != 4) || uIdx)
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
if (w & 1) // It's not described in spec but sample implementation unable to convert odd sized images
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
refineStep(w, h, ycn ? VX_DF_IMAGE_UYVY : VX_DF_IMAGE_YUYV, astep);
|
||||
refineStep(w, h, bcn == 3 ? VX_DF_IMAGE_RGB : VX_DF_IMAGE_RGBX, bstep);
|
||||
try
|
||||
{
|
||||
ivx::Context ctx = getOpenVXHALContext();
|
||||
vxImage
|
||||
ia = ivx::Image::createFromHandle(ctx, ycn ? VX_DF_IMAGE_UYVY : VX_DF_IMAGE_YUYV,
|
||||
ivx::Image::createAddressing(w, h, 2, (vx_int32)astep), (void*)a);
|
||||
if (ia.range() == VX_CHANNEL_RANGE_FULL)
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED; // OpenCV store NV12/NV21 as RANGE_RESTRICTED while OpenVX expect RANGE_FULL
|
||||
vxImage
|
||||
ib = ivx::Image::createFromHandle(ctx, bcn == 3 ? VX_DF_IMAGE_RGB : VX_DF_IMAGE_RGBX,
|
||||
ivx::Image::createAddressing(w, h, bcn, (vx_int32)bstep), b);
|
||||
ivx::IVX_CHECK_STATUS(vxuColorConvert(ctx, ia, ib));
|
||||
}
|
||||
catch (ivx::RuntimeError & e)
|
||||
{
|
||||
PRINT_HALERR_MSG(runtime);
|
||||
return CV_HAL_ERROR_UNKNOWN;
|
||||
}
|
||||
catch (ivx::WrapperError & e)
|
||||
{
|
||||
PRINT_HALERR_MSG(wrapper);
|
||||
return CV_HAL_ERROR_UNKNOWN;
|
||||
}
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
|
||||
int ovx_hal_integral(int depth, int sdepth, int, const uchar * a, size_t astep, uchar * b, size_t bstep, uchar * c, size_t, uchar * d, size_t, int w, int h, int cn)
|
||||
{
|
||||
if (skipSmallImages<VX_KERNEL_INTEGRAL_IMAGE>(w, h))
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
if (depth != CV_8U || sdepth != CV_32S || c != NULL || d != NULL || cn != 1)
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
refineStep(w, h, VX_DF_IMAGE_U8, astep);
|
||||
try
|
||||
{
|
||||
ivx::Context ctx = getOpenVXHALContext();
|
||||
ivx::Image
|
||||
ia = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8,
|
||||
ivx::Image::createAddressing(w, h, 1, (vx_int32)astep), const_cast<uchar*>(a)),
|
||||
ib = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U32,
|
||||
ivx::Image::createAddressing(w, h, 4, (vx_int32)bstep), (unsigned int *)(b + bstep + sizeof(unsigned int)));
|
||||
ivx::IVX_CHECK_STATUS(vxuIntegralImage(ctx, ia, ib));
|
||||
std::memset(b, 0, (w + 1) * sizeof(unsigned int));
|
||||
b += bstep;
|
||||
for (int i = 0; i < h; i++, b += bstep)
|
||||
{
|
||||
*((unsigned int*)b) = 0;
|
||||
}
|
||||
}
|
||||
catch (ivx::RuntimeError & e)
|
||||
{
|
||||
PRINT_HALERR_MSG(runtime);
|
||||
return CV_HAL_ERROR_UNKNOWN;
|
||||
}
|
||||
catch (ivx::WrapperError & e)
|
||||
{
|
||||
PRINT_HALERR_MSG(wrapper);
|
||||
return CV_HAL_ERROR_UNKNOWN;
|
||||
}
|
||||
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
Vendored
-145
@@ -1,145 +0,0 @@
|
||||
#ifndef OPENCV_OPENVX_HAL_HPP_INCLUDED
|
||||
#define OPENCV_OPENVX_HAL_HPP_INCLUDED
|
||||
|
||||
#include "opencv2/core/hal/interface.h"
|
||||
|
||||
#include "VX/vx.h"
|
||||
|
||||
template <typename T>
|
||||
int ovx_hal_add(const T *a, size_t astep, const T *b, size_t bstep, T *c, size_t cstep, int w, int h);
|
||||
template <typename T>
|
||||
int ovx_hal_sub(const T *a, size_t astep, const T *b, size_t bstep, T *c, size_t cstep, int w, int h);
|
||||
|
||||
template <typename T>
|
||||
int ovx_hal_absdiff(const T *a, size_t astep, const T *b, size_t bstep, T *c, size_t cstep, int w, int h);
|
||||
|
||||
template <typename T>
|
||||
int ovx_hal_and(const T *a, size_t astep, const T *b, size_t bstep, T *c, size_t cstep, int w, int h);
|
||||
template <typename T>
|
||||
int ovx_hal_or(const T *a, size_t astep, const T *b, size_t bstep, T *c, size_t cstep, int w, int h);
|
||||
template <typename T>
|
||||
int ovx_hal_xor(const T *a, size_t astep, const T *b, size_t bstep, T *c, size_t cstep, int w, int h);
|
||||
int ovx_hal_not(const uchar *a, size_t astep, uchar *c, size_t cstep, int w, int h);
|
||||
|
||||
template <typename T>
|
||||
int ovx_hal_mul(const T *a, size_t astep, const T *b, size_t bstep, T *c, size_t cstep, int w, int h, double scale);
|
||||
|
||||
int ovx_hal_merge8u(const uchar **src_data, uchar *dst_data, int len, int cn);
|
||||
int ovx_hal_resize(int atype, const uchar *a, size_t astep, int aw, int ah, uchar *b, size_t bstep, int bw, int bh, double inv_scale_x, double inv_scale_y, int interpolation);
|
||||
int ovx_hal_warpAffine(int atype, const uchar *a, size_t astep, int aw, int ah, uchar *b, size_t bstep, int bw, int bh, const double M[6], int interpolation, int borderType, const double borderValue[4]);
|
||||
int ovx_hal_warpPerspective(int atype, const uchar *a, size_t astep, int aw, int ah, uchar *b, size_t bstep, int bw, int bh, const double M[9], int interpolation, int borderType, const double borderValue[4]);
|
||||
|
||||
struct cvhalFilter2D;
|
||||
int ovx_hal_filterInit(cvhalFilter2D **filter_context, uchar *kernel_data, size_t kernel_step, int kernel_type, int kernel_width, int kernel_height,
|
||||
int, int, int src_type, int dst_type, int borderType, double delta, int anchor_x, int anchor_y, bool allowSubmatrix, bool allowInplace);
|
||||
int ovx_hal_filterFree(cvhalFilter2D *filter_context);
|
||||
int ovx_hal_filter(cvhalFilter2D *filter_context, uchar *a, size_t astep, uchar *b, size_t bstep, int w, int h, int, int, int, int);
|
||||
int ovx_hal_sepFilterInit(cvhalFilter2D **filter_context, int src_type, int dst_type,
|
||||
int kernel_type, uchar *kernelx_data, int kernelx_length, uchar *kernely_data, int kernely_length,
|
||||
int anchor_x, int anchor_y, double delta, int borderType);
|
||||
|
||||
#if VX_VERSION > VX_VERSION_1_0
|
||||
int ovx_hal_morphInit(cvhalFilter2D **filter_context, int operation, int src_type, int dst_type, int , int ,
|
||||
int kernel_type, uchar *kernel_data, size_t kernel_step, int kernel_width, int kernel_height, int anchor_x, int anchor_y,
|
||||
int borderType, const double borderValue[4], int iterations, bool allowSubmatrix, bool allowInplace);
|
||||
int ovx_hal_morphFree(cvhalFilter2D *filter_context);
|
||||
int ovx_hal_morph(cvhalFilter2D *filter_context, uchar *a, size_t astep, uchar *b, size_t bstep, int w, int h, int , int , int , int , int , int , int , int );
|
||||
#endif // 1.0 guard
|
||||
|
||||
int ovx_hal_cvtBGRtoBGR(const uchar * a, size_t astep, uchar * b, size_t bstep, int w, int h, int depth, int acn, int bcn, bool swapBlue);
|
||||
int ovx_hal_cvtGraytoBGR(const uchar * a, size_t astep, uchar * b, size_t bstep, int w, int h, int depth, int bcn);
|
||||
int ovx_hal_cvtTwoPlaneYUVtoBGR(const uchar * a, size_t astep, uchar * b, size_t bstep, int w, int h, int bcn, bool swapBlue, int uIdx);
|
||||
int ovx_hal_cvtTwoPlaneYUVtoBGREx(const uchar * a, size_t astep, const uchar * b, size_t bstep, uchar * c, size_t cstep, int w, int h, int bcn, bool swapBlue, int uIdx);
|
||||
int ovx_hal_cvtThreePlaneYUVtoBGR(const uchar * a, size_t astep, uchar * b, size_t bstep, int w, int h, int bcn, bool swapBlue, int uIdx);
|
||||
int ovx_hal_cvtBGRtoThreePlaneYUV(const uchar * a, size_t astep, uchar * b, size_t bstep, int w, int h, int acn, bool swapBlue, int uIdx);
|
||||
int ovx_hal_cvtOnePlaneYUVtoBGR(const uchar * a, size_t astep, uchar * b, size_t bstep, int w, int h, int bcn, bool swapBlue, int uIdx, int ycn);
|
||||
int ovx_hal_integral(int depth, int sdepth, int, const uchar * a, size_t astep, uchar * b, size_t bstep, uchar * c, size_t, uchar * d, size_t, int w, int h, int cn);
|
||||
|
||||
//==================================================================================================
|
||||
// functions redefinition
|
||||
// ...
|
||||
|
||||
#undef cv_hal_add8u
|
||||
#define cv_hal_add8u ovx_hal_add<uchar>
|
||||
#undef cv_hal_add16s
|
||||
#define cv_hal_add16s ovx_hal_add<short>
|
||||
#undef cv_hal_sub8u
|
||||
#define cv_hal_sub8u ovx_hal_sub<uchar>
|
||||
#undef cv_hal_sub16s
|
||||
#define cv_hal_sub16s ovx_hal_sub<short>
|
||||
|
||||
#undef cv_hal_absdiff8u
|
||||
#define cv_hal_absdiff8u ovx_hal_absdiff<uchar>
|
||||
#undef cv_hal_absdiff16s
|
||||
#define cv_hal_absdiff16s ovx_hal_absdiff<short>
|
||||
|
||||
#undef cv_hal_and8u
|
||||
#define cv_hal_and8u ovx_hal_and<uchar>
|
||||
#undef cv_hal_or8u
|
||||
#define cv_hal_or8u ovx_hal_or<uchar>
|
||||
#undef cv_hal_xor8u
|
||||
#define cv_hal_xor8u ovx_hal_xor<uchar>
|
||||
#undef cv_hal_not8u
|
||||
#define cv_hal_not8u ovx_hal_not
|
||||
|
||||
#undef cv_hal_mul8u
|
||||
#define cv_hal_mul8u ovx_hal_mul<uchar>
|
||||
#undef cv_hal_mul16s
|
||||
#define cv_hal_mul16s ovx_hal_mul<short>
|
||||
|
||||
#undef cv_hal_merge8u
|
||||
#define cv_hal_merge8u ovx_hal_merge8u
|
||||
|
||||
//#undef cv_hal_resize
|
||||
//#define cv_hal_resize ovx_hal_resize
|
||||
|
||||
//OpenVX warps use round to zero policy at least in sample implementation
|
||||
//while OpenCV require round to nearest
|
||||
//#undef cv_hal_warpAffine
|
||||
//#define cv_hal_warpAffine ovx_hal_warpAffine
|
||||
//#undef cv_hal_warpPerspective
|
||||
//#define cv_hal_warpPerspective ovx_hal_warpPerspective
|
||||
|
||||
#undef cv_hal_filterInit
|
||||
#define cv_hal_filterInit ovx_hal_filterInit
|
||||
#undef cv_hal_filter
|
||||
#define cv_hal_filter ovx_hal_filter
|
||||
#undef cv_hal_filterFree
|
||||
#define cv_hal_filterFree ovx_hal_filterFree
|
||||
|
||||
//#undef cv_hal_sepFilterInit
|
||||
//#define cv_hal_sepFilterInit ovx_hal_sepFilterInit
|
||||
//#undef cv_hal_sepFilter
|
||||
//#define cv_hal_sepFilter ovx_hal_filter
|
||||
//#undef cv_hal_sepFilterFree
|
||||
//#define cv_hal_sepFilterFree ovx_hal_filterFree
|
||||
|
||||
#if VX_VERSION > VX_VERSION_1_0
|
||||
|
||||
#undef cv_hal_morphInit
|
||||
#define cv_hal_morphInit ovx_hal_morphInit
|
||||
#undef cv_hal_morph
|
||||
#define cv_hal_morph ovx_hal_morph
|
||||
#undef cv_hal_morphFree
|
||||
#define cv_hal_morphFree ovx_hal_morphFree
|
||||
|
||||
#endif // 1.0 guard
|
||||
|
||||
#undef cv_hal_cvtBGRtoBGR
|
||||
#define cv_hal_cvtBGRtoBGR ovx_hal_cvtBGRtoBGR
|
||||
#undef cv_hal_cvtGraytoBGR
|
||||
#define cv_hal_cvtGraytoBGR ovx_hal_cvtGraytoBGR
|
||||
#undef cv_hal_cvtTwoPlaneYUVtoBGR
|
||||
#define cv_hal_cvtTwoPlaneYUVtoBGR ovx_hal_cvtTwoPlaneYUVtoBGR
|
||||
#undef cv_hal_cvtTwoPlaneYUVtoBGREx
|
||||
#define cv_hal_cvtTwoPlaneYUVtoBGREx ovx_hal_cvtTwoPlaneYUVtoBGREx
|
||||
#undef cv_hal_cvtThreePlaneYUVtoBGR
|
||||
#define cv_hal_cvtThreePlaneYUVtoBGR ovx_hal_cvtThreePlaneYUVtoBGR
|
||||
#undef cv_hal_cvtBGRtoThreePlaneYUV
|
||||
#define cv_hal_cvtBGRtoThreePlaneYUV ovx_hal_cvtBGRtoThreePlaneYUV
|
||||
#undef cv_hal_cvtOnePlaneYUVtoBGR
|
||||
#define cv_hal_cvtOnePlaneYUVtoBGR ovx_hal_cvtOnePlaneYUVtoBGR
|
||||
#undef cv_hal_integral
|
||||
#define cv_hal_integral ovx_hal_integral
|
||||
|
||||
#endif
|
||||
Vendored
-3277
@@ -1,3277 +0,0 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
|
||||
// Copyright (C) 2016, Intel Corporation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
|
||||
/*
|
||||
C++ wrappers over OpenVX 1.x C API
|
||||
Details: TBD
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef IVX_HPP
|
||||
#define IVX_HPP
|
||||
|
||||
#ifndef __cplusplus
|
||||
#error This file has to be compiled with C++ compiler
|
||||
#endif
|
||||
|
||||
|
||||
#include <VX/vx.h>
|
||||
#include <VX/vxu.h>
|
||||
|
||||
#ifndef VX_VERSION_1_1
|
||||
// 1.1 to 1.0 backward compatibility defines
|
||||
|
||||
static const vx_enum VX_INTERPOLATION_BILINEAR = VX_INTERPOLATION_TYPE_BILINEAR;
|
||||
static const vx_enum VX_INTERPOLATION_AREA = VX_INTERPOLATION_TYPE_AREA;
|
||||
static const vx_enum VX_INTERPOLATION_NEAREST_NEIGHBOR = VX_INTERPOLATION_TYPE_NEAREST_NEIGHBOR;
|
||||
|
||||
static const vx_enum VX_BORDER_CONSTANT = VX_BORDER_MODE_CONSTANT;
|
||||
static const vx_enum VX_BORDER_REPLICATE = VX_BORDER_MODE_REPLICATE;
|
||||
|
||||
#else
|
||||
|
||||
#ifdef IVX_RENAMED_REFS
|
||||
static const vx_enum VX_REF_ATTRIBUTE_TYPE = VX_REFERENCE_TYPE;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef IVX_USE_CXX98
|
||||
// checking compiler
|
||||
#if __cplusplus < 201103L && (!defined(_MSC_VER) || _MSC_VER < 1800)
|
||||
#define IVX_USE_CXX98
|
||||
#endif
|
||||
#endif // IVX_USE_CXX98
|
||||
|
||||
#if defined(IVX_USE_CXX98) && !defined(IVX_HIDE_INFO_WARNINGS)
|
||||
#ifdef _MSC_VER
|
||||
#pragma message ("ivx.hpp: The ISO C++ 2011 standard is not enabled, switching to C++98 fallback implementation.")
|
||||
#else
|
||||
#warning The ISO C++ 2011 standard is not enabled, switching to C++98 fallback implementation.
|
||||
#endif
|
||||
#endif // IVX_USE_CXX98
|
||||
|
||||
#ifndef IVX_USE_EXTERNAL_REFCOUNT
|
||||
// checking OpenVX version
|
||||
#ifndef VX_VERSION_1_1
|
||||
#define IVX_USE_EXTERNAL_REFCOUNT
|
||||
#endif
|
||||
#endif // IVX_USE_CXX98
|
||||
|
||||
#if defined(IVX_USE_EXTERNAL_REFCOUNT) && !defined(IVX_HIDE_INFO_WARNINGS)
|
||||
#ifdef _MSC_VER
|
||||
#pragma message ("ivx.hpp: OpenVX version < 1.1, switching to external refcounter implementation.")
|
||||
#else
|
||||
#warning OpenVX version < 1.1, switching to external refcounter implementation.
|
||||
#endif
|
||||
#endif // IVX_USE_EXTERNAL_REFCOUNT
|
||||
|
||||
#include <stdexcept>
|
||||
#include <utility>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <cstdlib>
|
||||
|
||||
#ifndef IVX_USE_CXX98
|
||||
#include <type_traits>
|
||||
namespace ivx
|
||||
{
|
||||
using std::is_same;
|
||||
using std::is_pointer;
|
||||
}
|
||||
#else
|
||||
namespace ivx
|
||||
{
|
||||
// helpers for compile-time type checking
|
||||
|
||||
template<typename, typename> struct is_same { static const bool value = false; };
|
||||
template<typename T> struct is_same<T, T> { static const bool value = true; };
|
||||
|
||||
template<typename T> struct is_pointer { static const bool value = false; };
|
||||
template<typename T> struct is_pointer<T*> { static const bool value = true; };
|
||||
template<typename T> struct is_pointer<const T*> { static const bool value = true; };
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef IVX_USE_OPENCV
|
||||
#include "opencv2/core.hpp"
|
||||
#endif
|
||||
|
||||
// disabling false alarm warnings
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(push)
|
||||
//#pragma warning( disable : 4??? )
|
||||
#elif defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunused-local-typedef"
|
||||
#pragma clang diagnostic ignored "-Wmissing-prototypes"
|
||||
#elif defined(__GNUC__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
|
||||
#pragma GCC diagnostic ignored "-Wunused-value"
|
||||
#pragma GCC diagnostic ignored "-Wmissing-declarations"
|
||||
#endif // compiler macro
|
||||
|
||||
namespace ivx
|
||||
{
|
||||
|
||||
inline vx_uint16 compiledWithVersion()
|
||||
{ return VX_VERSION; }
|
||||
|
||||
/// Exception class for OpenVX runtime errors
|
||||
class RuntimeError : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
/// Constructor
|
||||
explicit RuntimeError(vx_status st, const std::string& msg = "")
|
||||
: runtime_error(msg), _status(st)
|
||||
{}
|
||||
|
||||
/// OpenVX error code
|
||||
vx_status status() const
|
||||
{ return _status; }
|
||||
|
||||
private:
|
||||
vx_status _status;
|
||||
};
|
||||
|
||||
/// Exception class for wrappers logic errors
|
||||
class WrapperError : public std::logic_error
|
||||
{
|
||||
public:
|
||||
/// Constructor
|
||||
explicit WrapperError(const std::string& msg) : logic_error(msg)
|
||||
{}
|
||||
};
|
||||
|
||||
inline void checkVxStatus(vx_status status, const std::string& func, const std::string& msg)
|
||||
{
|
||||
if(status != VX_SUCCESS) throw RuntimeError( status, func + "() : " + msg );
|
||||
}
|
||||
|
||||
|
||||
/// Helper macro for turning a runtime error in the provided code into a \RuntimeError
|
||||
#define IVX_CHECK_STATUS(code) checkVxStatus(code, __func__, #code)
|
||||
|
||||
|
||||
/// OpenVX enum to type compile-time converter (TODO: add more types)
|
||||
template<vx_enum E> struct EnumToType {};
|
||||
template<> struct EnumToType<VX_TYPE_CHAR> { typedef vx_char type; static const vx_size bytes = sizeof(type); };
|
||||
template<> struct EnumToType<VX_TYPE_INT8> { typedef vx_int8 type; static const vx_size bytes = sizeof(type); };
|
||||
template<> struct EnumToType<VX_TYPE_UINT8> { typedef vx_uint8 type; static const vx_size bytes = sizeof(type); };
|
||||
template<> struct EnumToType<VX_TYPE_INT16> { typedef vx_int16 type; static const vx_size bytes = sizeof(type); };
|
||||
template<> struct EnumToType<VX_TYPE_UINT16> { typedef vx_uint16 type; static const vx_size bytes = sizeof(type); };
|
||||
template<> struct EnumToType<VX_TYPE_INT32> { typedef vx_int32 type; static const vx_size bytes = sizeof(type); };
|
||||
template<> struct EnumToType<VX_TYPE_UINT32> { typedef vx_uint32 type; static const vx_size bytes = sizeof(type); };
|
||||
template<> struct EnumToType<VX_TYPE_INT64> { typedef vx_int64 type; static const vx_size bytes = sizeof(type); };
|
||||
template<> struct EnumToType<VX_TYPE_UINT64> { typedef vx_uint64 type; static const vx_size bytes = sizeof(type); };
|
||||
template<> struct EnumToType<VX_TYPE_FLOAT32> { typedef vx_float32 type; static const vx_size bytes = sizeof(type); };
|
||||
template<> struct EnumToType<VX_TYPE_FLOAT64> { typedef vx_float64 type; static const vx_size bytes = sizeof(type); };
|
||||
template<> struct EnumToType<VX_TYPE_ENUM> { typedef vx_enum type; static const vx_size bytes = sizeof(type); };
|
||||
template<> struct EnumToType<VX_TYPE_SIZE> { typedef vx_size type; static const vx_size bytes = sizeof(type); };
|
||||
template<> struct EnumToType<VX_TYPE_DF_IMAGE> { typedef vx_df_image type; static const vx_size bytes = sizeof(type); };
|
||||
template<> struct EnumToType<VX_TYPE_BOOL> { typedef vx_bool type; static const vx_size bytes = sizeof(type); };
|
||||
template<> struct EnumToType<VX_TYPE_KEYPOINT> { typedef vx_keypoint_t type;static const vx_size bytes = sizeof(type); };
|
||||
#ifndef IVX_USE_CXX98
|
||||
template <vx_enum E> using EnumToType_t = typename EnumToType<E>::type;
|
||||
#endif
|
||||
|
||||
/// Gets size in bytes for the provided OpenVX type enum
|
||||
inline vx_size enumToTypeSize(vx_enum type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case VX_TYPE_CHAR: return EnumToType<VX_TYPE_CHAR>::bytes;
|
||||
case VX_TYPE_INT8: return EnumToType<VX_TYPE_INT8>::bytes;
|
||||
case VX_TYPE_UINT8: return EnumToType<VX_TYPE_UINT8>::bytes;
|
||||
case VX_TYPE_INT16: return EnumToType<VX_TYPE_INT16>::bytes;
|
||||
case VX_TYPE_UINT16: return EnumToType<VX_TYPE_UINT16>::bytes;
|
||||
case VX_TYPE_INT32: return EnumToType<VX_TYPE_INT32>::bytes;
|
||||
case VX_TYPE_UINT32: return EnumToType<VX_TYPE_UINT32>::bytes;
|
||||
case VX_TYPE_INT64: return EnumToType<VX_TYPE_INT64>::bytes;
|
||||
case VX_TYPE_UINT64: return EnumToType<VX_TYPE_UINT64>::bytes;
|
||||
case VX_TYPE_FLOAT32: return EnumToType<VX_TYPE_FLOAT32>::bytes;
|
||||
case VX_TYPE_FLOAT64: return EnumToType<VX_TYPE_FLOAT64>::bytes;
|
||||
case VX_TYPE_ENUM: return EnumToType<VX_TYPE_ENUM>::bytes;
|
||||
case VX_TYPE_SIZE: return EnumToType<VX_TYPE_SIZE>::bytes;
|
||||
case VX_TYPE_DF_IMAGE: return EnumToType<VX_TYPE_DF_IMAGE>::bytes;
|
||||
case VX_TYPE_BOOL: return EnumToType<VX_TYPE_BOOL>::bytes;
|
||||
case VX_TYPE_KEYPOINT: return EnumToType<VX_TYPE_KEYPOINT>::bytes;
|
||||
default: throw WrapperError(std::string(__func__) + ": unsupported type enum");
|
||||
}
|
||||
}
|
||||
|
||||
/// type to enum compile-time converter (TODO: add more types)
|
||||
template<typename T> struct TypeToEnum {};
|
||||
template<> struct TypeToEnum<vx_char> { static const vx_enum value = VX_TYPE_CHAR; };
|
||||
template<> struct TypeToEnum<vx_int8> { static const vx_enum value = VX_TYPE_INT8; };
|
||||
template<> struct TypeToEnum<vx_uint8> { static const vx_enum value = VX_TYPE_UINT8, imgType = VX_DF_IMAGE_U8; };
|
||||
template<> struct TypeToEnum<vx_int16> { static const vx_enum value = VX_TYPE_INT16, imgType = VX_DF_IMAGE_S16; };
|
||||
template<> struct TypeToEnum<vx_uint16> { static const vx_enum value = VX_TYPE_UINT16, imgType = VX_DF_IMAGE_U16; };
|
||||
template<> struct TypeToEnum<vx_int32> { static const vx_enum value = VX_TYPE_INT32, imgType = VX_DF_IMAGE_S32; };
|
||||
template<> struct TypeToEnum<vx_uint32> { static const vx_enum value = VX_TYPE_UINT32, imgType = VX_DF_IMAGE_U32; };
|
||||
template<> struct TypeToEnum<vx_int64> { static const vx_enum value = VX_TYPE_INT64; };
|
||||
template<> struct TypeToEnum<vx_uint64> { static const vx_enum value = VX_TYPE_UINT64; };
|
||||
template<> struct TypeToEnum<vx_float32> { static const vx_enum value = VX_TYPE_FLOAT32, imgType = VX_DF_IMAGE('F', '0', '3', '2'); };
|
||||
template<> struct TypeToEnum<vx_float64> { static const vx_enum value = VX_TYPE_FLOAT64; };
|
||||
template<> struct TypeToEnum<vx_bool> { static const vx_enum value = VX_TYPE_BOOL; };
|
||||
template<> struct TypeToEnum<vx_keypoint_t> {static const vx_enum value = VX_TYPE_KEYPOINT; };
|
||||
// the commented types are aliases (of integral tyes) and have conflicts with the types above
|
||||
//template<> struct TypeToEnum<vx_enum> { static const vx_enum val = VX_TYPE_ENUM; };
|
||||
//template<> struct TypeToEnum<vx_size> { static const vx_enum val = VX_TYPE_SIZE; };
|
||||
//template<> struct TypeToEnum<vx_df_image> { static const vx_enum val = VX_TYPE_DF_IMAGE; };
|
||||
|
||||
inline bool areTypesCompatible(const vx_enum a, const vx_enum b)
|
||||
{
|
||||
return enumToTypeSize(a) == enumToTypeSize(b);
|
||||
}
|
||||
|
||||
#ifdef IVX_USE_OPENCV
|
||||
inline int enumToCVType(vx_enum type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case VX_TYPE_CHAR: return CV_8UC1;//While OpenCV support 8S as well, 8U is supported wider
|
||||
case VX_TYPE_INT8: return CV_8SC1;
|
||||
case VX_TYPE_UINT8: return CV_8UC1;
|
||||
case VX_TYPE_INT16: return CV_16SC1;
|
||||
case VX_TYPE_UINT16: return CV_16UC1;
|
||||
case VX_TYPE_INT32: return CV_32SC1;
|
||||
case VX_TYPE_UINT32: return CV_32SC1;//That's not the best option but there is CV_32S type only
|
||||
case VX_TYPE_FLOAT32: return CV_32FC1;
|
||||
case VX_TYPE_FLOAT64: return CV_64FC1;
|
||||
case VX_TYPE_ENUM: return CV_32SC1;
|
||||
case VX_TYPE_BOOL: return CV_32SC1;
|
||||
default: throw WrapperError(std::string(__func__) + ": unsupported type enum");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/// Helper type, provides info for OpenVX 'objects' (vx_reference extending) types
|
||||
template <typename T> struct RefTypeTraits {};
|
||||
|
||||
class Context;
|
||||
template <> struct RefTypeTraits <vx_context>
|
||||
{
|
||||
typedef vx_context vxType;
|
||||
typedef Context wrapperType;
|
||||
static const vx_enum vxTypeEnum = VX_TYPE_CONTEXT;
|
||||
static vx_status release(vxType& ref) { return vxReleaseContext(&ref); }
|
||||
};
|
||||
|
||||
class Graph;
|
||||
template <> struct RefTypeTraits <vx_graph>
|
||||
{
|
||||
typedef vx_graph vxType;
|
||||
typedef Graph wrapperType;
|
||||
static const vx_enum vxTypeEnum = VX_TYPE_GRAPH;
|
||||
static vx_status release(vxType& ref) { return vxReleaseGraph(&ref); }
|
||||
};
|
||||
|
||||
class Node;
|
||||
template <> struct RefTypeTraits <vx_node>
|
||||
{
|
||||
typedef vx_node vxType;
|
||||
typedef Node wrapperType;
|
||||
static const vx_enum vxTypeEnum = VX_TYPE_NODE;
|
||||
static vx_status release(vxType& ref) { return vxReleaseNode(&ref); }
|
||||
};
|
||||
|
||||
class Kernel;
|
||||
template <> struct RefTypeTraits <vx_kernel>
|
||||
{
|
||||
typedef vx_kernel vxType;
|
||||
typedef Kernel wrapperType;
|
||||
static const vx_enum vxTypeEnum = VX_TYPE_KERNEL;
|
||||
static vx_status release(vxType& ref) { return vxReleaseKernel(&ref); }
|
||||
};
|
||||
|
||||
class Param;
|
||||
template <> struct RefTypeTraits <vx_parameter>
|
||||
{
|
||||
typedef vx_parameter vxType;
|
||||
typedef Param wrapperType;
|
||||
static const vx_enum vxTypeEnum = VX_TYPE_PARAMETER;
|
||||
static vx_status release(vxType& ref) { return vxReleaseParameter(&ref); }
|
||||
};
|
||||
|
||||
class Image;
|
||||
template <> struct RefTypeTraits <vx_image>
|
||||
{
|
||||
typedef vx_image vxType;
|
||||
typedef Image wrapperType;
|
||||
static const vx_enum vxTypeEnum = VX_TYPE_IMAGE;
|
||||
static vx_status release(vxType& ref) { return vxReleaseImage(&ref); }
|
||||
};
|
||||
|
||||
class Scalar;
|
||||
template <> struct RefTypeTraits <vx_scalar>
|
||||
{
|
||||
typedef vx_scalar vxType;
|
||||
typedef Scalar wrapperType;
|
||||
static const vx_enum vxTypeEnum = VX_TYPE_SCALAR;
|
||||
static vx_status release(vxType& ref) { return vxReleaseScalar(&ref); }
|
||||
};
|
||||
|
||||
class Array;
|
||||
template <> struct RefTypeTraits <vx_array>
|
||||
{
|
||||
typedef vx_array vxType;
|
||||
typedef Array wrapperType;
|
||||
static const vx_enum vxTypeEnum = VX_TYPE_ARRAY;
|
||||
static vx_status release(vxType& ref) { return vxReleaseArray(&ref); }
|
||||
};
|
||||
|
||||
class Threshold;
|
||||
template <> struct RefTypeTraits <vx_threshold>
|
||||
{
|
||||
typedef vx_threshold vxType;
|
||||
typedef Threshold wrapperType;
|
||||
static const vx_enum vxTypeEnum = VX_TYPE_THRESHOLD;
|
||||
static vx_status release(vxType& ref) { return vxReleaseThreshold(&ref); }
|
||||
};
|
||||
|
||||
class Convolution;
|
||||
template <> struct RefTypeTraits <vx_convolution>
|
||||
{
|
||||
typedef vx_convolution vxType;
|
||||
typedef Convolution wrapperType;
|
||||
static const vx_enum vxTypeEnum = VX_TYPE_CONVOLUTION;
|
||||
static vx_status release(vxType& ref) { return vxReleaseConvolution(&ref); }
|
||||
};
|
||||
|
||||
class Matrix;
|
||||
template <> struct RefTypeTraits <vx_matrix>
|
||||
{
|
||||
typedef vx_matrix vxType;
|
||||
typedef Matrix wrapperType;
|
||||
static const vx_enum vxTypeEnum = VX_TYPE_MATRIX;
|
||||
static vx_status release(vxType& ref) { return vxReleaseMatrix(&ref); }
|
||||
};
|
||||
|
||||
class LUT;
|
||||
template <> struct RefTypeTraits <vx_lut>
|
||||
{
|
||||
typedef vx_lut vxType;
|
||||
typedef LUT wrapperType;
|
||||
static const vx_enum vxTypeEnum = VX_TYPE_LUT;
|
||||
static vx_status release(vxType& ref) { return vxReleaseLUT(&ref); }
|
||||
};
|
||||
|
||||
class Pyramid;
|
||||
template <> struct RefTypeTraits <vx_pyramid>
|
||||
{
|
||||
typedef vx_pyramid vxType;
|
||||
typedef Pyramid wrapperType;
|
||||
static const vx_enum vxTypeEnum = VX_TYPE_PYRAMID;
|
||||
static vx_status release(vxType& ref) { return vxReleasePyramid(&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); }
|
||||
};
|
||||
|
||||
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
|
||||
|
||||
/// Casting to vx_reference with compile-time check
|
||||
|
||||
// takes 'vx_reference' itself and RefWrapper<T> via 'operator vx_reference()'
|
||||
inline vx_reference castToReference(vx_reference ref)
|
||||
{ return ref; }
|
||||
|
||||
// takes vx_reference extensions that have RefTypeTraits<T> specializations
|
||||
template<typename T>
|
||||
inline vx_reference castToReference(const T& ref, typename RefTypeTraits<T>::vxType dummy = 0)
|
||||
{ (void)dummy; return (vx_reference)ref; }
|
||||
|
||||
#else
|
||||
|
||||
template<typename T, typename = void>
|
||||
struct is_ref : std::is_same<T, vx_reference>{}; // allow vx_reference
|
||||
|
||||
// allow RefWrapper<> types
|
||||
template<typename T>
|
||||
#ifndef _MSC_VER
|
||||
struct is_ref<T, decltype(T().operator vx_reference(), void())> : std::true_type {};
|
||||
#else
|
||||
// workarounding VC14 compiler crash
|
||||
struct is_ref<T, decltype(T::vxType(), void())> : std::true_type {};
|
||||
#endif
|
||||
|
||||
// allow vx_reference extensions
|
||||
template<typename T>
|
||||
struct is_ref<T, decltype(RefTypeTraits<T>::vxTypeEnum, void())> : std::true_type {};
|
||||
|
||||
/// Casting to vx_reference with compile-time check
|
||||
|
||||
template<typename T>
|
||||
inline vx_reference castToReference(const T& obj)
|
||||
{
|
||||
static_assert(is_ref<T>::value, "unsupported conversion");
|
||||
return (vx_reference) obj;
|
||||
}
|
||||
|
||||
#endif // IVX_USE_CXX98
|
||||
|
||||
inline void checkVxRef(vx_reference ref, const std::string& func, const std::string& msg)
|
||||
{
|
||||
vx_status status = vxGetStatus(ref);
|
||||
if(status != VX_SUCCESS) throw RuntimeError( status, func + "() : " + msg );
|
||||
}
|
||||
|
||||
/// Helper macro for checking the provided OpenVX 'object' and throwing a \RuntimeError in case of error
|
||||
#define IVX_CHECK_REF(code) checkVxRef(castToReference(code), __func__, #code)
|
||||
|
||||
|
||||
#ifdef IVX_USE_EXTERNAL_REFCOUNT
|
||||
|
||||
/// Base class for OpenVX 'objects' wrappers
|
||||
template <typename T> class RefWrapper
|
||||
{
|
||||
public:
|
||||
typedef T vxType;
|
||||
static const vx_enum vxTypeEnum = RefTypeTraits <T>::vxTypeEnum;
|
||||
|
||||
/// Default constructor
|
||||
RefWrapper() : ref(0), refcount(0)
|
||||
{}
|
||||
|
||||
/// Constructor
|
||||
/// \param r OpenVX 'object' (e.g. vx_image)
|
||||
/// \param retainRef flag indicating whether to increase ref counter in constructor (false by default)
|
||||
explicit RefWrapper(T r, bool retainRef = false) : ref(0), refcount(0)
|
||||
{ reset(r, retainRef); }
|
||||
|
||||
/// Copy constructor
|
||||
RefWrapper(const RefWrapper& r) : ref(r.ref), refcount(r.refcount)
|
||||
{ addRef(); }
|
||||
|
||||
#ifndef IVX_USE_CXX98
|
||||
/// Move constructor
|
||||
RefWrapper(RefWrapper&& rw) noexcept : RefWrapper()
|
||||
{
|
||||
using std::swap;
|
||||
swap(ref, rw.ref);
|
||||
swap(refcount, rw.refcount);
|
||||
}
|
||||
#endif
|
||||
|
||||
/// Casting to the wrapped OpenVX 'object'
|
||||
operator T() const
|
||||
{ return ref; }
|
||||
|
||||
/// Casting to vx_reference since every OpenVX 'object' extends it
|
||||
operator vx_reference() const
|
||||
{ return castToReference(ref); }
|
||||
|
||||
/// Assigning a new value (decreasing ref counter for the old one)
|
||||
/// \param r OpenVX 'object' (e.g. vx_image)
|
||||
/// \param retainRef flag indicating whether to increase ref counter in constructor (false by default)
|
||||
void reset(T r, bool retainRef = false)
|
||||
{
|
||||
release();
|
||||
ref = r;
|
||||
#ifdef VX_VERSION_1_1
|
||||
if(retainRef) addRef();
|
||||
#else
|
||||
// if 'retainRef' -just don't use ref-counting for v 1.0
|
||||
if(!retainRef) refcount = new int(1);
|
||||
#endif
|
||||
checkRef();
|
||||
}
|
||||
|
||||
/// Assigning an empty value (decreasing ref counter for the old one)
|
||||
void reset()
|
||||
{ release(); }
|
||||
|
||||
/// Dropping kept value without releas decreasing ref counter
|
||||
/// \return the value being dropped
|
||||
T detach()
|
||||
{
|
||||
T tmp = ref;
|
||||
ref = 0;
|
||||
release();
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/// Unified assignment operator (covers both copy and move cases)
|
||||
RefWrapper& operator=(RefWrapper r)
|
||||
{
|
||||
using std::swap;
|
||||
swap(ref, r.ref);
|
||||
swap(refcount, r.refcount);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Checking for non-empty
|
||||
bool operator !() const
|
||||
{ return ref == 0; }
|
||||
|
||||
#ifndef IVX_USE_CXX98
|
||||
/// Explicit boolean evaluation (called automatically inside conditional operators only)
|
||||
explicit operator bool() const
|
||||
{ return ref != 0; }
|
||||
#endif
|
||||
|
||||
/// Getting a context that is kept in each OpenVX 'object' (call get<Context>())
|
||||
template<typename C>
|
||||
C get() const
|
||||
{
|
||||
typedef int static_assert_context[is_same<C, Context>::value ? 1 : -1];
|
||||
vx_context c = vxGetContext(castToReference(ref));
|
||||
// vxGetContext doesn't increment ref count, let do it in wrapper c-tor
|
||||
return C(c, true);
|
||||
}
|
||||
|
||||
#ifndef IVX_USE_CXX98
|
||||
/// Getting a context that is kept in each OpenVX 'object'
|
||||
template<typename C = Context, typename = typename std::enable_if<std::is_same<C, Context>::value>::type>
|
||||
C getContext() const
|
||||
{
|
||||
vx_context c = vxGetContext(castToReference(ref));
|
||||
// vxGetContext doesn't increment ref count, let do it in wrapper c-tor
|
||||
return C(c, true);
|
||||
}
|
||||
#endif // IVX_USE_CXX98
|
||||
|
||||
protected:
|
||||
T ref;
|
||||
int* refcount;
|
||||
|
||||
void addRef()
|
||||
{
|
||||
#ifdef VX_VERSION_1_1
|
||||
if(ref) IVX_CHECK_STATUS(vxRetainReference(castToReference(ref)));
|
||||
#else //TODO: make thread-safe
|
||||
if(refcount) ++(*refcount);
|
||||
#endif
|
||||
}
|
||||
|
||||
void release()
|
||||
{
|
||||
#ifdef VX_VERSION_1_1
|
||||
if(ref) RefTypeTraits<T>::release(ref);
|
||||
#else //TODO: make thread-safe
|
||||
if(refcount && --(*refcount) == 0)
|
||||
{
|
||||
if(ref) RefTypeTraits<T>::release(ref);
|
||||
ref = 0;
|
||||
delete refcount;
|
||||
refcount = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void checkRef() const
|
||||
{
|
||||
IVX_CHECK_REF(ref);
|
||||
vx_enum type;
|
||||
IVX_CHECK_STATUS(vxQueryReference((vx_reference)ref, VX_REF_ATTRIBUTE_TYPE, &type, sizeof(type)));
|
||||
if (type != vxTypeEnum) throw WrapperError("incompatible reference type");
|
||||
}
|
||||
|
||||
~RefWrapper()
|
||||
{ release(); }
|
||||
};
|
||||
|
||||
#ifdef IVX_USE_CXX98
|
||||
|
||||
#define IVX_REF_STD_CTORS_AND_ASSIGNMENT(Class) \
|
||||
Class() : RefWrapper() {} \
|
||||
explicit Class(Class::vxType _ref, bool retainRef = false) : RefWrapper(_ref, retainRef) {} \
|
||||
Class(const Class& _obj) : RefWrapper(_obj) {} \
|
||||
\
|
||||
Class& operator=(Class _obj) { using std::swap; swap(ref, _obj.ref); swap(refcount, _obj.refcount); return *this; }
|
||||
|
||||
#else
|
||||
|
||||
#define IVX_REF_STD_CTORS_AND_ASSIGNMENT(Class) \
|
||||
Class() : RefWrapper() {} \
|
||||
explicit Class(Class::vxType _ref, bool retainRef = false) : RefWrapper(_ref, retainRef) {} \
|
||||
Class(const Class& _obj) : RefWrapper(_obj) {} \
|
||||
Class(Class&& _obj) : RefWrapper(std::move(_obj)) {} \
|
||||
\
|
||||
Class& operator=(Class _obj) { using std::swap; swap(ref, _obj.ref); swap(refcount, _obj.refcount); return *this; }
|
||||
|
||||
#endif // IVX_USE_CXX98
|
||||
|
||||
#else // not IVX_USE_EXTERNAL_REFCOUNT
|
||||
|
||||
/// Base class for OpenVX 'objects' wrappers
|
||||
template <typename T> class RefWrapper
|
||||
{
|
||||
public:
|
||||
typedef T vxType;
|
||||
static const vx_enum vxTypeEnum = RefTypeTraits <T>::vxTypeEnum;
|
||||
|
||||
/// Default constructor
|
||||
RefWrapper() : ref(0)
|
||||
{}
|
||||
|
||||
/// Constructor
|
||||
/// \param r OpenVX 'object' (e.g. vx_image)
|
||||
/// \param retainRef flag indicating whether to increase ref counter in constructor (false by default)
|
||||
explicit RefWrapper(T r, bool retainRef = false) : ref(0)
|
||||
{ reset(r, retainRef); }
|
||||
|
||||
/// Copy constructor
|
||||
RefWrapper(const RefWrapper& r) : ref(r.ref)
|
||||
{ addRef(); }
|
||||
|
||||
#ifndef IVX_USE_CXX98
|
||||
/// Move constructor
|
||||
RefWrapper(RefWrapper&& rw) noexcept : RefWrapper()
|
||||
{
|
||||
using std::swap;
|
||||
swap(ref, rw.ref);
|
||||
}
|
||||
#endif
|
||||
|
||||
/// Casting to the wrapped OpenVX 'object'
|
||||
operator T() const
|
||||
{ return ref; }
|
||||
|
||||
/// Casting to vx_reference since every OpenVX 'object' extends it
|
||||
operator vx_reference() const
|
||||
{ return castToReference(ref); }
|
||||
|
||||
/// Getting a context that is kept in each OpenVX 'object' (call get<Context>())
|
||||
template<typename C>
|
||||
C get() const
|
||||
{
|
||||
typedef int static_assert_context[is_same<C, Context>::value ? 1 : -1];
|
||||
vx_context c = vxGetContext(castToReference(ref));
|
||||
// vxGetContext doesn't increment ref count, let do it in wrapper c-tor
|
||||
return C(c, true);
|
||||
}
|
||||
|
||||
#ifndef IVX_USE_CXX98
|
||||
/// Getting a context that is kept in each OpenVX 'object'
|
||||
template<typename C = Context, typename = typename std::enable_if<std::is_same<C, Context>::value>::type>
|
||||
C getContext() const
|
||||
{
|
||||
vx_context c = vxGetContext(castToReference(ref));
|
||||
// vxGetContext doesn't increment ref count, let do it in wrapper c-tor
|
||||
return C(c, true);
|
||||
}
|
||||
#endif // IVX_USE_CXX98
|
||||
|
||||
/// Assigning a new value (decreasing ref counter for the old one)
|
||||
/// \param r OpenVX 'object' (e.g. vx_image)
|
||||
/// \param retainRef flag indicating whether to increase ref counter in constructor (false by default)
|
||||
void reset(T r, bool retainRef = false)
|
||||
{
|
||||
release();
|
||||
ref = r;
|
||||
if (retainRef) addRef();
|
||||
checkRef();
|
||||
}
|
||||
|
||||
/// Assigning an empty value (decreasing ref counter for the old one)
|
||||
void reset()
|
||||
{ release(); }
|
||||
|
||||
/// Dropping kept value without releas decreasing ref counter
|
||||
/// \return the value being dropped
|
||||
T detach()
|
||||
{
|
||||
T tmp = ref;
|
||||
ref = 0;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/// Unified assignment operator (covers both copy and move cases)
|
||||
RefWrapper& operator=(RefWrapper r)
|
||||
{
|
||||
using std::swap;
|
||||
swap(ref, r.ref);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Checking for non-empty
|
||||
bool operator !() const
|
||||
{ return ref == 0; }
|
||||
|
||||
#ifndef IVX_USE_CXX98
|
||||
/// Explicit boolean evaluation (called automatically inside conditional operators only)
|
||||
explicit operator bool() const
|
||||
{ return ref != 0; }
|
||||
#endif
|
||||
|
||||
protected:
|
||||
T ref;
|
||||
|
||||
void addRef()
|
||||
{ if (ref) IVX_CHECK_STATUS(vxRetainReference((vx_reference)ref)); }
|
||||
|
||||
void release()
|
||||
{
|
||||
if (ref) RefTypeTraits<T>::release(ref);
|
||||
ref = 0;
|
||||
}
|
||||
|
||||
void checkRef() const
|
||||
{
|
||||
IVX_CHECK_REF(ref);
|
||||
vx_enum type;
|
||||
IVX_CHECK_STATUS(vxQueryReference((vx_reference)ref, VX_REF_ATTRIBUTE_TYPE, &type, sizeof(type)));
|
||||
if (type != vxTypeEnum) throw WrapperError("incompatible reference type");
|
||||
}
|
||||
|
||||
~RefWrapper()
|
||||
{ release(); }
|
||||
};
|
||||
|
||||
#ifdef IVX_USE_CXX98
|
||||
|
||||
#define IVX_REF_STD_CTORS_AND_ASSIGNMENT(Class) \
|
||||
Class() : RefWrapper() {} \
|
||||
explicit Class(Class::vxType _ref, bool retainRef = false) : RefWrapper(_ref, retainRef) {} \
|
||||
Class(const Class& _obj) : RefWrapper(_obj) {} \
|
||||
\
|
||||
Class& operator=(Class _obj) { using std::swap; swap(ref, _obj.ref); return *this; }
|
||||
|
||||
#else
|
||||
|
||||
#define IVX_REF_STD_CTORS_AND_ASSIGNMENT(Class) \
|
||||
Class() : RefWrapper() {} \
|
||||
explicit Class(Class::vxType _ref, bool retainRef = false) : RefWrapper(_ref, retainRef) {} \
|
||||
Class(const Class& _obj) : RefWrapper(_obj) {} \
|
||||
Class(Class&& _obj) : RefWrapper(std::move(_obj)) {} \
|
||||
\
|
||||
Class& operator=(Class _obj) { using std::swap; swap(ref, _obj.ref); return *this; }
|
||||
|
||||
#endif // IVX_USE_CXX98
|
||||
|
||||
#endif // IVX_USE_EXTERNAL_REFCOUNT
|
||||
|
||||
#ifndef VX_VERSION_1_1
|
||||
typedef vx_border_mode_t border_t;
|
||||
#else
|
||||
typedef vx_border_t border_t;
|
||||
#endif
|
||||
|
||||
/// vx_context wrapper
|
||||
class Context : public RefWrapper<vx_context>
|
||||
{
|
||||
public:
|
||||
|
||||
IVX_REF_STD_CTORS_AND_ASSIGNMENT(Context)
|
||||
|
||||
/// vxCreateContext() wrapper
|
||||
static Context create()
|
||||
{ return Context(vxCreateContext()); }
|
||||
|
||||
/// vxGetContext() wrapper
|
||||
template <typename T>
|
||||
static Context getFrom(const T& ref)
|
||||
{
|
||||
vx_context c = vxGetContext(castToReference(ref));
|
||||
// vxGetContext doesn't increment ref count, let do it in wrapper c-tor
|
||||
return Context(c, true);
|
||||
}
|
||||
|
||||
/// vxLoadKernels() wrapper
|
||||
void loadKernels(const std::string& module)
|
||||
{ IVX_CHECK_STATUS( vxLoadKernels(ref, module.c_str()) ); }
|
||||
|
||||
/// vxQueryContext() wrapper
|
||||
template<typename T>
|
||||
void query(vx_enum att, T& value) const
|
||||
{ IVX_CHECK_STATUS(vxQueryContext(ref, att, &value, sizeof(value))); }
|
||||
|
||||
#ifndef VX_VERSION_1_1
|
||||
static const vx_enum
|
||||
VX_CONTEXT_VENDOR_ID = VX_CONTEXT_ATTRIBUTE_VENDOR_ID,
|
||||
VX_CONTEXT_VERSION = VX_CONTEXT_ATTRIBUTE_VERSION,
|
||||
VX_CONTEXT_UNIQUE_KERNELS = VX_CONTEXT_ATTRIBUTE_UNIQUE_KERNELS,
|
||||
VX_CONTEXT_MODULES = VX_CONTEXT_ATTRIBUTE_MODULES,
|
||||
VX_CONTEXT_REFERENCES = VX_CONTEXT_ATTRIBUTE_REFERENCES,
|
||||
VX_CONTEXT_IMPLEMENTATION = VX_CONTEXT_ATTRIBUTE_IMPLEMENTATION,
|
||||
VX_CONTEXT_EXTENSIONS_SIZE = VX_CONTEXT_ATTRIBUTE_EXTENSIONS_SIZE,
|
||||
VX_CONTEXT_EXTENSIONS = VX_CONTEXT_ATTRIBUTE_EXTENSIONS,
|
||||
VX_CONTEXT_CONVOLUTION_MAX_DIMENSION = VX_CONTEXT_ATTRIBUTE_CONVOLUTION_MAXIMUM_DIMENSION,
|
||||
VX_CONTEXT_OPTICAL_FLOW_MAX_WINDOW_DIMENSION = VX_CONTEXT_ATTRIBUTE_OPTICAL_FLOW_WINDOW_MAXIMUM_DIMENSION,
|
||||
VX_CONTEXT_IMMEDIATE_BORDER = VX_CONTEXT_ATTRIBUTE_IMMEDIATE_BORDER_MODE,
|
||||
VX_CONTEXT_UNIQUE_KERNEL_TABLE = VX_CONTEXT_ATTRIBUTE_UNIQUE_KERNEL_TABLE;
|
||||
#endif
|
||||
|
||||
/// vxQueryContext(VX_CONTEXT_VENDOR_ID) wrapper
|
||||
vx_uint16 vendorID() const
|
||||
{
|
||||
vx_uint16 v;
|
||||
query(VX_CONTEXT_VENDOR_ID, v);
|
||||
return v;
|
||||
}
|
||||
|
||||
/// vxQueryContext(VX_CONTEXT_VERSION) wrapper
|
||||
vx_uint16 version() const
|
||||
{
|
||||
vx_uint16 v;
|
||||
query(VX_CONTEXT_VERSION, v);
|
||||
return v;
|
||||
}
|
||||
|
||||
/// vxQueryContext(VX_CONTEXT_UNIQUE_KERNELS) wrapper
|
||||
vx_uint32 uniqueKernelsNum() const
|
||||
{
|
||||
vx_uint32 v;
|
||||
query(VX_CONTEXT_UNIQUE_KERNELS, v);
|
||||
return v;
|
||||
}
|
||||
|
||||
/// vxQueryContext(VX_CONTEXT_MODULES) wrapper
|
||||
vx_uint32 modulesNum() const
|
||||
{
|
||||
vx_uint32 v;
|
||||
query(VX_CONTEXT_MODULES, v);
|
||||
return v;
|
||||
}
|
||||
|
||||
/// vxQueryContext(VX_CONTEXT_REFERENCES) wrapper
|
||||
vx_uint32 refsNum() const
|
||||
{
|
||||
vx_uint32 v;
|
||||
query(VX_CONTEXT_REFERENCES, v);
|
||||
return v;
|
||||
}
|
||||
|
||||
/// vxQueryContext(VX_CONTEXT_EXTENSIONS_SIZE) wrapper
|
||||
vx_size extensionsSize() const
|
||||
{
|
||||
vx_size v;
|
||||
query(VX_CONTEXT_EXTENSIONS_SIZE, v);
|
||||
return v;
|
||||
}
|
||||
|
||||
/// vxQueryContext(VX_CONTEXT_CONVOLUTION_MAX_DIMENSION) wrapper
|
||||
vx_size convolutionMaxDimension() const
|
||||
{
|
||||
vx_size v;
|
||||
query(VX_CONTEXT_CONVOLUTION_MAX_DIMENSION, v);
|
||||
return v;
|
||||
}
|
||||
|
||||
/// vxQueryContext(VX_CONTEXT_OPTICAL_FLOW_MAX_WINDOW_DIMENSION) wrapper
|
||||
vx_size opticalFlowMaxWindowSize() const
|
||||
{
|
||||
vx_size v;
|
||||
query(VX_CONTEXT_OPTICAL_FLOW_MAX_WINDOW_DIMENSION, v);
|
||||
return v;
|
||||
}
|
||||
|
||||
/// vxQueryContext(VX_CONTEXT_IMMEDIATE_BORDER) wrapper
|
||||
border_t immediateBorder() const
|
||||
{
|
||||
border_t v;
|
||||
query(VX_CONTEXT_IMMEDIATE_BORDER, v);
|
||||
return v;
|
||||
}
|
||||
|
||||
/// vxQueryContext(VX_CONTEXT_IMPLEMENTATION) wrapper
|
||||
std::string implName() const
|
||||
{
|
||||
std::vector<vx_char> v(VX_MAX_IMPLEMENTATION_NAME);
|
||||
IVX_CHECK_STATUS(vxQueryContext(ref, VX_CONTEXT_IMPLEMENTATION, &v[0], v.size() * sizeof(vx_char)));
|
||||
return std::string(v.data());
|
||||
}
|
||||
|
||||
/// vxQueryContext(VX_CONTEXT_EXTENSIONS) wrapper
|
||||
std::string extensionsStr() const
|
||||
{
|
||||
std::vector<vx_char> v(extensionsSize());
|
||||
IVX_CHECK_STATUS(vxQueryContext(ref, VX_CONTEXT_EXTENSIONS, &v[0], v.size() * sizeof(vx_char)));
|
||||
return std::string(v.data());
|
||||
}
|
||||
|
||||
/// vxQueryContext(VX_CONTEXT_UNIQUE_KERNEL_TABLE) wrapper
|
||||
std::vector<vx_kernel_info_t> kernelTable() const
|
||||
{
|
||||
std::vector<vx_kernel_info_t> v(uniqueKernelsNum());
|
||||
IVX_CHECK_STATUS(vxQueryContext(ref, VX_CONTEXT_UNIQUE_KERNEL_TABLE, &v[0], v.size() * sizeof(vx_kernel_info_t)));
|
||||
return v;
|
||||
}
|
||||
|
||||
#ifdef VX_VERSION_1_1
|
||||
/// vxQueryContext(VX_CONTEXT_IMMEDIATE_BORDER_POLICY) wrapper
|
||||
vx_enum immediateBorderPolicy() const
|
||||
{
|
||||
vx_enum v;
|
||||
query(VX_CONTEXT_IMMEDIATE_BORDER_POLICY, v);
|
||||
return v;
|
||||
}
|
||||
|
||||
/// vxQueryContext(VX_CONTEXT_NONLINEAR_MAX_DIMENSION) wrapper
|
||||
vx_size nonlinearMaxDimension() const
|
||||
{
|
||||
vx_size v;
|
||||
query(VX_CONTEXT_NONLINEAR_MAX_DIMENSION, v);
|
||||
return v;
|
||||
}
|
||||
#endif
|
||||
|
||||
/// vxSetContextAttribute() wrapper
|
||||
template<typename T>
|
||||
void setAttribute(vx_enum att, const T& value)
|
||||
{ IVX_CHECK_STATUS( vxSetContextAttribute(ref, att, &value, sizeof(value)) ); }
|
||||
|
||||
/// vxSetContextAttribute(BORDER) wrapper
|
||||
void setImmediateBorder(const border_t& bm)
|
||||
{ setAttribute(VX_CONTEXT_IMMEDIATE_BORDER, bm); }
|
||||
|
||||
#ifndef VX_VERSION_1_1
|
||||
/// vxSetContextAttribute(BORDER) wrapper
|
||||
void setImmediateBorder(vx_enum mode, vx_uint32 val = 0)
|
||||
{ border_t bm = {mode, val}; setImmediateBorder(bm); }
|
||||
#else
|
||||
/// vxSetContextAttribute(BORDER) wrapper
|
||||
void setImmediateBorder(vx_enum mode, const vx_pixel_value_t& val)
|
||||
{ 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
|
||||
void setImmediateBorder(vx_enum mode)
|
||||
{ vx_pixel_value_t val = {}; setImmediateBorder(mode, val); }
|
||||
#endif
|
||||
};
|
||||
|
||||
/// vx_graph wrapper
|
||||
class Graph : public RefWrapper<vx_graph>
|
||||
{
|
||||
public:
|
||||
IVX_REF_STD_CTORS_AND_ASSIGNMENT(Graph);
|
||||
|
||||
/// vxCreateGraph() wrapper
|
||||
static Graph create(vx_context c)
|
||||
{ return Graph(vxCreateGraph(c)); }
|
||||
|
||||
/// vxVerifyGraph() wrapper
|
||||
void verify()
|
||||
{ IVX_CHECK_STATUS( vxVerifyGraph(ref) ); }
|
||||
|
||||
/// vxProcessGraph() wrapper
|
||||
void process()
|
||||
{ IVX_CHECK_STATUS( vxProcessGraph(ref) ); }
|
||||
|
||||
/// vxScheduleGraph() wrapper
|
||||
void schedule()
|
||||
{ IVX_CHECK_STATUS(vxScheduleGraph(ref) ); }
|
||||
|
||||
/// vxWaitGraph() wrapper
|
||||
void wait()
|
||||
{ IVX_CHECK_STATUS(vxWaitGraph(ref)); }
|
||||
};
|
||||
|
||||
/// vx_kernel wrapper
|
||||
class Kernel : public RefWrapper<vx_kernel>
|
||||
{
|
||||
public:
|
||||
IVX_REF_STD_CTORS_AND_ASSIGNMENT(Kernel);
|
||||
|
||||
/// vxGetKernelByEnum() wrapper
|
||||
static Kernel getByEnum(vx_context c, vx_enum kernelID)
|
||||
{ return Kernel(vxGetKernelByEnum(c, kernelID)); }
|
||||
|
||||
/// vxGetKernelByName() wrapper
|
||||
static Kernel getByName(vx_context c, const std::string& name)
|
||||
{ return Kernel(vxGetKernelByName(c, name.c_str())); }
|
||||
};
|
||||
|
||||
|
||||
/// vx_node wrapper
|
||||
class Node : public RefWrapper<vx_node>
|
||||
{
|
||||
public:
|
||||
IVX_REF_STD_CTORS_AND_ASSIGNMENT(Node);
|
||||
|
||||
/// vxCreateGenericNode() wrapper
|
||||
static Node create(vx_graph g, vx_kernel k)
|
||||
{ return Node(vxCreateGenericNode(g, k)); }
|
||||
|
||||
/// Create node for the kernel and set the parameters
|
||||
static Node create(vx_graph graph, vx_kernel kernel, const std::vector<vx_reference>& params)
|
||||
{
|
||||
Node node = Node::create(graph, kernel);
|
||||
vx_uint32 i = 0;
|
||||
for (std::vector<vx_reference>::const_iterator p = params.begin(); p != params.end(); ++p)
|
||||
node.setParameterByIndex(i++, *p);
|
||||
return node;
|
||||
}
|
||||
|
||||
/// Create node for the kernel ID and set the parameters
|
||||
static Node create(vx_graph graph, vx_enum kernelID, const std::vector<vx_reference>& params)
|
||||
{ return Node::create(graph, Kernel::getByEnum(Context::getFrom(graph), kernelID), params); }
|
||||
|
||||
#ifdef IVX_USE_CXX98
|
||||
/// Create node for the kernel ID and set one parameter
|
||||
template<typename T0>
|
||||
static Node create(vx_graph g, vx_enum kernelID,
|
||||
const T0& arg0)
|
||||
{
|
||||
std::vector<vx_reference> params;
|
||||
params.push_back(castToReference(arg0));
|
||||
return create(g, Kernel::getByEnum(Context::getFrom(g), kernelID), params);
|
||||
}
|
||||
|
||||
/// Create node for the kernel ID and set two parameters
|
||||
template<typename T0, typename T1>
|
||||
static Node create(vx_graph g, vx_enum kernelID,
|
||||
const T0& arg0, const T1& arg1)
|
||||
{
|
||||
std::vector<vx_reference> params;
|
||||
params.push_back(castToReference(arg0));
|
||||
params.push_back(castToReference(arg1));
|
||||
return create(g, Kernel::getByEnum(Context::getFrom(g), kernelID), params);
|
||||
}
|
||||
|
||||
/// Create node for the kernel ID and set three parameters
|
||||
template<typename T0, typename T1, typename T2>
|
||||
static Node create(vx_graph g, vx_enum kernelID,
|
||||
const T0& arg0, const T1& arg1, const T2& arg2)
|
||||
{
|
||||
std::vector<vx_reference> params;
|
||||
params.push_back(castToReference(arg0));
|
||||
params.push_back(castToReference(arg1));
|
||||
params.push_back(castToReference(arg2));
|
||||
return create(g, Kernel::getByEnum(Context::getFrom(g), kernelID), params);
|
||||
}
|
||||
|
||||
/// Create node for the kernel ID and set four parameters
|
||||
template<typename T0, typename T1, typename T2, typename T3>
|
||||
static Node create(vx_graph g, vx_enum kernelID,
|
||||
const T0& arg0, const T1& arg1, const T2& arg2,
|
||||
const T3& arg3)
|
||||
{
|
||||
std::vector<vx_reference> params;
|
||||
params.push_back(castToReference(arg0));
|
||||
params.push_back(castToReference(arg1));
|
||||
params.push_back(castToReference(arg2));
|
||||
params.push_back(castToReference(arg3));
|
||||
return create(g, Kernel::getByEnum(Context::getFrom(g), kernelID), params);
|
||||
}
|
||||
|
||||
/// Create node for the kernel ID and set five parameters
|
||||
template<typename T0, typename T1, typename T2, typename T3, typename T4>
|
||||
static Node create(vx_graph g, vx_enum kernelID,
|
||||
const T0& arg0, const T1& arg1, const T2& arg2,
|
||||
const T3& arg3, const T4& arg4)
|
||||
{
|
||||
std::vector<vx_reference> params;
|
||||
params.push_back(castToReference(arg0));
|
||||
params.push_back(castToReference(arg1));
|
||||
params.push_back(castToReference(arg2));
|
||||
params.push_back(castToReference(arg3));
|
||||
params.push_back(castToReference(arg4));
|
||||
return create(g, Kernel::getByEnum(Context::getFrom(g), kernelID), params);
|
||||
}
|
||||
|
||||
/// Create node for the kernel ID and set six parameters
|
||||
template<typename T0, typename T1, typename T2, typename T3, typename T4, typename T5>
|
||||
static Node create(vx_graph g, vx_enum kernelID,
|
||||
const T0& arg0, const T1& arg1, const T2& arg2,
|
||||
const T3& arg3, const T4& arg4, const T5& arg5)
|
||||
{
|
||||
std::vector<vx_reference> params;
|
||||
params.push_back(castToReference(arg0));
|
||||
params.push_back(castToReference(arg1));
|
||||
params.push_back(castToReference(arg2));
|
||||
params.push_back(castToReference(arg3));
|
||||
params.push_back(castToReference(arg4));
|
||||
params.push_back(castToReference(arg5));
|
||||
return create(g, Kernel::getByEnum(Context::getFrom(g), kernelID), params);
|
||||
}
|
||||
|
||||
/// Create node for the kernel ID and set seven parameters
|
||||
template<typename T0, typename T1, typename T2, typename T3, typename T4, typename T5,
|
||||
typename T6>
|
||||
static Node create(vx_graph g, vx_enum kernelID,
|
||||
const T0& arg0, const T1& arg1, const T2& arg2,
|
||||
const T3& arg3, const T4& arg4, const T5& arg5,
|
||||
const T6& arg6)
|
||||
{
|
||||
std::vector<vx_reference> params;
|
||||
params.push_back(castToReference(arg0));
|
||||
params.push_back(castToReference(arg1));
|
||||
params.push_back(castToReference(arg2));
|
||||
params.push_back(castToReference(arg3));
|
||||
params.push_back(castToReference(arg4));
|
||||
params.push_back(castToReference(arg5));
|
||||
params.push_back(castToReference(arg6));
|
||||
return create(g, Kernel::getByEnum(Context::getFrom(g), kernelID), params);
|
||||
}
|
||||
|
||||
/// Create node for the kernel ID and set eight parameters
|
||||
template<typename T0, typename T1, typename T2, typename T3, typename T4, typename T5,
|
||||
typename T6, typename T7>
|
||||
static Node create(vx_graph g, vx_enum kernelID,
|
||||
const T0& arg0, const T1& arg1, const T2& arg2,
|
||||
const T3& arg3, const T4& arg4, const T5& arg5,
|
||||
const T6& arg6, const T7& arg7)
|
||||
{
|
||||
std::vector<vx_reference> params;
|
||||
params.push_back(castToReference(arg0));
|
||||
params.push_back(castToReference(arg1));
|
||||
params.push_back(castToReference(arg2));
|
||||
params.push_back(castToReference(arg3));
|
||||
params.push_back(castToReference(arg4));
|
||||
params.push_back(castToReference(arg5));
|
||||
params.push_back(castToReference(arg6));
|
||||
params.push_back(castToReference(arg7));
|
||||
return create(g, Kernel::getByEnum(Context::getFrom(g), kernelID), params);
|
||||
}
|
||||
|
||||
/// Create node for the kernel ID and set nine parameters
|
||||
template<typename T0, typename T1, typename T2, typename T3, typename T4, typename T5,
|
||||
typename T6, typename T7, typename T8>
|
||||
static Node create(vx_graph g, vx_enum kernelID,
|
||||
const T0& arg0, const T1& arg1, const T2& arg2,
|
||||
const T3& arg3, const T4& arg4, const T5& arg5,
|
||||
const T6& arg6, const T7& arg7, const T8& arg8)
|
||||
{
|
||||
std::vector<vx_reference> params;
|
||||
params.push_back(castToReference(arg0));
|
||||
params.push_back(castToReference(arg1));
|
||||
params.push_back(castToReference(arg2));
|
||||
params.push_back(castToReference(arg3));
|
||||
params.push_back(castToReference(arg4));
|
||||
params.push_back(castToReference(arg5));
|
||||
params.push_back(castToReference(arg6));
|
||||
params.push_back(castToReference(arg7));
|
||||
params.push_back(castToReference(arg8));
|
||||
return create(g, Kernel::getByEnum(Context::getFrom(g), kernelID), params);
|
||||
}
|
||||
|
||||
/// Create node for the kernel ID and set ten parameters
|
||||
template<typename T0, typename T1, typename T2, typename T3, typename T4, typename T5,
|
||||
typename T6, typename T7, typename T8, typename T9>
|
||||
static Node create(vx_graph g, vx_enum kernelID,
|
||||
const T0& arg0, const T1& arg1, const T2& arg2,
|
||||
const T3& arg3, const T4& arg4, const T5& arg5,
|
||||
const T6& arg6, const T7& arg7, const T8& arg8,
|
||||
const T9& arg9)
|
||||
{
|
||||
std::vector<vx_reference> params;
|
||||
params.push_back(castToReference(arg0));
|
||||
params.push_back(castToReference(arg1));
|
||||
params.push_back(castToReference(arg2));
|
||||
params.push_back(castToReference(arg3));
|
||||
params.push_back(castToReference(arg4));
|
||||
params.push_back(castToReference(arg5));
|
||||
params.push_back(castToReference(arg6));
|
||||
params.push_back(castToReference(arg7));
|
||||
params.push_back(castToReference(arg8));
|
||||
params.push_back(castToReference(arg9));
|
||||
return create(g, Kernel::getByEnum(Context::getFrom(g), kernelID), params);
|
||||
}
|
||||
|
||||
#else // not IVX_USE_CXX98
|
||||
|
||||
/// Create node for the kernel ID and set the specified parameters
|
||||
template<typename...Ts>
|
||||
static Node create(vx_graph g, vx_enum kernelID, const Ts&...args)
|
||||
{ return create(g, Kernel::getByEnum(Context::getFrom(g), kernelID), { castToReference(args)... }); }
|
||||
|
||||
#endif // IVX_USE_CXX98
|
||||
|
||||
/// vxSetParameterByIndex() wrapper
|
||||
void setParameterByIndex(vx_uint32 index, vx_reference value)
|
||||
{ IVX_CHECK_STATUS(vxSetParameterByIndex(ref, index, value)); }
|
||||
|
||||
/// vxQueryNode() wrapper
|
||||
template<typename T>
|
||||
void query(vx_enum att, T& value) const
|
||||
{ IVX_CHECK_STATUS( vxQueryNode(ref, att, &value, sizeof(value)) ); }
|
||||
|
||||
#ifndef VX_VERSION_1_1
|
||||
static const vx_enum
|
||||
VX_NODE_STATUS = VX_NODE_ATTRIBUTE_STATUS,
|
||||
VX_NODE_PERFORMANCE = VX_NODE_ATTRIBUTE_PERFORMANCE,
|
||||
VX_NODE_BORDER = VX_NODE_ATTRIBUTE_BORDER_MODE,
|
||||
VX_NODE_LOCAL_DATA_SIZE = VX_NODE_ATTRIBUTE_LOCAL_DATA_SIZE,
|
||||
VX_NODE_LOCAL_DATA_PTR = VX_NODE_ATTRIBUTE_LOCAL_DATA_PTR,
|
||||
VX_BORDER_UNDEFINED = VX_BORDER_MODE_UNDEFINED;
|
||||
#endif
|
||||
|
||||
/// vxQueryNode(STATUS) wrapper
|
||||
vx_status status() const
|
||||
{
|
||||
vx_status v;
|
||||
query(VX_NODE_STATUS, v);
|
||||
return v;
|
||||
}
|
||||
|
||||
/// vxQueryNode(PERFORMANCE) wrapper
|
||||
vx_perf_t performance() const
|
||||
{
|
||||
vx_perf_t v;
|
||||
query(VX_NODE_PERFORMANCE, v);
|
||||
return v;
|
||||
}
|
||||
|
||||
/// vxQueryNode(BORDER) wrapper
|
||||
border_t border() const
|
||||
{
|
||||
border_t v;
|
||||
v.mode = VX_BORDER_UNDEFINED;
|
||||
query(VX_NODE_BORDER, v);
|
||||
return v;
|
||||
}
|
||||
|
||||
/// vxQueryNode(LOCAL_DATA_SIZE) wrapper
|
||||
vx_size dataSize() const
|
||||
{
|
||||
vx_size v;
|
||||
query(VX_NODE_LOCAL_DATA_SIZE, v);
|
||||
return v;
|
||||
}
|
||||
|
||||
/// vxQueryNode(LOCAL_DATA_PTR) wrapper
|
||||
void* dataPtr() const
|
||||
{
|
||||
void* v;
|
||||
query(VX_NODE_LOCAL_DATA_PTR, v);
|
||||
return v;
|
||||
}
|
||||
|
||||
#ifdef VX_VERSION_1_1
|
||||
/// vxQueryNode(PARAMETERS) wrapper
|
||||
vx_uint32 paramsNum() const
|
||||
{
|
||||
vx_uint32 v;
|
||||
query(VX_NODE_PARAMETERS, v);
|
||||
return v;
|
||||
}
|
||||
|
||||
/// vxQueryNode(REPLICATED) wrapper
|
||||
vx_bool isReplicated() const
|
||||
{
|
||||
vx_bool v;
|
||||
query(VX_NODE_IS_REPLICATED, v);
|
||||
return v;
|
||||
}
|
||||
|
||||
/// vxQueryNode(REPLICATE_FLAGS) wrapper
|
||||
void replicateFlags(std::vector<vx_bool>& flags) const
|
||||
{
|
||||
if(flags.empty()) flags.resize(paramsNum(), vx_false_e);
|
||||
IVX_CHECK_STATUS( vxQueryNode(ref, VX_NODE_REPLICATE_FLAGS, &flags[0], flags.size()*sizeof(flags[0])) );
|
||||
}
|
||||
|
||||
/// vxQueryNode(VX_NODE_VALID_RECT_RESET) wrapper
|
||||
vx_bool resetValidRect() const
|
||||
{
|
||||
vx_bool v;
|
||||
query(VX_NODE_VALID_RECT_RESET, v);
|
||||
return v;
|
||||
}
|
||||
#endif // VX_VERSION_1_1
|
||||
|
||||
/// vxSetNodeAttribute() wrapper
|
||||
template<typename T>
|
||||
void setAttribute(vx_enum att, const T& value)
|
||||
{ IVX_CHECK_STATUS( vxSetNodeAttribute(ref, att, &value, sizeof(value)) ); }
|
||||
|
||||
/// vxSetNodeAttribute(BORDER) wrapper
|
||||
void setBorder(const border_t& bm)
|
||||
{ setAttribute(VX_NODE_BORDER, bm); }
|
||||
|
||||
#ifndef VX_VERSION_1_1
|
||||
/// vxSetNodeAttribute(BORDER) wrapper
|
||||
void setBorder(vx_enum mode, vx_uint32 val = 0)
|
||||
{ vx_border_mode_t bm = {mode, val}; setBorder(bm); }
|
||||
#else
|
||||
/// vxSetNodeAttribute(BORDER) wrapper
|
||||
void setBorder(vx_enum mode, const vx_pixel_value_t& val)
|
||||
{ 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
|
||||
void setBorder(vx_enum mode)
|
||||
{ vx_pixel_value_t val = {}; setBorder(mode, val); }
|
||||
#endif
|
||||
|
||||
/// vxSetNodeAttribute(LOCAL_DATA_SIZE) wrapper
|
||||
void setDataSize(vx_size size)
|
||||
{ setAttribute(VX_NODE_LOCAL_DATA_SIZE, size); }
|
||||
|
||||
/// vxSetNodeAttribute(LOCAL_DATA_PTR) wrapper
|
||||
void setDataPtr(void* ptr)
|
||||
{ setAttribute(VX_NODE_LOCAL_DATA_PTR, ptr); }
|
||||
};
|
||||
|
||||
|
||||
/// vx_image wrapper
|
||||
class Image : public RefWrapper<vx_image>
|
||||
{
|
||||
public:
|
||||
IVX_REF_STD_CTORS_AND_ASSIGNMENT(Image);
|
||||
|
||||
/// vxCreateImage() wrapper
|
||||
static Image create(vx_context context, vx_uint32 width, vx_uint32 height, vx_df_image format)
|
||||
{ return Image(vxCreateImage(context, width, height, format)); }
|
||||
|
||||
/// vxCreateVirtualImage() wrapper
|
||||
static Image createVirtual(vx_graph graph, vx_uint32 width = 0, vx_uint32 height = 0, vx_df_image format = VX_DF_IMAGE_VIRT)
|
||||
{ return Image(vxCreateVirtualImage(graph, width, height, format)); }
|
||||
|
||||
#ifdef VX_VERSION_1_1
|
||||
/// vxCreateUniformImage() wrapper
|
||||
static Image createUniform(vx_context context, vx_uint32 width, vx_uint32 height, vx_df_image format, const vx_pixel_value_t& value)
|
||||
{ return Image(vxCreateUniformImage(context, width, height, format, &value)); }
|
||||
#else
|
||||
/// vxCreateUniformImage() wrapper
|
||||
static Image createUniform(vx_context context, vx_uint32 width, vx_uint32 height, vx_df_image format, const void* value)
|
||||
{ return Image(vxCreateUniformImage(context, width, height, format, value)); }
|
||||
#endif
|
||||
template <typename T>
|
||||
static Image createUniform(vx_context context, vx_uint32 width, vx_uint32 height, vx_df_image format, const T value)
|
||||
{
|
||||
#if VX_VERSION > VX_VERSION_1_0
|
||||
vx_pixel_value_t pixel;
|
||||
switch (format)
|
||||
{
|
||||
case VX_DF_IMAGE_U8:pixel.U8 = (vx_uint8)value; break;
|
||||
case VX_DF_IMAGE_S16:pixel.S16 = (vx_int16)value; break;
|
||||
case VX_DF_IMAGE_U16:pixel.U16 = (vx_uint16)value; break;
|
||||
case VX_DF_IMAGE_S32:pixel.S32 = (vx_int32)value; break;
|
||||
case VX_DF_IMAGE_U32:pixel.U32 = (vx_uint32)value; break;
|
||||
default:throw ivx::WrapperError("uniform image type unsupported by this call");
|
||||
}
|
||||
return Image(vxCreateUniformImage(context, width, height, format, &pixel));
|
||||
#else
|
||||
return Image(vxCreateUniformImage(context, width, height, format, &value));
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Planes number for the specified image format (fourcc)
|
||||
/// \return 0 for unknown formats
|
||||
static vx_size planes(vx_df_image format)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case VX_DF_IMAGE_IYUV:
|
||||
case VX_DF_IMAGE_YUV4: return 3;
|
||||
case VX_DF_IMAGE_NV12:
|
||||
case VX_DF_IMAGE_NV21: return 2;
|
||||
case VX_DF_IMAGE_RGB:
|
||||
case VX_DF_IMAGE_RGBX:
|
||||
case VX_DF_IMAGE_UYVY:
|
||||
case VX_DF_IMAGE_YUYV:
|
||||
case VX_DF_IMAGE_U8:
|
||||
case VX_DF_IMAGE_U16:
|
||||
case VX_DF_IMAGE_S16:
|
||||
case VX_DF_IMAGE_U32:
|
||||
case VX_DF_IMAGE_S32:
|
||||
case /*VX_DF_IMAGE_F32*/VX_DF_IMAGE('F', '0', '3', '2'):
|
||||
return 1;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// Create vx_imagepatch_addressing_t structure with default values
|
||||
static vx_imagepatch_addressing_t createAddressing()
|
||||
{ vx_imagepatch_addressing_t ipa = VX_IMAGEPATCH_ADDR_INIT; return ipa; }
|
||||
|
||||
/// Create vx_imagepatch_addressing_t structure with the provided values
|
||||
static vx_imagepatch_addressing_t createAddressing(
|
||||
vx_uint32 dimX, vx_uint32 dimY,
|
||||
vx_int32 strideX, vx_int32 strideY,
|
||||
vx_uint32 scaleX = VX_SCALE_UNITY, vx_uint32 scaleY = VX_SCALE_UNITY )
|
||||
{
|
||||
if (std::abs(strideY) < std::abs(strideX*(vx_int32)dimX))
|
||||
throw WrapperError(std::string(__func__)+"(): invalid arguments");
|
||||
vx_imagepatch_addressing_t ipa = VX_IMAGEPATCH_ADDR_INIT;
|
||||
ipa.dim_x = dimX;
|
||||
ipa.dim_y = dimY;
|
||||
ipa.stride_x = strideX;
|
||||
ipa.stride_y = strideY;
|
||||
ipa.scale_x = scaleX;
|
||||
ipa.scale_y = scaleY;
|
||||
return ipa;
|
||||
}
|
||||
|
||||
/// Create vx_imagepatch_addressing_t structure for the specified image plane and its valid region
|
||||
vx_imagepatch_addressing_t createAddressing(vx_uint32 planeIdx)
|
||||
{ return createAddressing(planeIdx, getValidRegion()); }
|
||||
|
||||
/// Create vx_imagepatch_addressing_t structure for the specified image plane and the provided region
|
||||
vx_imagepatch_addressing_t createAddressing(vx_uint32 planeIdx, const vx_rectangle_t& rect)
|
||||
{
|
||||
vx_uint32 w = rect.end_x-rect.start_x, h = rect.end_y-rect.start_y;
|
||||
vx_size patchBytes = computePatchSize(planeIdx, rect);
|
||||
vx_imagepatch_addressing_t ipa = createAddressing(w, h, (vx_int32)(patchBytes/w/h), (vx_int32)(patchBytes/h));
|
||||
return ipa;
|
||||
}
|
||||
|
||||
#ifndef VX_VERSION_1_1
|
||||
static const vx_enum VX_MEMORY_TYPE_HOST = VX_IMPORT_TYPE_HOST;
|
||||
#endif
|
||||
/// vxCreateImageFromHandle() wrapper
|
||||
static Image createFromHandle(
|
||||
vx_context context, vx_df_image format,
|
||||
const std::vector<vx_imagepatch_addressing_t>& addrs,
|
||||
const std::vector<void*>& ptrs, vx_enum memType = VX_MEMORY_TYPE_HOST )
|
||||
{
|
||||
vx_size num = planes(format);
|
||||
if(num == 0)
|
||||
throw WrapperError(std::string(__func__)+"(): unknown/unexpected planes number for the requested format");
|
||||
if (addrs.size() != num || ptrs.size() != num)
|
||||
throw WrapperError(std::string(__func__)+"(): incomplete input");
|
||||
#ifdef VX_VERSION_1_1
|
||||
return Image(vxCreateImageFromHandle(context, format, &addrs[0], &ptrs[0], memType));
|
||||
#else
|
||||
return Image( vxCreateImageFromHandle(context, format,
|
||||
const_cast<vx_imagepatch_addressing_t*>(&addrs[0]),
|
||||
const_cast<void**>(&ptrs[0]), memType) );
|
||||
#endif
|
||||
}
|
||||
|
||||
/// vxCreateImageFromHandle() wrapper for a single plane image
|
||||
static Image createFromHandle(vx_context context, vx_df_image format,const vx_imagepatch_addressing_t& addr, void* ptr)
|
||||
{
|
||||
if(planes(format) != 1) throw WrapperError(std::string(__func__)+"(): not a single plane format");
|
||||
return Image(vxCreateImageFromHandle(context, format, const_cast<vx_imagepatch_addressing_t*> (&addr), &ptr, VX_MEMORY_TYPE_HOST));
|
||||
}
|
||||
|
||||
#ifdef VX_VERSION_1_1
|
||||
/// vxSwapImageHandle() wrapper
|
||||
/// \param newPtrs keeps addresses of new image planes data, can be of image planes size or empty when new pointers are not provided
|
||||
/// \param prevPtrs storage for the previous addresses of image planes data, can be of image planes size or empty when previous pointers are not needed
|
||||
void swapHandle(const std::vector<void*>& newPtrs, std::vector<void*>& prevPtrs)
|
||||
{
|
||||
vx_size num = planes();
|
||||
if(num == 0)
|
||||
throw WrapperError(std::string(__func__)+"(): unexpected planes number");
|
||||
if (!newPtrs.empty() && newPtrs.size() != num)
|
||||
throw WrapperError(std::string(__func__)+"(): unexpected number of input pointers");
|
||||
if (!prevPtrs.empty() && prevPtrs.size() != num)
|
||||
throw WrapperError(std::string(__func__)+"(): unexpected number of output pointers");
|
||||
IVX_CHECK_STATUS( vxSwapImageHandle( ref,
|
||||
newPtrs.empty() ? 0 : &newPtrs[0],
|
||||
prevPtrs.empty() ? 0 : &prevPtrs[0],
|
||||
num ) );
|
||||
}
|
||||
|
||||
/// vxSwapImageHandle() wrapper for a single plane image
|
||||
/// \param newPtr an address of new image data, can be zero when new pointer is not provided
|
||||
/// \return the previuos address of image data
|
||||
void* swapHandle(void* newPtr)
|
||||
{
|
||||
if(planes() != 1) throw WrapperError(std::string(__func__)+"(): not a single plane image");
|
||||
void* prevPtr = 0;
|
||||
IVX_CHECK_STATUS( vxSwapImageHandle(ref, &newPtr, &prevPtr, 1) );
|
||||
return prevPtr;
|
||||
}
|
||||
|
||||
/// vxSwapImageHandle() wrapper for the case when no new pointers provided and previous ones are not needed (retrive memory back)
|
||||
void swapHandle()
|
||||
{ IVX_CHECK_STATUS( vxSwapImageHandle(ref, 0, 0, 0) ); }
|
||||
|
||||
/// vxCreateImageFromChannel() wrapper
|
||||
Image createFromChannel(vx_enum channel)
|
||||
{ return Image(vxCreateImageFromChannel(ref, channel)); }
|
||||
#endif // VX_VERSION_1_1
|
||||
|
||||
/// vxQueryImage() wrapper
|
||||
template<typename T>
|
||||
void query(vx_enum att, T& value) const
|
||||
{ IVX_CHECK_STATUS( vxQueryImage(ref, att, &value, sizeof(value)) ); }
|
||||
|
||||
#ifndef VX_VERSION_1_1
|
||||
static const vx_enum
|
||||
VX_IMAGE_WIDTH = VX_IMAGE_ATTRIBUTE_WIDTH,
|
||||
VX_IMAGE_HEIGHT = VX_IMAGE_ATTRIBUTE_HEIGHT,
|
||||
VX_IMAGE_FORMAT = VX_IMAGE_ATTRIBUTE_FORMAT,
|
||||
VX_IMAGE_PLANES = VX_IMAGE_ATTRIBUTE_PLANES,
|
||||
VX_IMAGE_SPACE = VX_IMAGE_ATTRIBUTE_SPACE,
|
||||
VX_IMAGE_RANGE = VX_IMAGE_ATTRIBUTE_RANGE,
|
||||
VX_IMAGE_SIZE = VX_IMAGE_ATTRIBUTE_SIZE;
|
||||
#endif
|
||||
|
||||
/// vxQueryImage(VX_IMAGE_WIDTH) wrapper
|
||||
vx_uint32 width() const
|
||||
{
|
||||
vx_uint32 v;
|
||||
query(VX_IMAGE_WIDTH, v);
|
||||
return v;
|
||||
}
|
||||
|
||||
/// vxQueryImage(VX_IMAGE_HEIGHT) wrapper
|
||||
vx_uint32 height() const
|
||||
{
|
||||
vx_uint32 v;
|
||||
query(VX_IMAGE_HEIGHT, v);
|
||||
return v;
|
||||
}
|
||||
|
||||
/// vxQueryImage(VX_IMAGE_FORMAT) wrapper
|
||||
vx_df_image format() const
|
||||
{
|
||||
vx_df_image v;
|
||||
query(VX_IMAGE_FORMAT, v);
|
||||
return v;
|
||||
}
|
||||
|
||||
/// vxQueryImage(VX_IMAGE_PLANES) wrapper
|
||||
vx_size planes() const
|
||||
{
|
||||
vx_size v;
|
||||
query(VX_IMAGE_PLANES, v);
|
||||
return v;
|
||||
}
|
||||
|
||||
/// vxQueryImage(VX_IMAGE_SPACE) wrapper
|
||||
vx_enum space() const
|
||||
{
|
||||
vx_enum v;
|
||||
query(VX_IMAGE_SPACE, v);
|
||||
return v;
|
||||
}
|
||||
|
||||
/// vxQueryImage(VX_IMAGE_RANGE) wrapper
|
||||
vx_enum range() const
|
||||
{
|
||||
vx_enum v;
|
||||
query(VX_IMAGE_RANGE, v);
|
||||
return v;
|
||||
}
|
||||
|
||||
/// vxQueryImage(VX_IMAGE_SIZE) wrapper
|
||||
vx_size size() const
|
||||
{
|
||||
vx_size v;
|
||||
query(VX_IMAGE_SIZE, v);
|
||||
return v;
|
||||
}
|
||||
|
||||
#ifdef VX_VERSION_1_1
|
||||
/// vxQueryImage(VX_IMAGE_MEMORY_TYPE) wrapper
|
||||
vx_memory_type_e memType() const
|
||||
{
|
||||
vx_memory_type_e v;
|
||||
query(VX_IMAGE_MEMORY_TYPE, v);
|
||||
return v;
|
||||
}
|
||||
#endif // VX_VERSION_1_1
|
||||
|
||||
/// vxSetImageAttribute() wrapper
|
||||
template<typename T>
|
||||
void setAttribute(vx_enum att, T& value) const
|
||||
{ IVX_CHECK_STATUS(vxSetImageAttribute(ref, att, &value, sizeof(value))); }
|
||||
|
||||
/// vxSetImageAttribute(SPACE) wrapper
|
||||
void setColorSpace(const vx_enum& sp)
|
||||
{ setAttribute(VX_IMAGE_SPACE, sp); }
|
||||
|
||||
/// vxGetValidRegionImage() wrapper
|
||||
vx_rectangle_t getValidRegion() const
|
||||
{
|
||||
vx_rectangle_t rect;
|
||||
IVX_CHECK_STATUS( vxGetValidRegionImage(ref, &rect) );
|
||||
return rect;
|
||||
}
|
||||
|
||||
/// vxComputeImagePatchSize(valid region) wrapper
|
||||
vx_size computePatchSize(vx_uint32 planeIdx)
|
||||
{ return computePatchSize(planeIdx, getValidRegion()); }
|
||||
|
||||
/// vxComputeImagePatchSize() wrapper
|
||||
vx_size computePatchSize(vx_uint32 planeIdx, const vx_rectangle_t& rect)
|
||||
{
|
||||
vx_size bytes = vxComputeImagePatchSize(ref, &rect, planeIdx);
|
||||
if (bytes == 0) throw WrapperError(std::string(__func__)+"(): vxComputeImagePatchSize returned 0");
|
||||
return bytes;
|
||||
}
|
||||
|
||||
#ifdef VX_VERSION_1_1
|
||||
/// vxSetImageValidRectangle() wrapper
|
||||
void setValidRectangle(const vx_rectangle_t& rect)
|
||||
{ IVX_CHECK_STATUS( vxSetImageValidRectangle(ref, &rect) ); }
|
||||
#endif // VX_VERSION_1_1
|
||||
|
||||
/// Copy image plane content to the provided memory
|
||||
void copyTo(vx_uint32 planeIdx, const vx_imagepatch_addressing_t& addr, void* data)
|
||||
{
|
||||
if(!data) throw WrapperError(std::string(__func__)+"(): output pointer is 0");
|
||||
vx_rectangle_t r = getValidRegion();
|
||||
// TODO: add sizes consistency checks
|
||||
/*
|
||||
vx_uint32 w = r.end_x - r.start_x, h = r.end_y - r.start_y;
|
||||
if (w != addr.dim_x) throw WrapperError("Image::copyTo(): inconsistent dimension X");
|
||||
if (h != addr.dim_y) throw WrapperError("Image::copyTo(): inconsistent dimension Y");
|
||||
*/
|
||||
#ifdef VX_VERSION_1_1
|
||||
IVX_CHECK_STATUS(vxCopyImagePatch(ref, &r, planeIdx, &addr, data, VX_READ_ONLY, VX_MEMORY_TYPE_HOST));
|
||||
#else
|
||||
vx_imagepatch_addressing_t* a = const_cast<vx_imagepatch_addressing_t*>(&addr);
|
||||
IVX_CHECK_STATUS(vxAccessImagePatch(ref, &r, planeIdx, a, &data, VX_READ_ONLY));
|
||||
IVX_CHECK_STATUS(vxCommitImagePatch(ref, 0, planeIdx, a, data));
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Copy the provided memory data to the specified image plane
|
||||
void copyFrom(vx_uint32 planeIdx, const vx_imagepatch_addressing_t& addr, const void* data)
|
||||
{
|
||||
if (!data) throw WrapperError(std::string(__func__)+"(): input pointer is 0");
|
||||
vx_rectangle_t r = getValidRegion();
|
||||
// TODO: add sizes consistency checks
|
||||
/*
|
||||
vx_uint32 w = r.end_x - r.start_x, h = r.end_y - r.start_y;
|
||||
//vx_size patchBytes = vxComputeImagePatchSize(ref, &r, planeIdx);
|
||||
if (w != addr.dim_x) throw WrapperError("Image::copyFrom(): inconsistent dimension X");
|
||||
if (h != addr.dim_y) throw WrapperError("Image::copyFrom(): inconsistent dimension Y");
|
||||
*/
|
||||
#ifdef VX_VERSION_1_1
|
||||
IVX_CHECK_STATUS(vxCopyImagePatch(ref, &r, planeIdx, &addr, (void*)data, VX_WRITE_ONLY, VX_MEMORY_TYPE_HOST));
|
||||
#else
|
||||
vx_imagepatch_addressing_t* a = const_cast<vx_imagepatch_addressing_t*>(&addr);
|
||||
IVX_CHECK_STATUS(vxAccessImagePatch(ref, &r, planeIdx, a, const_cast<void**>(&data), VX_WRITE_ONLY));
|
||||
IVX_CHECK_STATUS(vxCommitImagePatch(ref, &r, planeIdx, a, data));
|
||||
#endif
|
||||
}
|
||||
|
||||
/// vxCopyImagePatch() wrapper (or vxAccessImagePatch() + vxCommitImagePatch() for OpenVX 1.0)
|
||||
void copy( vx_uint32 planeIdx, vx_rectangle_t rect,
|
||||
const vx_imagepatch_addressing_t& addr, void* data,
|
||||
vx_enum usage, vx_enum memoryType = VX_MEMORY_TYPE_HOST )
|
||||
{
|
||||
#ifdef VX_VERSION_1_1
|
||||
IVX_CHECK_STATUS(vxCopyImagePatch(ref, &rect, planeIdx, &addr, (void*)data, usage, memoryType));
|
||||
#else
|
||||
(void)memoryType;
|
||||
vx_imagepatch_addressing_t* a = const_cast<vx_imagepatch_addressing_t*>(&addr);
|
||||
IVX_CHECK_STATUS(vxAccessImagePatch(ref, &rect, planeIdx, a, &data, usage));
|
||||
IVX_CHECK_STATUS(vxCommitImagePatch(ref, &rect, planeIdx, a, data));
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef IVX_USE_OPENCV
|
||||
/// Convert image format (fourcc) to cv::Mat type, throws WrapperError if not possible
|
||||
static int formatToMatType(vx_df_image format, vx_uint32 planeIdx = 0)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case VX_DF_IMAGE_RGB: return CV_8UC3;
|
||||
case VX_DF_IMAGE_RGBX: return CV_8UC4;
|
||||
case VX_DF_IMAGE_U8: return CV_8UC1;
|
||||
case VX_DF_IMAGE_U16: return CV_16UC1;
|
||||
case VX_DF_IMAGE_S16: return CV_16SC1;
|
||||
case VX_DF_IMAGE_U32:
|
||||
case VX_DF_IMAGE_S32: return CV_32SC1;
|
||||
case VX_DF_IMAGE('F', '0', '3', '2'):
|
||||
return CV_32FC1;
|
||||
case VX_DF_IMAGE_YUV4:
|
||||
case VX_DF_IMAGE_IYUV: return CV_8UC1;
|
||||
case VX_DF_IMAGE_UYVY:
|
||||
case VX_DF_IMAGE_YUYV: return CV_8UC2;
|
||||
case VX_DF_IMAGE_NV12:
|
||||
case VX_DF_IMAGE_NV21: return planeIdx == 0 ? CV_8UC1 : CV_8UC2;
|
||||
default: throw WrapperError(std::string(__func__)+"(): unsupported image format");
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert cv::Mat type to standard image format (fourcc), throws WrapperError if not possible
|
||||
static vx_df_image matTypeToFormat(int matType)
|
||||
{
|
||||
switch (matType)
|
||||
{
|
||||
case CV_8UC4: return VX_DF_IMAGE_RGBX;
|
||||
case CV_8UC3: return VX_DF_IMAGE_RGB;
|
||||
case CV_8UC1: return VX_DF_IMAGE_U8;
|
||||
case CV_16UC1: return VX_DF_IMAGE_U16;
|
||||
case CV_16SC1: return VX_DF_IMAGE_S16;
|
||||
case CV_32SC1: return VX_DF_IMAGE_S32;
|
||||
case CV_32FC1: return VX_DF_IMAGE('F', '0', '3', '2');
|
||||
default: throw WrapperError(std::string(__func__)+"(): unsupported cv::Mat type");
|
||||
}
|
||||
}
|
||||
|
||||
/// Initialize cv::Mat shape to fit the specified image plane data
|
||||
void createMatForPlane(cv::Mat& m, vx_uint32 planeIdx)
|
||||
{
|
||||
vx_df_image f = format();
|
||||
//vx_uint32 w = width(), h = height();
|
||||
vx_rectangle_t r = getValidRegion();
|
||||
vx_int32 w = vx_int32(r.end_x - r.start_x), h = vx_int32(r.end_y - r.start_y);
|
||||
switch (f)
|
||||
{
|
||||
case VX_DF_IMAGE_IYUV:
|
||||
if (planeIdx == 0u) m.create(h, w, formatToMatType(f));
|
||||
else if (planeIdx == 1u || planeIdx == 2u) m.create(h/2, w/2, formatToMatType(f));
|
||||
else throw WrapperError(std::string(__func__)+"(): wrong plane index");
|
||||
break;
|
||||
case VX_DF_IMAGE_YUV4:
|
||||
if (planeIdx == 0u || planeIdx == 1u || planeIdx == 2u) m.create(h, w, formatToMatType(f));
|
||||
else throw WrapperError(std::string(__func__)+"(): wrong plane index");
|
||||
break;
|
||||
case VX_DF_IMAGE_NV12:
|
||||
case VX_DF_IMAGE_NV21:
|
||||
if (planeIdx == 0u) m.create(h, w, formatToMatType(f, 0));
|
||||
else if (planeIdx == 1u) m.create(h/2, w/2, formatToMatType(f, 1));
|
||||
else throw WrapperError(std::string(__func__)+"(): wrong plane index");
|
||||
break;
|
||||
case VX_DF_IMAGE_RGB:
|
||||
case VX_DF_IMAGE_RGBX:
|
||||
case VX_DF_IMAGE_UYVY:
|
||||
case VX_DF_IMAGE_YUYV:
|
||||
case VX_DF_IMAGE_U8:
|
||||
case VX_DF_IMAGE_U16:
|
||||
case VX_DF_IMAGE_S16:
|
||||
case VX_DF_IMAGE_U32:
|
||||
case VX_DF_IMAGE_S32:
|
||||
case /*VX_DF_IMAGE_F32*/VX_DF_IMAGE('F', '0', '3', '2'):
|
||||
if(planeIdx == 0u) m.create(h, w, formatToMatType(f));
|
||||
else throw WrapperError(std::string(__func__)+"(): wrong plane index");
|
||||
break;
|
||||
default: throw WrapperError(std::string(__func__)+"(): unsupported color format");
|
||||
}
|
||||
}
|
||||
|
||||
/// Create vx_imagepatch_addressing_t corresponding to the provided cv::Mat
|
||||
static vx_imagepatch_addressing_t createAddressing(const cv::Mat& m)
|
||||
{
|
||||
if(m.empty()) throw WrapperError(std::string(__func__)+"(): empty input Mat");
|
||||
return createAddressing((vx_uint32)m.cols, (vx_uint32)m.rows, (vx_int32)m.elemSize(), (vx_int32)m.step);
|
||||
}
|
||||
|
||||
/// Copy image plane content to the provided cv::Mat (reallocate if needed)
|
||||
void copyTo(vx_uint32 planeIdx, cv::Mat& m)
|
||||
{
|
||||
createMatForPlane(m, planeIdx);
|
||||
copyTo(planeIdx, createAddressing((vx_uint32)m.cols, (vx_uint32)m.rows, (vx_int32)m.elemSize(), (vx_int32)m.step), m.ptr());
|
||||
}
|
||||
|
||||
/// Copy the provided cv::Mat data to the specified image plane
|
||||
void copyFrom(vx_uint32 planeIdx, const cv::Mat& m)
|
||||
{
|
||||
if(m.empty()) throw WrapperError(std::string(__func__)+"(): empty input Mat");
|
||||
// TODO: add sizes consistency checks
|
||||
//vx_rectangle_t r = getValidRegion();
|
||||
copyFrom(planeIdx, createAddressing((vx_uint32)m.cols, (vx_uint32)m.rows, (vx_int32)m.elemSize(), (vx_int32)m.step), m.ptr());
|
||||
}
|
||||
|
||||
/*
|
||||
private:
|
||||
cv::Mat _mat; // TODO: update copy/move-c-tors, operator=() and swapHandles()
|
||||
public:
|
||||
static Image createFromHandle(vx_context context, const cv::Mat& mat)
|
||||
{
|
||||
if(mat.empty()) throw WrapperError(std::string(__func__)+"(): empty cv::Mat");
|
||||
Image res = createFromHandle(context, matTypeToFormat(mat.type()), createAddressing(mat), mat.data );
|
||||
res._mat = mat;
|
||||
return res;
|
||||
}
|
||||
*/
|
||||
#endif //IVX_USE_OPENCV
|
||||
|
||||
struct Patch;
|
||||
};
|
||||
|
||||
/// Helper class for a mapping vx_image patch
|
||||
struct Image::Patch
|
||||
{
|
||||
public:
|
||||
/// reference to the current vx_imagepatch_addressing_t
|
||||
const vx_imagepatch_addressing_t& addr() const
|
||||
{ return _addr;}
|
||||
|
||||
/// current pixels data pointer
|
||||
void* data() const
|
||||
{ return _data; }
|
||||
|
||||
#ifdef VX_VERSION_1_1
|
||||
/// vx_memory_type_e for the current data pointer
|
||||
vx_memory_type_e memType() const
|
||||
{ return _memType; }
|
||||
|
||||
/// vx_map_id for the current mapping
|
||||
vx_map_id mapId() const
|
||||
{ return _mapId; }
|
||||
#else
|
||||
/// reference to vx_rectangle_t for the current mapping
|
||||
const vx_rectangle_t& rectangle() const
|
||||
{ return _rect; }
|
||||
|
||||
/// Image plane index for the current mapping
|
||||
vx_uint32 planeIndex() const
|
||||
{ return _planeIdx; }
|
||||
#endif // VX_VERSION_1_1
|
||||
|
||||
/// vx_image for the current mapping
|
||||
vx_image image() const
|
||||
{ return _img; }
|
||||
|
||||
/// where this patch is mapped
|
||||
bool isMapped() const
|
||||
{ return _img != 0; }
|
||||
|
||||
#ifdef IVX_USE_OPENCV
|
||||
/// Reference to cv::Mat instance wrapping the mapped image data, becomes invalid after unmap()
|
||||
cv::Mat& getMat()
|
||||
{ return _m; }
|
||||
#endif //IVX_USE_OPENCV
|
||||
|
||||
protected:
|
||||
vx_imagepatch_addressing_t _addr;
|
||||
void* _data;
|
||||
vx_image _img;
|
||||
#ifdef VX_VERSION_1_1
|
||||
vx_memory_type_e _memType;
|
||||
vx_map_id _mapId;
|
||||
#else
|
||||
vx_rectangle_t _rect;
|
||||
vx_uint32 _planeIdx;
|
||||
#endif
|
||||
#ifdef IVX_USE_OPENCV
|
||||
cv::Mat _m;
|
||||
#endif
|
||||
|
||||
public:
|
||||
/// Default constructor
|
||||
Patch() : _addr(createAddressing()), _data(0), _img(0)
|
||||
#ifdef VX_VERSION_1_1
|
||||
, _memType(VX_MEMORY_TYPE_HOST), _mapId(0)
|
||||
{}
|
||||
#else
|
||||
, _planeIdx(-1)
|
||||
{ _rect.start_x = _rect.end_x = _rect.start_y = _rect.end_y = 0u; }
|
||||
#endif
|
||||
|
||||
#ifndef IVX_USE_CXX98
|
||||
/// Move constructor
|
||||
Patch(Patch&& p) : Patch()
|
||||
{
|
||||
using std::swap;
|
||||
swap(_addr, p._addr);
|
||||
swap(_data, p._data);
|
||||
#ifdef VX_VERSION_1_1
|
||||
swap(_memType, p._memType);
|
||||
swap(_mapId, p._mapId);
|
||||
#else
|
||||
swap(_rect, p._rect);
|
||||
swap(_planeIdx, p._planeIdx);
|
||||
#endif
|
||||
swap(_img, p._img);
|
||||
#ifdef IVX_USE_OPENCV
|
||||
swap(_m, p._m);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/// vxMapImagePatch(VX_READ_ONLY, planeIdx valid region)
|
||||
void map(vx_image img, vx_uint32 planeIdx)
|
||||
{ map(img, planeIdx, Image(img, true).getValidRegion()); }
|
||||
|
||||
/// vxMapImagePatch() wrapper (or vxAccessImagePatch() for 1.0)
|
||||
void map(vx_image img, vx_uint32 planeIdx, const vx_rectangle_t& rect, vx_enum usage = VX_READ_ONLY, vx_uint32 flags = 0)
|
||||
{
|
||||
if (isMapped()) throw WrapperError(std::string(__func__)+"(): already mapped");
|
||||
#ifdef VX_VERSION_1_1
|
||||
IVX_CHECK_STATUS(vxMapImagePatch(img, &rect, planeIdx, &_mapId, &_addr, &_data, usage, _memType, flags) );
|
||||
#else
|
||||
IVX_CHECK_STATUS(vxAccessImagePatch(img, &rect, planeIdx, &_addr, &_data, usage));
|
||||
(void)flags;
|
||||
_rect = rect;
|
||||
_planeIdx = planeIdx;
|
||||
#endif
|
||||
if (_data == 0) throw WrapperError(std::string(__func__)+"(): mapped address is null");
|
||||
_img = img;
|
||||
#ifdef IVX_USE_OPENCV
|
||||
vx_df_image format;
|
||||
IVX_CHECK_STATUS( vxQueryImage(_img, VX_IMAGE_FORMAT, &format, sizeof(format)) );
|
||||
int matType = formatToMatType(format);
|
||||
_m = cv::Mat( vx_int32((vx_int64)_addr.dim_y * VX_SCALE_UNITY / _addr.scale_y),
|
||||
vx_int32((vx_int64)_addr.dim_x * VX_SCALE_UNITY / _addr.scale_x),
|
||||
matType, _data, std::size_t(_addr.stride_y) );
|
||||
#endif
|
||||
}
|
||||
|
||||
/// vxUnmapImagePatch() wrapper (or vxCommitImagePatch() for 1.0)
|
||||
void unmap()
|
||||
{
|
||||
#ifdef VX_VERSION_1_1
|
||||
IVX_CHECK_STATUS(vxUnmapImagePatch(_img, _mapId));
|
||||
_mapId = 0;
|
||||
#else
|
||||
IVX_CHECK_STATUS(vxCommitImagePatch(_img, &_rect, _planeIdx, &_addr, _data));
|
||||
_rect.start_x = _rect.end_x = _rect.start_y = _rect.end_y = 0u;
|
||||
_planeIdx = -1;
|
||||
|
||||
#endif
|
||||
_img = 0;
|
||||
_data = 0;
|
||||
_addr = createAddressing();
|
||||
#ifdef IVX_USE_OPENCV
|
||||
_m.release();
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Destructor
|
||||
~Patch()
|
||||
{ try { if (_img) unmap(); } catch(...) {; /*ignore*/} }
|
||||
|
||||
/// Pointer to the specified pixel data (vxFormatImagePatchAddress2d)
|
||||
void* pixelPtr(vx_uint32 x, vx_uint32 y)
|
||||
{
|
||||
if (!_data) throw WrapperError(std::string(__func__)+"(): base pointer is NULL");
|
||||
if (x >= _addr.dim_x) throw WrapperError(std::string(__func__)+"(): X out of range");
|
||||
if (y >= _addr.dim_y) throw WrapperError(std::string(__func__)+"(): Y out of range");
|
||||
return vxFormatImagePatchAddress2d(_data, x, y, &_addr);
|
||||
}
|
||||
|
||||
private:
|
||||
Patch(const Patch& p); // = delete
|
||||
Patch& operator=(const Patch&); // = delete
|
||||
#ifndef IVX_USE_CXX98
|
||||
Patch& operator=(Patch&&); // = delete
|
||||
#endif
|
||||
};
|
||||
|
||||
/// vx_parameter wrapper
|
||||
class Param : public RefWrapper<vx_parameter>
|
||||
{
|
||||
public:
|
||||
IVX_REF_STD_CTORS_AND_ASSIGNMENT(Param);
|
||||
// NYI
|
||||
};
|
||||
|
||||
/// vx_scalar wrapper
|
||||
class Scalar : public RefWrapper<vx_scalar>
|
||||
{
|
||||
public:
|
||||
IVX_REF_STD_CTORS_AND_ASSIGNMENT(Scalar);
|
||||
|
||||
/// vxCreateScalar() wrapper
|
||||
static Scalar create(vx_context c, vx_enum dataType, const void *ptr)
|
||||
{ return Scalar( vxCreateScalar(c, dataType, ptr) ); }
|
||||
|
||||
/// vxCreateScalar() wrapper, value is passed as a value not as a pointer
|
||||
template<typename T> static Scalar create(vx_context c, vx_enum dataType, T value)
|
||||
{
|
||||
typedef int static_assert_not_pointer[is_pointer<T>::value ? -1 : 1];
|
||||
return Scalar( vxCreateScalar(c, dataType, &value) );
|
||||
}
|
||||
|
||||
/// vxCreateScalar() wrapper, data type is guessed based on the passed value
|
||||
template<vx_enum E> static Scalar create(vx_context c, typename EnumToType<E>::type value)
|
||||
{ return Scalar( vxCreateScalar(c, E, &value) ); }
|
||||
|
||||
#ifndef VX_VERSION_1_1
|
||||
static const vx_enum VX_SCALAR_TYPE = VX_SCALAR_ATTRIBUTE_TYPE;
|
||||
#endif
|
||||
/// Get scalar data type
|
||||
vx_enum type()
|
||||
{
|
||||
vx_enum val;
|
||||
IVX_CHECK_STATUS( vxQueryScalar(ref, VX_SCALAR_TYPE, &val, sizeof(val)) );
|
||||
return val;
|
||||
}
|
||||
|
||||
/// Get scalar value
|
||||
template<typename T>
|
||||
void getValue(T& val)
|
||||
{
|
||||
if (!areTypesCompatible(TypeToEnum<T>::value, type()))
|
||||
throw WrapperError(std::string(__func__)+"(): incompatible types");
|
||||
#ifdef VX_VERSION_1_1
|
||||
IVX_CHECK_STATUS( vxCopyScalar(ref, &val, VX_READ_ONLY, VX_MEMORY_TYPE_HOST) );
|
||||
#else
|
||||
IVX_CHECK_STATUS( vxReadScalarValue(ref, &val) );
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Get scalar value
|
||||
template<typename T>
|
||||
T getValue()
|
||||
{
|
||||
T val;
|
||||
getValue(val);
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
/// Set scalar value
|
||||
template<typename T>
|
||||
void setValue(T val)
|
||||
{
|
||||
if (!areTypesCompatible(TypeToEnum<T>::value, type()))
|
||||
throw WrapperError(std::string(__func__)+"(): incompatible types");
|
||||
#ifdef VX_VERSION_1_1
|
||||
IVX_CHECK_STATUS(vxCopyScalar(ref, &val, VX_WRITE_ONLY, VX_MEMORY_TYPE_HOST));
|
||||
#else
|
||||
IVX_CHECK_STATUS( vxWriteScalarValue(ref, &val) );
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
/// vx_threshold wrapper
|
||||
class Threshold : public RefWrapper<vx_threshold>
|
||||
{
|
||||
public:
|
||||
IVX_REF_STD_CTORS_AND_ASSIGNMENT(Threshold);
|
||||
|
||||
/// vxCreateThreshold() wrapper
|
||||
static Threshold create(vx_context c, vx_enum threshType, vx_enum dataType)
|
||||
{ return Threshold(vxCreateThreshold(c, threshType, dataType)); }
|
||||
|
||||
#ifndef VX_VERSION_1_1
|
||||
static const vx_enum
|
||||
VX_THRESHOLD_TYPE = VX_THRESHOLD_ATTRIBUTE_TYPE,
|
||||
VX_THRESHOLD_THRESHOLD_VALUE = VX_THRESHOLD_ATTRIBUTE_THRESHOLD_VALUE,
|
||||
VX_THRESHOLD_THRESHOLD_LOWER = VX_THRESHOLD_ATTRIBUTE_THRESHOLD_LOWER,
|
||||
VX_THRESHOLD_THRESHOLD_UPPER = VX_THRESHOLD_ATTRIBUTE_THRESHOLD_UPPER,
|
||||
VX_THRESHOLD_TRUE_VALUE = VX_THRESHOLD_ATTRIBUTE_TRUE_VALUE,
|
||||
VX_THRESHOLD_FALSE_VALUE = VX_THRESHOLD_ATTRIBUTE_FALSE_VALUE,
|
||||
VX_THRESHOLD_DATA_TYPE = VX_THRESHOLD_ATTRIBUTE_DATA_TYPE;
|
||||
#endif
|
||||
|
||||
|
||||
/// Create binary threshold with the provided value
|
||||
static Threshold createBinary(vx_context c, vx_enum dataType, vx_int32 val)
|
||||
{
|
||||
Threshold thr = create(c, VX_THRESHOLD_TYPE_BINARY, dataType);
|
||||
IVX_CHECK_STATUS( vxSetThresholdAttribute(thr.ref, VX_THRESHOLD_THRESHOLD_VALUE, &val, sizeof(val)) );
|
||||
return thr;
|
||||
}
|
||||
|
||||
/// Create range threshold with the provided low and high values
|
||||
static Threshold createRange(vx_context c, vx_enum dataType, vx_int32 valLower, vx_int32 valUpper)
|
||||
{
|
||||
Threshold thr = create(c, VX_THRESHOLD_TYPE_RANGE, dataType);
|
||||
IVX_CHECK_STATUS( vxSetThresholdAttribute(thr.ref, VX_THRESHOLD_THRESHOLD_LOWER, &valLower, sizeof(valLower)) );
|
||||
IVX_CHECK_STATUS( vxSetThresholdAttribute(thr.ref, VX_THRESHOLD_THRESHOLD_UPPER, &valUpper, sizeof(valUpper)) );
|
||||
return thr;
|
||||
}
|
||||
|
||||
/// vxQueryThreshold() wrapper
|
||||
template<typename T>
|
||||
void query(vx_enum att, T& val) const
|
||||
{ IVX_CHECK_STATUS( vxQueryThreshold(ref, att, &val, sizeof(val)) ); }
|
||||
|
||||
/// vxQueryThreshold(VX_THRESHOLD_TYPE) wrapper
|
||||
vx_enum type() const
|
||||
{
|
||||
vx_enum v;
|
||||
query(VX_THRESHOLD_TYPE, v);
|
||||
return v;
|
||||
}
|
||||
|
||||
/// vxQueryThreshold(DATA_TYPE) wrapper
|
||||
vx_enum dataType() const
|
||||
{
|
||||
vx_enum v;
|
||||
query(VX_THRESHOLD_DATA_TYPE, v);
|
||||
return v;
|
||||
}
|
||||
|
||||
/// vxQueryThreshold(THRESHOLD_VALUE) wrapper
|
||||
vx_int32 value() const
|
||||
{
|
||||
vx_int32 v;
|
||||
query(VX_THRESHOLD_THRESHOLD_VALUE, v);
|
||||
return v;
|
||||
}
|
||||
|
||||
/// vxQueryThreshold(THRESHOLD_LOWER) wrapper
|
||||
vx_int32 valueLower() const
|
||||
{
|
||||
vx_int32 v;
|
||||
query(VX_THRESHOLD_THRESHOLD_LOWER, v);
|
||||
return v;
|
||||
}
|
||||
|
||||
/// vxQueryThreshold(THRESHOLD_UPPER) wrapper
|
||||
vx_int32 valueUpper() const
|
||||
{
|
||||
vx_int32 v;
|
||||
query(VX_THRESHOLD_THRESHOLD_UPPER, v);
|
||||
return v;
|
||||
}
|
||||
|
||||
/// vxQueryThreshold(TRUE_VALUE) wrapper
|
||||
vx_int32 valueTrue() const
|
||||
{
|
||||
vx_int32 v;
|
||||
query(VX_THRESHOLD_TRUE_VALUE, v);
|
||||
return v;
|
||||
}
|
||||
|
||||
/// vxQueryThreshold(FALSE_VALUE) wrapper
|
||||
vx_int32 valueFalse() const
|
||||
{
|
||||
vx_int32 v;
|
||||
query(VX_THRESHOLD_FALSE_VALUE, v);
|
||||
return v;
|
||||
}
|
||||
|
||||
/// vxSetThresholdAttribute(THRESHOLD_VALUE) wrapper
|
||||
void setValue(vx_int32 &val)
|
||||
{ IVX_CHECK_STATUS(vxSetThresholdAttribute(ref, VX_THRESHOLD_THRESHOLD_VALUE, &val, sizeof(val))); }
|
||||
|
||||
/// vxSetThresholdAttribute(THRESHOLD_LOWER) wrapper
|
||||
void setValueLower(vx_int32 &val)
|
||||
{ IVX_CHECK_STATUS(vxSetThresholdAttribute(ref, VX_THRESHOLD_THRESHOLD_LOWER, &val, sizeof(val))); }
|
||||
|
||||
/// vxSetThresholdAttribute(THRESHOLD_UPPER) wrapper
|
||||
void setValueUpper(vx_int32 &val)
|
||||
{ IVX_CHECK_STATUS(vxSetThresholdAttribute(ref, VX_THRESHOLD_THRESHOLD_UPPER, &val, sizeof(val))); }
|
||||
|
||||
/// vxSetThresholdAttribute(TRUE_VALUE) wrapper
|
||||
void setValueTrue(vx_int32 &val)
|
||||
{ IVX_CHECK_STATUS(vxSetThresholdAttribute(ref, VX_THRESHOLD_TRUE_VALUE, &val, sizeof(val))); }
|
||||
|
||||
/// vxSetThresholdAttribute(FALSE_VALUE) wrapper
|
||||
void setValueFalse(vx_int32 &val)
|
||||
{ IVX_CHECK_STATUS(vxSetThresholdAttribute(ref, VX_THRESHOLD_FALSE_VALUE, &val, sizeof(val))); }
|
||||
};
|
||||
|
||||
/// vx_array wrapper
|
||||
class Array : public RefWrapper<vx_array>
|
||||
{
|
||||
public:
|
||||
IVX_REF_STD_CTORS_AND_ASSIGNMENT(Array);
|
||||
|
||||
/// vxCreateArray() wrapper
|
||||
static Array create(vx_context c, vx_enum type, vx_size capacity)
|
||||
{ return Array(vxCreateArray(c, type, capacity)); }
|
||||
|
||||
/// 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 addItems(vx_size count, const void* ptr, vx_size stride)
|
||||
{
|
||||
IVX_CHECK_STATUS(vxAddArrayItems(ref, count, ptr, stride));
|
||||
}
|
||||
|
||||
void truncateArray(vx_size new_count)
|
||||
{
|
||||
if(new_count <= itemCount())
|
||||
IVX_CHECK_STATUS(vxTruncateArray(ref, new_count));
|
||||
else
|
||||
throw WrapperError(std::string(__func__) + "(): array is too small");
|
||||
}
|
||||
|
||||
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 addItem(const T& item)
|
||||
{
|
||||
if (!areTypesCompatible(TypeToEnum<T>::value, itemType()))
|
||||
throw WrapperError(std::string(__func__) + "(): destination type is wrong");
|
||||
addItems(1, &item, sizeof(T));
|
||||
}
|
||||
|
||||
template<typename T> void addItems(const std::vector<T>& data)
|
||||
{
|
||||
if (!areTypesCompatible(TypeToEnum<T>::value, itemType()))
|
||||
throw WrapperError(std::string(__func__) + "(): destination type is wrong");
|
||||
addItems(data.size(), &data[0], itemSize());
|
||||
}
|
||||
|
||||
template<typename T> void copyRangeTo(size_t start, size_t end, std::vector<T>& data)
|
||||
{
|
||||
if (!areTypesCompatible(TypeToEnum<T>::value, itemType()))
|
||||
throw WrapperError(std::string(__func__) + "(): destination type is wrong");
|
||||
if (data.empty())
|
||||
data.resize((end - start));
|
||||
else if (data.size() != (end - start))
|
||||
{
|
||||
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 (!areTypesCompatible(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 addItems(cv::InputArray ia)
|
||||
{
|
||||
cv::Mat m = ia.getMat();
|
||||
if (m.type() != enumToCVType(itemType()))
|
||||
throw WrapperError(std::string(__func__) + "(): destination type is wrong");
|
||||
addItems(m.total(), m.isContinuous() ? m.ptr() : m.clone().ptr(),
|
||||
(vx_size)(m.elemSize()));
|
||||
}
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
/*
|
||||
* Convolution
|
||||
*/
|
||||
class Convolution : public RefWrapper<vx_convolution>
|
||||
{
|
||||
public:
|
||||
IVX_REF_STD_CTORS_AND_ASSIGNMENT(Convolution);
|
||||
|
||||
static Convolution create(vx_context context, vx_size columns, vx_size rows)
|
||||
{ return Convolution(vxCreateConvolution(context, columns, rows)); }
|
||||
|
||||
#ifndef VX_VERSION_1_1
|
||||
static const vx_enum
|
||||
VX_MEMORY_TYPE_HOST = VX_IMPORT_TYPE_HOST,
|
||||
VX_CONVOLUTION_ROWS = VX_CONVOLUTION_ATTRIBUTE_ROWS,
|
||||
VX_CONVOLUTION_COLUMNS = VX_CONVOLUTION_ATTRIBUTE_COLUMNS,
|
||||
VX_CONVOLUTION_SCALE = VX_CONVOLUTION_ATTRIBUTE_SCALE,
|
||||
VX_CONVOLUTION_SIZE = VX_CONVOLUTION_ATTRIBUTE_SIZE;
|
||||
#endif
|
||||
|
||||
template<typename T>
|
||||
void query(vx_enum att, T& value) const
|
||||
{ IVX_CHECK_STATUS( vxQueryConvolution(ref, att, &value, sizeof(value)) ); }
|
||||
|
||||
vx_size columns() const
|
||||
{
|
||||
vx_size v;
|
||||
query(VX_CONVOLUTION_COLUMNS, v);
|
||||
return v;
|
||||
}
|
||||
|
||||
vx_size rows() const
|
||||
{
|
||||
vx_size v;
|
||||
query(VX_CONVOLUTION_ROWS, v);
|
||||
return v;
|
||||
}
|
||||
|
||||
vx_uint32 scale() const
|
||||
{
|
||||
vx_uint32 v;
|
||||
query(VX_CONVOLUTION_SCALE, v);
|
||||
return v;
|
||||
}
|
||||
|
||||
vx_size size() const
|
||||
{
|
||||
vx_size v;
|
||||
query(VX_CONVOLUTION_SIZE, v);
|
||||
return v;
|
||||
}
|
||||
|
||||
vx_enum dataType()
|
||||
{
|
||||
return VX_TYPE_INT16;
|
||||
}
|
||||
|
||||
void setScale(vx_uint32 newScale)
|
||||
{ IVX_CHECK_STATUS( vxSetConvolutionAttribute(ref, VX_CONVOLUTION_SCALE, &newScale, sizeof(newScale)) ); }
|
||||
|
||||
void copyTo(void* data)
|
||||
{
|
||||
if (!data) throw WrapperError(std::string(__func__) + "(): output pointer is 0");
|
||||
#ifdef VX_VERSION_1_1
|
||||
IVX_CHECK_STATUS(vxCopyConvolutionCoefficients(ref, data, VX_READ_ONLY, VX_MEMORY_TYPE_HOST));
|
||||
#else
|
||||
IVX_CHECK_STATUS(vxReadConvolutionCoefficients(ref, (vx_int16 *)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(vxCopyConvolutionCoefficients(ref, const_cast<void*>(data), VX_WRITE_ONLY, VX_MEMORY_TYPE_HOST));
|
||||
#else
|
||||
IVX_CHECK_STATUS(vxWriteConvolutionCoefficients(ref, (const vx_int16 *)data));
|
||||
#endif
|
||||
}
|
||||
|
||||
void copy(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(vxCopyConvolutionCoefficients(ref, data, usage, memType));
|
||||
#else
|
||||
if (usage == VX_READ_ONLY)
|
||||
IVX_CHECK_STATUS(vxReadConvolutionCoefficients(ref, (vx_int16 *)data));
|
||||
else if (usage == VX_WRITE_ONLY)
|
||||
IVX_CHECK_STATUS(vxWriteConvolutionCoefficients(ref, (const vx_int16 *)data));
|
||||
else
|
||||
throw WrapperError(std::string(__func__) + "(): unknown copy direction");
|
||||
(void)memType;
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename T> void copyTo(std::vector<T>& data)
|
||||
{
|
||||
if (!areTypesCompatible(TypeToEnum<T>::value, dataType()))
|
||||
throw WrapperError(std::string(__func__) + "(): destination type is wrong");
|
||||
if (data.size()*sizeof(T) != size())
|
||||
{
|
||||
if (data.size() == 0)
|
||||
data.resize(size()/sizeof(T));
|
||||
else
|
||||
throw WrapperError(std::string(__func__) + "(): destination size is wrong");
|
||||
}
|
||||
copyTo(&data[0]);
|
||||
}
|
||||
|
||||
template<typename T> void copyFrom(const std::vector<T>& data)
|
||||
{
|
||||
if (!areTypesCompatible(TypeToEnum<T>::value, dataType()))
|
||||
throw WrapperError(std::string(__func__) + "(): source type is wrong");
|
||||
if (data.size()*sizeof(T) != size()) 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) != rows() || (vx_size)(m.cols) != columns()) && !m.empty())
|
||||
throw WrapperError(std::string(__func__) + "(): destination size is wrong");
|
||||
|
||||
if (m.isContinuous() && (vx_size)(m.rows) == rows() && (vx_size)(m.cols) == columns())
|
||||
{
|
||||
copyTo(m.ptr());
|
||||
}
|
||||
else
|
||||
{
|
||||
cv::Mat tmp((int)rows(), (int)columns(), 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) != rows() || (vx_size)(m.cols) != columns()) 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
|
||||
};
|
||||
|
||||
/*
|
||||
* Matrix
|
||||
*/
|
||||
class Matrix : public RefWrapper<vx_matrix>
|
||||
{
|
||||
public:
|
||||
IVX_REF_STD_CTORS_AND_ASSIGNMENT(Matrix);
|
||||
|
||||
static Matrix create(vx_context context, vx_enum dataType, vx_size columns, vx_size rows)
|
||||
{ return Matrix(vxCreateMatrix(context, dataType, columns, rows)); }
|
||||
|
||||
#ifdef VX_VERSION_1_1
|
||||
static Matrix createFromPattern(vx_context context, vx_enum pattern, vx_size columns, vx_size rows)
|
||||
{ return Matrix(vxCreateMatrixFromPattern(context, pattern, columns, rows)); }
|
||||
#endif
|
||||
|
||||
#ifndef VX_VERSION_1_1
|
||||
static const vx_enum
|
||||
VX_MEMORY_TYPE_HOST = VX_IMPORT_TYPE_HOST,
|
||||
VX_MATRIX_TYPE = VX_MATRIX_ATTRIBUTE_TYPE,
|
||||
VX_MATRIX_ROWS = VX_MATRIX_ATTRIBUTE_ROWS,
|
||||
VX_MATRIX_COLUMNS = VX_MATRIX_ATTRIBUTE_COLUMNS,
|
||||
VX_MATRIX_SIZE = VX_MATRIX_ATTRIBUTE_SIZE;
|
||||
#endif
|
||||
|
||||
template<typename T>
|
||||
void query(vx_enum att, T& value) const
|
||||
{ IVX_CHECK_STATUS( vxQueryMatrix(ref, att, &value, sizeof(value)) ); }
|
||||
|
||||
vx_enum dataType() const
|
||||
{
|
||||
vx_enum v;
|
||||
query(VX_MATRIX_TYPE, v);
|
||||
return v;
|
||||
}
|
||||
|
||||
vx_size columns() const
|
||||
{
|
||||
vx_size v;
|
||||
query(VX_MATRIX_COLUMNS, v);
|
||||
return v;
|
||||
}
|
||||
|
||||
vx_size rows() const
|
||||
{
|
||||
vx_size v;
|
||||
query(VX_MATRIX_ROWS, v);
|
||||
return v;
|
||||
}
|
||||
|
||||
vx_size size() const
|
||||
{
|
||||
vx_size v;
|
||||
query(VX_MATRIX_SIZE, v);
|
||||
return v;
|
||||
}
|
||||
|
||||
#ifdef VX_VERSION_1_1
|
||||
vx_coordinates2d_t origin() const
|
||||
{
|
||||
vx_coordinates2d_t v;
|
||||
query(VX_MATRIX_ORIGIN, v);
|
||||
return v;
|
||||
}
|
||||
|
||||
vx_enum pattern() const
|
||||
{
|
||||
vx_enum v;
|
||||
query(VX_MATRIX_PATTERN, 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(vxCopyMatrix(ref, data, VX_READ_ONLY, VX_MEMORY_TYPE_HOST));
|
||||
#else
|
||||
IVX_CHECK_STATUS(vxReadMatrix(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(vxCopyMatrix(ref, const_cast<void*>(data), VX_WRITE_ONLY, VX_MEMORY_TYPE_HOST));
|
||||
#else
|
||||
IVX_CHECK_STATUS(vxWriteMatrix(ref, data));
|
||||
#endif
|
||||
}
|
||||
|
||||
void copy(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(vxCopyMatrix(ref, data, usage, memType));
|
||||
#else
|
||||
if (usage == VX_READ_ONLY)
|
||||
IVX_CHECK_STATUS(vxReadMatrix(ref, data));
|
||||
else if (usage == VX_WRITE_ONLY)
|
||||
IVX_CHECK_STATUS(vxWriteMatrix(ref, data));
|
||||
else
|
||||
throw WrapperError(std::string(__func__) + "(): unknown copy direction");
|
||||
(void)memType;
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename T> void copyTo(std::vector<T>& data)
|
||||
{
|
||||
if (!areTypesCompatible(TypeToEnum<T>::value, dataType()))
|
||||
throw WrapperError(std::string(__func__) + "(): destination type is wrong");
|
||||
if (data.size()*sizeof(T) != size())
|
||||
{
|
||||
if (data.size() == 0)
|
||||
data.resize(size()/sizeof(T));
|
||||
else
|
||||
throw WrapperError(std::string(__func__) + "(): destination size is wrong");
|
||||
}
|
||||
copyTo(&data[0]);
|
||||
}
|
||||
|
||||
template<typename T> void copyFrom(const std::vector<T>& data)
|
||||
{
|
||||
if (!areTypesCompatible(TypeToEnum<T>::value, dataType()))
|
||||
throw WrapperError(std::string(__func__) + "(): source type is wrong");
|
||||
if (data.size()*sizeof(T) != size()) 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) != rows() || (vx_size)(m.cols) != columns()) && !m.empty())
|
||||
throw WrapperError(std::string(__func__) + "(): destination size is wrong");
|
||||
|
||||
if (m.isContinuous() && (vx_size)(m.rows) == rows() && (vx_size)(m.cols) == columns())
|
||||
{
|
||||
copyTo(m.ptr());
|
||||
}
|
||||
else
|
||||
{
|
||||
cv::Mat tmp((int)rows(), (int)columns(), 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) != rows() || (vx_size)(m.cols) != columns()) 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
|
||||
};
|
||||
|
||||
/*
|
||||
* LUT
|
||||
*/
|
||||
class LUT : public RefWrapper<vx_lut>
|
||||
{
|
||||
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<typename T>
|
||||
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<void*>(data), VX_WRITE_ONLY, VX_MEMORY_TYPE_HOST));
|
||||
#else
|
||||
IVX_CHECK_STATUS(vxAccessLUT(ref, const_cast<void**>(&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<void**>(&data), usage));
|
||||
IVX_CHECK_STATUS(vxCommitLUT(ref, data));
|
||||
(void)memType;
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename T> void copyTo(std::vector<T>& data)
|
||||
{
|
||||
if (!areTypesCompatible(TypeToEnum<T>::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<typename T> void copyFrom(const std::vector<T>& data)
|
||||
{
|
||||
if (!areTypesCompatible(TypeToEnum<T>::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
|
||||
};
|
||||
|
||||
/*
|
||||
* Pyramid
|
||||
*/
|
||||
class Pyramid : public RefWrapper<vx_pyramid>
|
||||
{
|
||||
public:
|
||||
IVX_REF_STD_CTORS_AND_ASSIGNMENT(Pyramid)
|
||||
|
||||
static Pyramid create(vx_context context, vx_size levels, vx_float32 scale,
|
||||
vx_uint32 width, vx_uint32 height, vx_df_image format)
|
||||
{return Pyramid(vxCreatePyramid(context, levels, scale, width, height, format));}
|
||||
|
||||
static Pyramid createVirtual(vx_graph graph, vx_size levels, vx_float32 scale,
|
||||
vx_uint32 width, vx_uint32 height, vx_df_image format)
|
||||
{return Pyramid(vxCreateVirtualPyramid(graph, levels, scale, width, height, format));}
|
||||
|
||||
#ifndef VX_VERSION_1_1
|
||||
static const vx_enum
|
||||
VX_PYRAMID_LEVELS = VX_PYRAMID_ATTRIBUTE_LEVELS,
|
||||
VX_PYRAMID_SCALE = VX_PYRAMID_ATTRIBUTE_SCALE,
|
||||
VX_PYRAMID_WIDTH = VX_PYRAMID_ATTRIBUTE_WIDTH,
|
||||
VX_PYRAMID_HEIGHT = VX_PYRAMID_ATTRIBUTE_HEIGHT,
|
||||
VX_PYRAMID_FORMAT = VX_PYRAMID_ATTRIBUTE_FORMAT;
|
||||
#endif
|
||||
|
||||
template<typename T>
|
||||
void query(vx_enum att, T& value) const
|
||||
{ IVX_CHECK_STATUS( vxQueryPyramid(ref, att, &value, sizeof(value)) ); }
|
||||
|
||||
vx_size levels() const
|
||||
{
|
||||
vx_size l;
|
||||
query(VX_PYRAMID_LEVELS, l);
|
||||
return l;
|
||||
}
|
||||
|
||||
vx_float32 scale() const
|
||||
{
|
||||
vx_float32 s;
|
||||
query(VX_PYRAMID_SCALE, s);
|
||||
return s;
|
||||
}
|
||||
|
||||
vx_uint32 width() const
|
||||
{
|
||||
vx_uint32 v;
|
||||
query(VX_PYRAMID_WIDTH, v);
|
||||
return v;
|
||||
}
|
||||
|
||||
vx_uint32 height() const
|
||||
{
|
||||
vx_uint32 v;
|
||||
query(VX_PYRAMID_HEIGHT, v);
|
||||
return v;
|
||||
}
|
||||
|
||||
vx_df_image format() const
|
||||
{
|
||||
vx_df_image f;
|
||||
query(VX_PYRAMID_FORMAT, f);
|
||||
return f;
|
||||
}
|
||||
|
||||
Image getLevel(vx_uint32 index)
|
||||
{ return Image(vxGetPyramidLevel(ref, index)); }
|
||||
};
|
||||
|
||||
/*
|
||||
* 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
|
||||
};
|
||||
|
||||
/*
|
||||
* 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
|
||||
namespace nodes {
|
||||
|
||||
/// Creates a Gaussian Filter 3x3 Node (vxGaussian3x3Node)
|
||||
inline Node gaussian3x3(vx_graph graph, vx_image inImg, vx_image outImg)
|
||||
{ return Node(vxGaussian3x3Node(graph, inImg, outImg)); }
|
||||
|
||||
} // namespace nodes
|
||||
|
||||
} // namespace ivx
|
||||
|
||||
// restore warnings
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(pop)
|
||||
#elif defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#elif defined(__GNUC__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif // compiler macro
|
||||
|
||||
#endif //IVX_HPP
|
||||
-42
@@ -1,42 +0,0 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
|
||||
// Copyright (C) 2016, Intel Corporation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
|
||||
/*
|
||||
C++ wrappers over OpenVX 1.x C API ("openvx-debug" module)
|
||||
Details: TBD
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef IVX_LIB_DEBUG_HPP
|
||||
#define IVX_LIB_DEBUG_HPP
|
||||
|
||||
#include "ivx.hpp"
|
||||
|
||||
namespace ivx
|
||||
{
|
||||
namespace debug
|
||||
{
|
||||
/*
|
||||
* "openvx-debug" module
|
||||
*/
|
||||
|
||||
//
|
||||
void fReadImage(vx_context c, const std::string& path, vx_image img)
|
||||
{
|
||||
IVX_CHECK_STATUS( vxuFReadImage(c, (vx_char*)path.c_str(), img) );
|
||||
}
|
||||
|
||||
//
|
||||
void fWriteImage(vx_context c, vx_image img, const std::string& path)
|
||||
{
|
||||
IVX_CHECK_STATUS( vxuFWriteImage(c, img, (vx_char*)path.c_str()) );
|
||||
}
|
||||
|
||||
} // namespace debug
|
||||
} // namespace ivx
|
||||
|
||||
#endif //IVX_LIB_DEBUG_HPP
|
||||
@@ -332,9 +332,6 @@ OCV_OPTION(WITH_OPENEXR "Include ILM support via OpenEXR" ((WIN32 OR ANDROID OR
|
||||
OCV_OPTION(WITH_OPENGL "Include OpenGL support" OFF
|
||||
VISIBLE_IF NOT ANDROID AND NOT WINRT
|
||||
VERIFY HAVE_OPENGL)
|
||||
OCV_OPTION(WITH_OPENVX "Include OpenVX support" OFF
|
||||
VISIBLE_IF TRUE
|
||||
VERIFY HAVE_OPENVX)
|
||||
OCV_OPTION(WITH_OPENNI "Include OpenNI support" OFF
|
||||
VISIBLE_IF NOT ANDROID AND NOT IOS AND NOT XROS AND NOT WINRT
|
||||
VERIFY HAVE_OPENNI)
|
||||
@@ -913,10 +910,6 @@ if(WITH_VTK)
|
||||
include(cmake/OpenCVDetectVTK.cmake)
|
||||
endif()
|
||||
|
||||
if(WITH_OPENVX)
|
||||
include(cmake/FindOpenVX.cmake)
|
||||
endif()
|
||||
|
||||
if(WITH_QUIRC)
|
||||
add_subdirectory(3rdparty/quirc)
|
||||
set(HAVE_QUIRC TRUE)
|
||||
@@ -950,12 +943,6 @@ if(NOT DEFINED OpenCV_HAL)
|
||||
set(OpenCV_HAL "OpenCV_HAL")
|
||||
endif()
|
||||
|
||||
if(HAVE_OPENVX)
|
||||
if(NOT ";${OpenCV_HAL};" MATCHES ";openvx;")
|
||||
set(OpenCV_HAL "openvx;${OpenCV_HAL}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WITH_CAROTENE)
|
||||
ocv_debug_message(STATUS "Enable carotene acceleration")
|
||||
if(NOT ";${OpenCV_HAL};" MATCHES ";carotene;")
|
||||
@@ -980,10 +967,6 @@ foreach(hal ${OpenCV_HAL})
|
||||
else()
|
||||
message(STATUS "Carotene: NEON is not available, disabling carotene...")
|
||||
endif()
|
||||
elseif(hal STREQUAL "openvx")
|
||||
add_subdirectory(3rdparty/openvx)
|
||||
ocv_hal_register(OPENVX_HAL_LIBRARIES OPENVX_HAL_HEADERS OPENVX_HAL_INCLUDE_DIRS)
|
||||
list(APPEND OpenCV_USED_HAL "openvx (ver ${OPENVX_HAL_VERSION})")
|
||||
else()
|
||||
ocv_debug_message(STATUS "OpenCV HAL: ${hal} ...")
|
||||
ocv_clear_vars(OpenCV_HAL_LIBRARIES OpenCV_HAL_HEADERS OpenCV_HAL_INCLUDE_DIRS)
|
||||
@@ -1751,10 +1734,6 @@ if(WITH_EIGEN OR HAVE_EIGEN)
|
||||
status(" Eigen:" HAVE_EIGEN THEN "YES (ver ${EIGEN_WORLD_VERSION}.${EIGEN_MAJOR_VERSION}.${EIGEN_MINOR_VERSION})" ELSE NO)
|
||||
endif()
|
||||
|
||||
if(WITH_OPENVX OR HAVE_OPENVX)
|
||||
status(" OpenVX:" HAVE_OPENVX THEN "YES (${OPENVX_LIBRARIES})" ELSE "NO")
|
||||
endif()
|
||||
|
||||
status(" Custom HAL:" OpenCV_USED_HAL THEN "YES (${OpenCV_USED_HAL})" ELSE "NO")
|
||||
|
||||
foreach(s ${CUSTOM_STATUS})
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
ocv_clear_vars(HAVE_OPENVX)
|
||||
|
||||
set(OPENVX_ROOT "" CACHE PATH "OpenVX install directory")
|
||||
set(OPENVX_LIB_CANDIDATES "openvx;vxu" CACHE STRING "OpenVX library candidates list")
|
||||
|
||||
function(find_openvx_libs _found)
|
||||
foreach(one ${OPENVX_LIB_CANDIDATES})
|
||||
find_library(OPENVX_${one}_LIBRARY ${one} PATHS "${OPENVX_ROOT}/lib" "${OPENVX_ROOT}/bin")
|
||||
if(OPENVX_${one}_LIBRARY)
|
||||
list(APPEND _list ${OPENVX_${one}_LIBRARY})
|
||||
endif()
|
||||
endforeach()
|
||||
set(${_found} ${_list} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
if(OPENVX_ROOT)
|
||||
find_path(OPENVX_INCLUDE_DIR "VX/vx.h" PATHS "${OPENVX_ROOT}/include" DOC "OpenVX include path")
|
||||
if(NOT DEFINED OPENVX_LIBRARIES)
|
||||
find_openvx_libs(found)
|
||||
if(found)
|
||||
set(OPENVX_LIBRARIES "${found}" CACHE STRING "OpenVX libraries")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(OPENVX_INCLUDE_DIR AND OPENVX_LIBRARIES)
|
||||
set(HAVE_OPENVX TRUE)
|
||||
|
||||
try_compile(OPENVX_RENAMED_REF
|
||||
"${OpenCV_BINARY_DIR}"
|
||||
"${OpenCV_SOURCE_DIR}/cmake/checks/openvx_refenum_test.cpp"
|
||||
CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:STRING=${OPENVX_INCLUDE_DIR}"
|
||||
LINK_LIBRARIES ${OPENVX_LIBRARIES}
|
||||
OUTPUT_VARIABLE OUTPUT
|
||||
)
|
||||
if(OPENVX_RENAMED_REF)
|
||||
add_definitions(-DIVX_RENAMED_REFS=1)
|
||||
message(STATUS "OpenVX: Checking reference attribute name convention... New")
|
||||
else()
|
||||
message(STATUS "OpenVX: Checking reference attribute name convention... Old")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT HAVE_OPENVX)
|
||||
ocv_clear_vars(HAVE_OPENVX OPENVX_LIBRARIES OPENVX_INCLUDE_DIR)
|
||||
endif()
|
||||
@@ -1,6 +1,6 @@
|
||||
set(TIMVX_INSTALL_DIR "" CACHE PATH "Path to libtim-vx installation")
|
||||
set(VIVANTE_SDK_DIR "" CACHE PATH "Path to VIVANTE SDK needed by TIM-VX.")
|
||||
set(VIVANTE_SDK_LIB_CANDIDATES "OpenVX;VSC;GAL;ArchModelSw;NNArchPerf" CACHE STRING "VIVANTE SDK library candidates")
|
||||
set(VIVANTE_SDK_LIB_CANDIDATES "VSC;GAL;ArchModelSw;NNArchPerf" CACHE STRING "VIVANTE SDK library candidates")
|
||||
|
||||
# Ensure VIVANTE SDK library candidates are present in given search path
|
||||
function(find_vivante_sdk_libs _viv_notfound _viv_search_path)
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
#include <VX/vx.h>
|
||||
int main()
|
||||
{
|
||||
return VX_REFERENCE_COUNT == VX_REFERENCE_TYPE ? VX_REFERENCE_NAME : 0;
|
||||
}
|
||||
@@ -137,9 +137,6 @@
|
||||
/* Library was compiled with functions instrumentation */
|
||||
#cmakedefine ENABLE_INSTRUMENTATION
|
||||
|
||||
/* OpenVX */
|
||||
#cmakedefine HAVE_OPENVX
|
||||
|
||||
/* OpenCV trace utilities */
|
||||
#cmakedefine OPENCV_TRACE
|
||||
|
||||
|
||||
@@ -623,7 +623,6 @@ Following build options are utilized in `opencv_contrib` modules, as stated [pre
|
||||
`WITH_CAROTENE`
|
||||
`WITH_CPUFEATURES`
|
||||
`WITH_EIGEN`
|
||||
`WITH_OPENVX`
|
||||
`WITH_DIRECTX`
|
||||
`WITH_VA`
|
||||
`WITH_LAPACK`
|
||||
|
||||
@@ -3404,6 +3404,5 @@ struct ParamType<_Tp, typename std::enable_if< std::is_enum<_Tp>::value >::type>
|
||||
#include "opencv2/core/cvstd.inl.hpp"
|
||||
#include "opencv2/core/utility.hpp"
|
||||
#include "opencv2/core/optim.hpp"
|
||||
#include "opencv2/core/ovx.hpp"
|
||||
|
||||
#endif /*OPENCV_CORE_HPP*/
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
|
||||
// Copyright (C) 2016, Intel Corporation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
|
||||
// OpenVX related definitions and declarations
|
||||
|
||||
#pragma once
|
||||
#ifndef OPENCV_OVX_DEFS_HPP
|
||||
#define OPENCV_OVX_DEFS_HPP
|
||||
|
||||
#include "cvconfig.h"
|
||||
|
||||
// utility macro for running OpenVX-based implementations
|
||||
#ifdef HAVE_OPENVX
|
||||
|
||||
#define IVX_HIDE_INFO_WARNINGS
|
||||
#define IVX_USE_OPENCV
|
||||
#include "ivx.hpp"
|
||||
|
||||
namespace cv{
|
||||
namespace ovx{
|
||||
// Get common thread local OpenVX context
|
||||
CV_EXPORTS_W ivx::Context& getOpenVXContext();
|
||||
|
||||
template <int kernel_id> inline bool skipSmallImages(int w, int h) { return w*h < 3840 * 2160; }
|
||||
}}
|
||||
|
||||
#define CV_OVX_RUN(condition, func, ...) \
|
||||
if (cv::useOpenVX() && (condition) && func) \
|
||||
{ \
|
||||
return __VA_ARGS__; \
|
||||
}
|
||||
|
||||
#else
|
||||
#define CV_OVX_RUN(condition, func, ...)
|
||||
#endif // HAVE_OPENVX
|
||||
|
||||
// Throw an error in debug mode or try another implementation in release
|
||||
#ifdef _DEBUG
|
||||
#define VX_DbgThrow(s) CV_Error(cv::Error::StsInternal, (s))
|
||||
#else
|
||||
#define VX_DbgThrow(s) return false
|
||||
#endif
|
||||
|
||||
#endif // OPENCV_OVX_DEFS_HPP
|
||||
@@ -1,28 +0,0 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
|
||||
// Copyright (C) 2016, Intel Corporation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
|
||||
// OpenVX related definitions and declarations
|
||||
|
||||
#pragma once
|
||||
#ifndef OPENCV_OVX_HPP
|
||||
#define OPENCV_OVX_HPP
|
||||
|
||||
#include "cvdef.h"
|
||||
|
||||
namespace cv
|
||||
{
|
||||
/// Check if use of OpenVX is possible
|
||||
CV_EXPORTS_W bool haveOpenVX();
|
||||
|
||||
/// Check if use of OpenVX is enabled
|
||||
CV_EXPORTS_W bool useOpenVX();
|
||||
|
||||
/// Enable/disable use of OpenVX
|
||||
CV_EXPORTS_W void setUseOpenVX(bool flag);
|
||||
} // namespace cv
|
||||
|
||||
#endif // OPENCV_OVX_HPP
|
||||
@@ -106,7 +106,6 @@ enum RegionLocationFlag {
|
||||
|
||||
REGION_FLAG_IMPL_IPP = (1 << 16), ///< region is part of IPP code path
|
||||
REGION_FLAG_IMPL_OPENCL = (2 << 16), ///< region is part of OpenCL code path
|
||||
REGION_FLAG_IMPL_OPENVX = (3 << 16), ///< region is part of OpenVX code path
|
||||
|
||||
REGION_FLAG_IMPL_MASK = (15 << 16),
|
||||
|
||||
|
||||
@@ -79,9 +79,6 @@ struct RegionStatistics
|
||||
#ifdef HAVE_OPENCL
|
||||
int64 durationImplOpenCL;
|
||||
#endif
|
||||
#ifdef HAVE_OPENVX
|
||||
int64 durationImplOpenVX;
|
||||
#endif
|
||||
|
||||
RegionStatistics() :
|
||||
currentSkippedRegions(0),
|
||||
@@ -91,9 +88,6 @@ struct RegionStatistics
|
||||
#endif
|
||||
#ifdef HAVE_OPENCL
|
||||
,durationImplOpenCL(0)
|
||||
#endif
|
||||
#ifdef HAVE_OPENVX
|
||||
,durationImplOpenVX(0)
|
||||
#endif
|
||||
{}
|
||||
|
||||
@@ -106,9 +100,6 @@ struct RegionStatistics
|
||||
#endif
|
||||
#ifdef HAVE_OPENCL
|
||||
result.durationImplOpenCL = durationImplOpenCL; durationImplOpenCL = 0;
|
||||
#endif
|
||||
#ifdef HAVE_OPENVX
|
||||
result.durationImplOpenVX = durationImplOpenVX; durationImplOpenVX = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -121,9 +112,6 @@ struct RegionStatistics
|
||||
#endif
|
||||
#ifdef HAVE_OPENCL
|
||||
durationImplOpenCL += stat.durationImplOpenCL;
|
||||
#endif
|
||||
#ifdef HAVE_OPENVX
|
||||
durationImplOpenVX += stat.durationImplOpenVX;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -135,9 +123,6 @@ struct RegionStatistics
|
||||
#endif
|
||||
#ifdef HAVE_OPENCL
|
||||
durationImplOpenCL = (int64)(durationImplOpenCL * c);
|
||||
#endif
|
||||
#ifdef HAVE_OPENVX
|
||||
durationImplOpenVX = (int64)(durationImplOpenVX * c);
|
||||
#endif
|
||||
}
|
||||
};
|
||||
@@ -152,9 +137,6 @@ std::ostream& operator<<(std::ostream& out, const RegionStatistics& stat)
|
||||
#endif
|
||||
#ifdef HAVE_OPENCL
|
||||
<< " durationImplOpenCL=" << stat.durationImplOpenCL
|
||||
#endif
|
||||
#ifdef HAVE_OPENVX
|
||||
<< " durationImplOpenVX=" << stat.durationImplOpenVX
|
||||
#endif
|
||||
;
|
||||
return out;
|
||||
@@ -169,9 +151,6 @@ struct RegionStatisticsStatus
|
||||
#ifdef HAVE_OPENCL
|
||||
int ignoreDepthImplOpenCL;
|
||||
#endif
|
||||
#ifdef HAVE_OPENVX
|
||||
int ignoreDepthImplOpenVX;
|
||||
#endif
|
||||
|
||||
RegionStatisticsStatus() { reset(); }
|
||||
|
||||
@@ -183,9 +162,6 @@ struct RegionStatisticsStatus
|
||||
#endif
|
||||
#ifdef HAVE_OPENCL
|
||||
ignoreDepthImplOpenCL = 0;
|
||||
#endif
|
||||
#ifdef HAVE_OPENVX
|
||||
ignoreDepthImplOpenVX = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -199,9 +175,6 @@ struct RegionStatisticsStatus
|
||||
#endif
|
||||
#ifdef HAVE_OPENCL
|
||||
ignoreDepthImplOpenCL = src.ignoreDepthImplOpenCL ? 1 : 0;
|
||||
#endif
|
||||
#ifdef HAVE_OPENVX
|
||||
ignoreDepthImplOpenVX = src.ignoreDepthImplOpenVX ? 1 : 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -222,10 +195,6 @@ std::ostream& operator<<(std::ostream& out, const RegionStatisticsStatus& s)
|
||||
#ifdef HAVE_OPENCL
|
||||
if (s.ignoreDepthImplOpenCL)
|
||||
out << " OpenCL=" << s.ignoreDepthImplOpenCL;
|
||||
#endif
|
||||
#ifdef HAVE_OPENVX
|
||||
if (s.ignoreDepthImplOpenVX)
|
||||
out << " OpenVX=" << s.ignoreDepthImplOpenVX;
|
||||
#endif
|
||||
out << "}";
|
||||
return out;
|
||||
@@ -389,8 +358,7 @@ public:
|
||||
enum OptimizationPath {
|
||||
CODE_PATH_PLAIN = 0,
|
||||
CODE_PATH_IPP,
|
||||
CODE_PATH_OPENCL,
|
||||
CODE_PATH_OPENVX
|
||||
CODE_PATH_OPENCL
|
||||
};
|
||||
|
||||
#ifdef OPENCV_WITH_ITT
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#include "precomp.hpp"
|
||||
#include "opencl_kernels_core.hpp"
|
||||
#include "convert.hpp"
|
||||
#include "opencv2/core/openvx/ovx_defs.hpp"
|
||||
|
||||
/****************************************************************************************\
|
||||
* LUT Transform *
|
||||
@@ -100,39 +99,6 @@ 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 = ovx::getOpenVXContext();
|
||||
|
||||
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 (const ivx::RuntimeError& e)
|
||||
{
|
||||
VX_DbgThrow(e.what());
|
||||
}
|
||||
catch (const ivx::WrapperError& e)
|
||||
{
|
||||
VX_DbgThrow(e.what());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_IPP)
|
||||
#if !IPP_DISABLE_PERF_LUT // there are no performance benefits (PR #2653)
|
||||
namespace ipp {
|
||||
@@ -374,8 +340,6 @@ void cv::LUT( InputArray _src, InputArray _lut, OutputArray _dst )
|
||||
_dst.createSameSize(_src, CV_MAKETYPE(_lut.depth(), cn));
|
||||
Mat dst = _dst.getMat();
|
||||
|
||||
CV_OVX_RUN(!ovx::skipSmallImages<VX_KERNEL_TABLE_LOOKUP>(src.cols, src.rows),
|
||||
openvx_LUT(src, dst, lut))
|
||||
|
||||
#if !IPP_DISABLE_PERF_LUT
|
||||
CV_IPP_RUN(_src.dims() <= 2, ipp_lut(src, lut, dst));
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
|
||||
#include "precomp.hpp"
|
||||
#include "opencl_kernels_core.hpp"
|
||||
#include "opencv2/core/openvx/ovx_defs.hpp"
|
||||
#include "stat.hpp"
|
||||
|
||||
#ifndef OPENCV_IPP_MEAN
|
||||
@@ -319,69 +318,6 @@ static bool ocl_meanStdDev( InputArray _src, OutputArray _mean, OutputArray _sdv
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPENVX
|
||||
static bool openvx_meanStdDev(Mat& src, OutputArray _mean, OutputArray _sdv, Mat& mask)
|
||||
{
|
||||
size_t total_size = src.total();
|
||||
int rows = src.size[0], cols = rows ? (int)(total_size / rows) : 0;
|
||||
if (src.type() != CV_8UC1|| !mask.empty() ||
|
||||
(src.dims != 2 && !(src.isContinuous() && cols > 0 && (size_t)rows*cols == total_size))
|
||||
)
|
||||
return false;
|
||||
|
||||
try
|
||||
{
|
||||
ivx::Context ctx = ovx::getOpenVXContext();
|
||||
#ifndef VX_VERSION_1_1
|
||||
if (ctx.vendorID() == VX_ID_KHRONOS)
|
||||
return false; // Do not use OpenVX meanStdDev estimation for sample 1.0.1 implementation due to lack of accuracy
|
||||
#endif
|
||||
|
||||
ivx::Image
|
||||
ia = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8,
|
||||
ivx::Image::createAddressing(cols, rows, 1, (vx_int32)(src.step[0])), src.ptr());
|
||||
|
||||
vx_float32 mean_temp, stddev_temp;
|
||||
ivx::IVX_CHECK_STATUS(vxuMeanStdDev(ctx, ia, &mean_temp, &stddev_temp));
|
||||
|
||||
if (_mean.needed())
|
||||
{
|
||||
if (!_mean.fixedSize())
|
||||
_mean.create(1, 1, CV_64F, -1, true);
|
||||
Mat mean = _mean.getMat();
|
||||
CV_Assert(mean.type() == CV_64F && mean.isContinuous() &&
|
||||
(mean.cols == 1 || mean.rows == 1) && mean.total() >= 1);
|
||||
double *pmean = mean.ptr<double>();
|
||||
pmean[0] = mean_temp;
|
||||
for (int c = 1; c < (int)mean.total(); c++)
|
||||
pmean[c] = 0;
|
||||
}
|
||||
|
||||
if (_sdv.needed())
|
||||
{
|
||||
if (!_sdv.fixedSize())
|
||||
_sdv.create(1, 1, CV_64F, -1, true);
|
||||
Mat stddev = _sdv.getMat();
|
||||
CV_Assert(stddev.type() == CV_64F && stddev.isContinuous() &&
|
||||
(stddev.cols == 1 || stddev.rows == 1) && stddev.total() >= 1);
|
||||
double *pstddev = stddev.ptr<double>();
|
||||
pstddev[0] = stddev_temp;
|
||||
for (int c = 1; c < (int)stddev.total(); c++)
|
||||
pstddev[c] = 0;
|
||||
}
|
||||
}
|
||||
catch (const ivx::RuntimeError & e)
|
||||
{
|
||||
VX_DbgThrow(e.what());
|
||||
}
|
||||
catch (const ivx::WrapperError & e)
|
||||
{
|
||||
VX_DbgThrow(e.what());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_IPP
|
||||
static bool ipp_meanStdDev(Mat& src, OutputArray _mean, OutputArray _sdv, Mat& mask)
|
||||
@@ -532,9 +468,6 @@ void meanStdDev(InputArray _src, OutputArray _mean, OutputArray _sdv, InputArray
|
||||
|
||||
Mat src = _src.getMat(), mask = _mask.getMat();
|
||||
|
||||
CV_OVX_RUN(!ovx::skipSmallImages<VX_KERNEL_MEAN_STDDEV>(src.cols, src.rows),
|
||||
openvx_meanStdDev(src, _mean, _sdv, mask))
|
||||
|
||||
CV_IPP_RUN(IPP_VERSION_X100 >= 700, ipp_meanStdDev(src, _mean, _sdv, mask));
|
||||
|
||||
int k, cn = src.channels(), depth = src.depth();
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
|
||||
#include "precomp.hpp"
|
||||
#include "opencl_kernels_core.hpp"
|
||||
#include "opencv2/core/openvx/ovx_defs.hpp"
|
||||
#include "stat.hpp"
|
||||
#include "opencv2/core/detail/dispatch_helper.impl.hpp"
|
||||
#include <algorithm>
|
||||
|
||||
@@ -1,105 +0,0 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
|
||||
// Copyright (C) 2016, Intel Corporation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
|
||||
// OpenVX related functions
|
||||
|
||||
#include "precomp.hpp"
|
||||
#include "opencv2/core/utils/tls.hpp"
|
||||
#include "opencv2/core/ovx.hpp"
|
||||
#include "opencv2/core/openvx/ovx_defs.hpp"
|
||||
|
||||
namespace cv
|
||||
{
|
||||
|
||||
namespace ovx
|
||||
{
|
||||
#ifdef HAVE_OPENVX
|
||||
|
||||
// Simple TLSData<ivx::Context> doesn't work, because default constructor doesn't create any OpenVX context.
|
||||
struct OpenVXTLSData
|
||||
{
|
||||
OpenVXTLSData() : ctx(ivx::Context::create()) {}
|
||||
ivx::Context ctx;
|
||||
};
|
||||
|
||||
static TLSData<OpenVXTLSData>& getOpenVXTLSData()
|
||||
{
|
||||
CV_SINGLETON_LAZY_INIT_REF(TLSData<OpenVXTLSData>, new TLSData<OpenVXTLSData>())
|
||||
}
|
||||
|
||||
struct OpenVXCleanupFunctor
|
||||
{
|
||||
~OpenVXCleanupFunctor() { getOpenVXTLSData().cleanup(); }
|
||||
};
|
||||
static OpenVXCleanupFunctor g_openvx_cleanup_functor;
|
||||
|
||||
ivx::Context& getOpenVXContext()
|
||||
{
|
||||
return getOpenVXTLSData().get()->ctx;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
bool haveOpenVX()
|
||||
{
|
||||
#ifdef HAVE_OPENVX
|
||||
static int g_haveOpenVX = -1;
|
||||
if(g_haveOpenVX < 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
ivx::Context context = ovx::getOpenVXContext();
|
||||
vx_uint16 vComp = ivx::compiledWithVersion();
|
||||
vx_uint16 vCurr = context.version();
|
||||
g_haveOpenVX =
|
||||
VX_VERSION_MAJOR(vComp) == VX_VERSION_MAJOR(vCurr) &&
|
||||
VX_VERSION_MINOR(vComp) == VX_VERSION_MINOR(vCurr)
|
||||
? 1 : 0;
|
||||
}
|
||||
catch(const ivx::WrapperError&)
|
||||
{ g_haveOpenVX = 0; }
|
||||
catch(const ivx::RuntimeError&)
|
||||
{ g_haveOpenVX = 0; }
|
||||
}
|
||||
return g_haveOpenVX == 1;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool useOpenVX()
|
||||
{
|
||||
#ifdef HAVE_OPENVX
|
||||
CoreTLSData& data = getCoreTlsData();
|
||||
if (data.useOpenVX < 0)
|
||||
{
|
||||
// enabled (if available) by default
|
||||
data.useOpenVX = haveOpenVX() ? 1 : 0;
|
||||
}
|
||||
return data.useOpenVX > 0;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void setUseOpenVX(bool flag)
|
||||
{
|
||||
#ifdef HAVE_OPENVX
|
||||
if( haveOpenVX() )
|
||||
{
|
||||
CoreTLSData& data = getCoreTlsData();
|
||||
data.useOpenVX = flag ? 1 : 0;
|
||||
}
|
||||
#else
|
||||
CV_Assert(!flag && "OpenVX support isn't enabled at compile time");
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace cv
|
||||
@@ -353,9 +353,6 @@ struct CoreTLSData
|
||||
//#endif
|
||||
useIPP(-1),
|
||||
useIPP_NE(-1)
|
||||
#ifdef HAVE_OPENVX
|
||||
,useOpenVX(-1)
|
||||
#endif
|
||||
{}
|
||||
|
||||
RNG rng;
|
||||
@@ -366,9 +363,6 @@ struct CoreTLSData
|
||||
//#endif
|
||||
int useIPP; // 1 - use, 0 - do not use, -1 - auto/not initialized
|
||||
int useIPP_NE; // 1 - use, 0 - do not use, -1 - auto/not initialized
|
||||
#ifdef HAVE_OPENVX
|
||||
int useOpenVX; // 1 - use, 0 - do not use, -1 - auto/not initialized
|
||||
#endif
|
||||
};
|
||||
|
||||
CoreTLSData& getCoreTlsData();
|
||||
|
||||
@@ -171,10 +171,6 @@ public:
|
||||
#ifdef HAVE_OPENCL
|
||||
if (result.durationImplOpenCL)
|
||||
ok &= this->printf(",tOCL=%lld", (long long int)result.durationImplOpenCL);
|
||||
#endif
|
||||
#ifdef HAVE_OPENVX
|
||||
if (result.durationImplOpenVX)
|
||||
ok &= this->printf(",tOVX=%lld", (long long int)result.durationImplOpenVX);
|
||||
#endif
|
||||
ok &= this->printf("\n");
|
||||
return ok;
|
||||
@@ -359,10 +355,6 @@ void Region::Impl::leaveRegion(TraceManagerThreadLocal& ctx)
|
||||
#ifdef HAVE_OPENCL
|
||||
if (result.durationImplOpenCL)
|
||||
__itt_metadata_add(domain, itt_id, __itt_string_handle_create("tOpenCL"), __itt_metadata_u64, 1, &result.durationImplOpenCL);
|
||||
#endif
|
||||
#ifdef HAVE_OPENVX
|
||||
if (result.durationImplOpenVX)
|
||||
__itt_metadata_add(domain, itt_id, __itt_string_handle_create("tOpenVX"), __itt_metadata_u64, 1, &result.durationImplOpenVX);
|
||||
#endif
|
||||
__itt_task_end(domain);
|
||||
}
|
||||
@@ -492,12 +484,6 @@ Region::Region(const LocationStaticStorage& location) :
|
||||
if (!ctx.stat_status.ignoreDepthImplOpenCL)
|
||||
ctx.stat_status.ignoreDepthImplOpenCL = currentDepth;
|
||||
break;
|
||||
#endif
|
||||
#ifdef HAVE_OPENVX
|
||||
case REGION_FLAG_IMPL_OPENVX:
|
||||
if (!ctx.stat_status.ignoreDepthImplOpenVX)
|
||||
ctx.stat_status.ignoreDepthImplOpenVX = currentDepth;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
@@ -615,11 +601,6 @@ void Region::destroy()
|
||||
cv::ocl::finish();
|
||||
myCodePath = Impl::CODE_PATH_OPENCL;
|
||||
break;
|
||||
#endif
|
||||
#ifdef HAVE_OPENVX
|
||||
case REGION_FLAG_IMPL_OPENVX:
|
||||
myCodePath = Impl::CODE_PATH_OPENVX;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
@@ -665,19 +646,6 @@ void Region::destroy()
|
||||
ctx.stat.durationImplOpenCL = duration;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#ifdef HAVE_OPENVX
|
||||
case Impl::CODE_PATH_OPENVX:
|
||||
if (ctx.stat_status.ignoreDepthImplOpenVX == currentDepth)
|
||||
{
|
||||
ctx.stat.durationImplOpenVX += duration;
|
||||
ctx.stat_status.ignoreDepthImplOpenVX = 0;
|
||||
}
|
||||
else if (active)
|
||||
{
|
||||
ctx.stat.durationImplOpenVX = duration;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
|
||||
@@ -49,8 +49,6 @@ The references are:
|
||||
#include "opencv2/core/hal/intrin.hpp"
|
||||
#include "opencv2/core/utils/buffer_area.private.hpp"
|
||||
|
||||
#include "opencv2/core/openvx/ovx_defs.hpp"
|
||||
|
||||
namespace cv
|
||||
{
|
||||
|
||||
@@ -371,70 +369,6 @@ static bool ocl_FAST( InputArray _img, std::vector<KeyPoint>& keypoints,
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HAVE_OPENVX
|
||||
namespace ovx {
|
||||
template <> inline bool skipSmallImages<VX_KERNEL_FAST_CORNERS>(int w, int h) { return w*h < 800 * 600; }
|
||||
}
|
||||
static bool openvx_FAST(InputArray _img, std::vector<KeyPoint>& keypoints,
|
||||
int _threshold, bool nonmaxSuppression, int type)
|
||||
{
|
||||
using namespace ivx;
|
||||
|
||||
// Nonmax suppression is done differently in OpenCV than in OpenVX
|
||||
// 9/16 is the only supported mode in OpenVX
|
||||
if(nonmaxSuppression || type != FastFeatureDetector::TYPE_9_16)
|
||||
return false;
|
||||
|
||||
Mat imgMat = _img.getMat();
|
||||
if(imgMat.empty() || imgMat.type() != CV_8UC1)
|
||||
return false;
|
||||
|
||||
if (ovx::skipSmallImages<VX_KERNEL_FAST_CORNERS>(imgMat.cols, imgMat.rows))
|
||||
return false;
|
||||
|
||||
try
|
||||
{
|
||||
Context context = ovx::getOpenVXContext();
|
||||
Image img = Image::createFromHandle(context, Image::matTypeToFormat(imgMat.type()),
|
||||
Image::createAddressing(imgMat), (void*)imgMat.data);
|
||||
ivx::Scalar threshold = ivx::Scalar::create<VX_TYPE_FLOAT32>(context, _threshold);
|
||||
vx_size capacity = imgMat.cols * imgMat.rows;
|
||||
Array corners = Array::create(context, VX_TYPE_KEYPOINT, capacity);
|
||||
|
||||
ivx::Scalar numCorners = ivx::Scalar::create<VX_TYPE_SIZE>(context, 0);
|
||||
|
||||
IVX_CHECK_STATUS(vxuFastCorners(context, img, threshold, (vx_bool)nonmaxSuppression, corners, numCorners));
|
||||
|
||||
size_t nPoints = numCorners.getValue<vx_size>();
|
||||
keypoints.clear(); keypoints.reserve(nPoints);
|
||||
std::vector<vx_keypoint_t> vxCorners;
|
||||
corners.copyTo(vxCorners);
|
||||
for(size_t i = 0; i < nPoints; i++)
|
||||
{
|
||||
vx_keypoint_t kp = vxCorners[i];
|
||||
//if nonmaxSuppression is false, kp.strength is undefined
|
||||
keypoints.push_back(KeyPoint((float)kp.x, (float)kp.y, 7.f, -1, kp.strength));
|
||||
}
|
||||
|
||||
#ifdef VX_VERSION_1_1
|
||||
//we should take user memory back before release
|
||||
//(it's not done automatically according to standard)
|
||||
img.swapHandle();
|
||||
#endif
|
||||
}
|
||||
catch (const RuntimeError & e)
|
||||
{
|
||||
VX_DbgThrow(e.what());
|
||||
}
|
||||
catch (const WrapperError & e)
|
||||
{
|
||||
VX_DbgThrow(e.what());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static inline int hal_FAST(cv::Mat& src, std::vector<KeyPoint>& keypoints, int threshold, bool nonmax_suppression, FastFeatureDetector::DetectorType type)
|
||||
{
|
||||
@@ -507,9 +441,6 @@ void FAST(InputArray _img, std::vector<KeyPoint>& keypoints, int threshold, bool
|
||||
CALL_HAL(fast, cv_hal_FAST, img.data, img.step, img.cols, img.rows,
|
||||
(uchar*)(keypoints.data()), &keypoints_count, threshold, nonmax_suppression, type);
|
||||
|
||||
CV_OVX_RUN(true,
|
||||
openvx_FAST(_img, keypoints, threshold, nonmax_suppression, type))
|
||||
|
||||
switch(type) {
|
||||
case FastFeatureDetector::TYPE_5_8:
|
||||
FAST_t<8>(_img, keypoints, threshold, nonmax_suppression);
|
||||
|
||||
@@ -47,7 +47,6 @@
|
||||
#define CV_CPU_OPTIMIZATION_DECLARATIONS_ONLY
|
||||
#include "accum.simd.hpp"
|
||||
#include "accum.simd_declarations.hpp"
|
||||
#include "opencv2/core/openvx/ovx_defs.hpp"
|
||||
|
||||
namespace cv
|
||||
{
|
||||
@@ -231,80 +230,6 @@ static bool ipp_accumulate(InputArray _src, InputOutputArray _dst, InputArray _m
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPENVX
|
||||
namespace cv
|
||||
{
|
||||
enum
|
||||
{
|
||||
VX_ACCUMULATE_OP = 0,
|
||||
VX_ACCUMULATE_SQUARE_OP = 1,
|
||||
VX_ACCUMULATE_WEIGHTED_OP = 2
|
||||
};
|
||||
|
||||
namespace ovx {
|
||||
template <> inline bool skipSmallImages<VX_KERNEL_ACCUMULATE>(int w, int h) { return w*h < 120 * 60; }
|
||||
}
|
||||
static bool openvx_accumulate(InputArray _src, InputOutputArray _dst, InputArray _mask, double _weight, int opType)
|
||||
{
|
||||
Mat srcMat = _src.getMat(), dstMat = _dst.getMat();
|
||||
if (ovx::skipSmallImages<VX_KERNEL_ACCUMULATE>(srcMat.cols, srcMat.rows))
|
||||
return false;
|
||||
if(!_mask.empty() ||
|
||||
(opType == VX_ACCUMULATE_WEIGHTED_OP && dstMat.type() != CV_8UC1 ) ||
|
||||
(opType != VX_ACCUMULATE_WEIGHTED_OP && dstMat.type() != CV_16SC1 ) ||
|
||||
srcMat.type() != CV_8UC1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
//TODO: handle different number of channels (channel extract && channel combine)
|
||||
//TODO: handle mask (threshold mask to 0xff && bitwise AND with src)
|
||||
//(both things can be done by creating a graph)
|
||||
|
||||
try
|
||||
{
|
||||
ivx::Context context = ovx::getOpenVXContext();
|
||||
ivx::Image srcImage = ivx::Image::createFromHandle(context, ivx::Image::matTypeToFormat(srcMat.type()),
|
||||
ivx::Image::createAddressing(srcMat), srcMat.data);
|
||||
ivx::Image dstImage = ivx::Image::createFromHandle(context, ivx::Image::matTypeToFormat(dstMat.type()),
|
||||
ivx::Image::createAddressing(dstMat), dstMat.data);
|
||||
ivx::Scalar shift = ivx::Scalar::create<VX_TYPE_UINT32>(context, 0);
|
||||
ivx::Scalar alpha = ivx::Scalar::create<VX_TYPE_FLOAT32>(context, _weight);
|
||||
|
||||
switch (opType)
|
||||
{
|
||||
case VX_ACCUMULATE_OP:
|
||||
ivx::IVX_CHECK_STATUS(vxuAccumulateImage(context, srcImage, dstImage));
|
||||
break;
|
||||
case VX_ACCUMULATE_SQUARE_OP:
|
||||
ivx::IVX_CHECK_STATUS(vxuAccumulateSquareImage(context, srcImage, shift, dstImage));
|
||||
break;
|
||||
case VX_ACCUMULATE_WEIGHTED_OP:
|
||||
ivx::IVX_CHECK_STATUS(vxuAccumulateWeightedImage(context, srcImage, alpha, dstImage));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef VX_VERSION_1_1
|
||||
//we should take user memory back before release
|
||||
//(it's not done automatically according to standard)
|
||||
srcImage.swapHandle(); dstImage.swapHandle();
|
||||
#endif
|
||||
}
|
||||
catch (const ivx::RuntimeError & e)
|
||||
{
|
||||
VX_DbgThrow(e.what());
|
||||
}
|
||||
catch (const ivx::WrapperError & e)
|
||||
{
|
||||
VX_DbgThrow(e.what());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void cv::accumulate( InputArray _src, InputOutputArray _dst, InputArray _mask )
|
||||
{
|
||||
CV_INSTRUMENT_REGION();
|
||||
@@ -321,9 +246,6 @@ void cv::accumulate( InputArray _src, InputOutputArray _dst, InputArray _mask )
|
||||
CV_IPP_RUN((_src.dims() <= 2 || (_src.isContinuous() && _dst.isContinuous() && (_mask.empty() || _mask.isContinuous()))),
|
||||
ipp_accumulate(_src, _dst, _mask));
|
||||
|
||||
CV_OVX_RUN(_src.dims() <= 2,
|
||||
openvx_accumulate(_src, _dst, _mask, 0.0, VX_ACCUMULATE_OP))
|
||||
|
||||
Mat src = _src.getMat(), dst = _dst.getMat(), mask = _mask.getMat();
|
||||
|
||||
|
||||
@@ -420,9 +342,6 @@ void cv::accumulateSquare( InputArray _src, InputOutputArray _dst, InputArray _m
|
||||
CV_IPP_RUN((_src.dims() <= 2 || (_src.isContinuous() && _dst.isContinuous() && (_mask.empty() || _mask.isContinuous()))),
|
||||
ipp_accumulate_square(_src, _dst, _mask));
|
||||
|
||||
CV_OVX_RUN(_src.dims() <= 2,
|
||||
openvx_accumulate(_src, _dst, _mask, 0.0, VX_ACCUMULATE_SQUARE_OP))
|
||||
|
||||
Mat src = _src.getMat(), dst = _dst.getMat(), mask = _mask.getMat();
|
||||
|
||||
int fidx = getAccTabIdx(sdepth, ddepth);
|
||||
@@ -624,9 +543,6 @@ void cv::accumulateWeighted( InputArray _src, InputOutputArray _dst,
|
||||
|
||||
CV_IPP_RUN((_src.dims() <= 2 || (_src.isContinuous() && _dst.isContinuous() && _mask.isContinuous())), ipp_accumulate_weighted(_src, _dst, alpha, _mask));
|
||||
|
||||
CV_OVX_RUN(_src.dims() <= 2,
|
||||
openvx_accumulate(_src, _dst, _mask, alpha, VX_ACCUMULATE_WEIGHTED_OP))
|
||||
|
||||
Mat src = _src.getMat(), dst = _dst.getMat(), mask = _mask.getMat();
|
||||
|
||||
|
||||
|
||||
@@ -48,8 +48,6 @@
|
||||
#include "opencv2/core/hal/intrin.hpp"
|
||||
#include "opencl_kernels_imgproc.hpp"
|
||||
|
||||
#include "opencv2/core/openvx/ovx_defs.hpp"
|
||||
|
||||
#include "box_filter.simd.hpp"
|
||||
#include "box_filter.simd_declarations.hpp" // defines CV_CPU_DISPATCH_MODES_ALL=AVX2,...,BASELINE based on CMakeLists.txt content
|
||||
|
||||
@@ -315,79 +313,6 @@ Ptr<FilterEngine> createBoxFilter(int srcType, int dstType, Size ksize,
|
||||
CV_CPU_DISPATCH_MODES_ALL);
|
||||
}
|
||||
|
||||
#ifdef HAVE_OPENVX
|
||||
namespace ovx {
|
||||
template <> inline bool skipSmallImages<VX_KERNEL_BOX_3x3>(int w, int h) { return w*h < 640 * 480; }
|
||||
}
|
||||
static bool openvx_boxfilter(InputArray _src, OutputArray _dst, int ddepth,
|
||||
Size ksize, Point anchor,
|
||||
bool normalize, int borderType)
|
||||
{
|
||||
if (ddepth < 0)
|
||||
ddepth = CV_8UC1;
|
||||
if (_src.type() != CV_8UC1 || ddepth != CV_8U || !normalize ||
|
||||
_src.cols() < 3 || _src.rows() < 3 ||
|
||||
ksize.width != 3 || ksize.height != 3 ||
|
||||
(anchor.x >= 0 && anchor.x != 1) ||
|
||||
(anchor.y >= 0 && anchor.y != 1) ||
|
||||
ovx::skipSmallImages<VX_KERNEL_BOX_3x3>(_src.cols(), _src.rows()))
|
||||
return false;
|
||||
|
||||
Mat src = _src.getMat();
|
||||
|
||||
if ((borderType & BORDER_ISOLATED) == 0 && src.isSubmatrix())
|
||||
return false; //Process isolated borders only
|
||||
vx_enum border;
|
||||
switch (borderType & ~BORDER_ISOLATED)
|
||||
{
|
||||
case BORDER_CONSTANT:
|
||||
border = VX_BORDER_CONSTANT;
|
||||
break;
|
||||
case BORDER_REPLICATE:
|
||||
border = VX_BORDER_REPLICATE;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
_dst.create(src.size(), CV_8UC1);
|
||||
Mat dst = _dst.getMat();
|
||||
|
||||
try
|
||||
{
|
||||
ivx::Context ctx = ovx::getOpenVXContext();
|
||||
|
||||
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 standard says nothing about thread-safety for now
|
||||
ivx::border_t prevBorder = ctx.immediateBorder();
|
||||
ctx.setImmediateBorder(border, (vx_uint8)(0));
|
||||
ivx::IVX_CHECK_STATUS(vxuBox3x3(ctx, ia, ib));
|
||||
ctx.setImmediateBorder(prevBorder);
|
||||
}
|
||||
catch (const ivx::RuntimeError & e)
|
||||
{
|
||||
VX_DbgThrow(e.what());
|
||||
}
|
||||
catch (const ivx::WrapperError & e)
|
||||
{
|
||||
VX_DbgThrow(e.what());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0 //defined(HAVE_IPP)
|
||||
static bool ipp_boxfilter(Mat &src, Mat &dst, Size ksize, Point anchor, bool normalize, int borderType)
|
||||
@@ -475,9 +400,6 @@ void boxFilter(InputArray _src, OutputArray _dst, int ddepth,
|
||||
ofs.x, ofs.y, wsz.width - src.cols - ofs.x, wsz.height - src.rows - ofs.y, ksize.width, ksize.height,
|
||||
anchor.x, anchor.y, normalize, borderType&~BORDER_ISOLATED);
|
||||
|
||||
CV_OVX_RUN(true,
|
||||
openvx_boxfilter(src, dst, ddepth, ksize, anchor, normalize, borderType))
|
||||
|
||||
//CV_IPP_RUN_FAST(ipp_boxfilter(src, dst, ksize, anchor, normalize, borderType));
|
||||
|
||||
borderType = (borderType&~BORDER_ISOLATED);
|
||||
|
||||
@@ -45,8 +45,6 @@
|
||||
#include "opencv2/core/hal/intrin.hpp"
|
||||
#include <deque>
|
||||
|
||||
#include "opencv2/core/openvx/ovx_defs.hpp"
|
||||
|
||||
namespace cv
|
||||
{
|
||||
|
||||
@@ -761,65 +759,6 @@ private:
|
||||
finalPass& operator=(const finalPass&); // = delete
|
||||
};
|
||||
|
||||
#ifdef HAVE_OPENVX
|
||||
namespace ovx {
|
||||
template <> inline bool skipSmallImages<VX_KERNEL_CANNY_EDGE_DETECTOR>(int w, int h) { return w*h < 640 * 480; }
|
||||
}
|
||||
static bool openvx_canny(const Mat& src, Mat& dst, int loVal, int hiVal, int kSize, bool useL2)
|
||||
{
|
||||
using namespace ivx;
|
||||
|
||||
Context context = ovx::getOpenVXContext();
|
||||
try
|
||||
{
|
||||
Image _src = Image::createFromHandle(
|
||||
context,
|
||||
Image::matTypeToFormat(src.type()),
|
||||
Image::createAddressing(src),
|
||||
src.data );
|
||||
Image _dst = Image::createFromHandle(
|
||||
context,
|
||||
Image::matTypeToFormat(dst.type()),
|
||||
Image::createAddressing(dst),
|
||||
dst.data );
|
||||
Threshold threshold = Threshold::createRange(context, VX_TYPE_UINT8, saturate_cast<uchar>(loVal), saturate_cast<uchar>(hiVal));
|
||||
|
||||
#if 0
|
||||
// the code below is disabled because vxuCannyEdgeDetector()
|
||||
// ignores context attribute VX_CONTEXT_IMMEDIATE_BORDER
|
||||
|
||||
// FIXME: may fail in multithread case
|
||||
border_t prevBorder = context.immediateBorder();
|
||||
context.setImmediateBorder(VX_BORDER_REPLICATE);
|
||||
IVX_CHECK_STATUS( vxuCannyEdgeDetector(context, _src, threshold, kSize, (useL2 ? VX_NORM_L2 : VX_NORM_L1), _dst) );
|
||||
context.setImmediateBorder(prevBorder);
|
||||
#else
|
||||
// alternative code without vxuCannyEdgeDetector()
|
||||
Graph graph = Graph::create(context);
|
||||
ivx::Node node = ivx::Node(vxCannyEdgeDetectorNode(graph, _src, threshold, kSize, (useL2 ? VX_NORM_L2 : VX_NORM_L1), _dst) );
|
||||
node.setBorder(VX_BORDER_REPLICATE);
|
||||
graph.verify();
|
||||
graph.process();
|
||||
#endif
|
||||
|
||||
#ifdef VX_VERSION_1_1
|
||||
_src.swapHandle();
|
||||
_dst.swapHandle();
|
||||
#endif
|
||||
}
|
||||
catch(const WrapperError& e)
|
||||
{
|
||||
VX_DbgThrow(e.what());
|
||||
}
|
||||
catch(const RuntimeError& e)
|
||||
{
|
||||
VX_DbgThrow(e.what());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif // HAVE_OPENVX
|
||||
|
||||
void Canny( InputArray _src, OutputArray _dst,
|
||||
double low_thresh, double high_thresh,
|
||||
int aperture_size, bool L2gradient )
|
||||
@@ -864,21 +803,6 @@ void Canny( InputArray _src, OutputArray _dst,
|
||||
CALL_HAL(canny, cv_hal_canny, src.data, src.step, dst.data, dst.step, src.cols, src.rows, src.channels(),
|
||||
low_thresh, high_thresh, aperture_size, L2gradient);
|
||||
|
||||
CV_OVX_RUN(
|
||||
false && /* disabling due to accuracy issues */
|
||||
src.type() == CV_8UC1 &&
|
||||
!src.isSubmatrix() &&
|
||||
src.cols >= aperture_size &&
|
||||
src.rows >= aperture_size &&
|
||||
!ovx::skipSmallImages<VX_KERNEL_CANNY_EDGE_DETECTOR>(src.cols, src.rows),
|
||||
openvx_canny(
|
||||
src,
|
||||
dst,
|
||||
cvFloor(low_thresh),
|
||||
cvFloor(high_thresh),
|
||||
aperture_size,
|
||||
L2gradient ) )
|
||||
|
||||
CV_IPP_RUN_FAST(ipp_Canny(src, Mat(), Mat(), dst, (float)low_thresh, (float)high_thresh, L2gradient, aperture_size))
|
||||
|
||||
if (L2gradient)
|
||||
|
||||
@@ -43,7 +43,6 @@
|
||||
#include "precomp.hpp"
|
||||
#include "opencl_kernels_imgproc.hpp"
|
||||
|
||||
#include "opencv2/core/openvx/ovx_defs.hpp"
|
||||
#include "filter.hpp"
|
||||
|
||||
/****************************************************************************************\
|
||||
@@ -182,83 +181,6 @@ cv::Ptr<cv::FilterEngine> cv::createDerivFilter(int srcType, int dstType,
|
||||
kx, ky, Point(-1,-1), 0, borderType );
|
||||
}
|
||||
|
||||
#ifdef HAVE_OPENVX
|
||||
namespace cv
|
||||
{
|
||||
namespace ovx {
|
||||
template <> inline bool skipSmallImages<VX_KERNEL_SOBEL_3x3>(int w, int h) { return w*h < 320 * 240; }
|
||||
}
|
||||
static bool openvx_sobel(InputArray _src, OutputArray _dst,
|
||||
int dx, int dy, int ksize,
|
||||
double scale, double delta, int borderType)
|
||||
{
|
||||
if (_src.type() != CV_8UC1 || _dst.type() != CV_16SC1 ||
|
||||
ksize != 3 || scale != 1.0 || delta != 0.0 ||
|
||||
(dx | dy) != 1 || (dx + dy) != 1 ||
|
||||
_src.cols() < ksize || _src.rows() < ksize ||
|
||||
ovx::skipSmallImages<VX_KERNEL_SOBEL_3x3>(_src.cols(), _src.rows())
|
||||
)
|
||||
return false;
|
||||
|
||||
Mat src = _src.getMat();
|
||||
Mat dst = _dst.getMat();
|
||||
|
||||
if ((borderType & BORDER_ISOLATED) == 0 && src.isSubmatrix())
|
||||
return false; //Process isolated borders only
|
||||
vx_enum border;
|
||||
switch (borderType & ~BORDER_ISOLATED)
|
||||
{
|
||||
case BORDER_CONSTANT:
|
||||
border = VX_BORDER_CONSTANT;
|
||||
break;
|
||||
case BORDER_REPLICATE:
|
||||
// border = VX_BORDER_REPLICATE;
|
||||
// break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ivx::Context ctx = ovx::getOpenVXContext();
|
||||
//if ((vx_size)ksize > ctx.convolutionMaxDimension())
|
||||
// return false;
|
||||
|
||||
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_S16,
|
||||
ivx::Image::createAddressing(dst.cols, dst.rows, 2, (vx_int32)(dst.step)), dst.data);
|
||||
|
||||
//ATTENTION: VX_CONTEXT_IMMEDIATE_BORDER attribute change could lead to strange issues in multi-threaded environments
|
||||
//since OpenVX standard says nothing about thread-safety for now
|
||||
ivx::border_t prevBorder = ctx.immediateBorder();
|
||||
ctx.setImmediateBorder(border, (vx_uint8)(0));
|
||||
if(dx)
|
||||
ivx::IVX_CHECK_STATUS(vxuSobel3x3(ctx, ia, ib, NULL));
|
||||
else
|
||||
ivx::IVX_CHECK_STATUS(vxuSobel3x3(ctx, ia, NULL, ib));
|
||||
ctx.setImmediateBorder(prevBorder);
|
||||
}
|
||||
catch (const ivx::RuntimeError & e)
|
||||
{
|
||||
VX_DbgThrow(e.what());
|
||||
}
|
||||
catch (const ivx::WrapperError & e)
|
||||
{
|
||||
VX_DbgThrow(e.what());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0 //defined HAVE_IPP
|
||||
namespace cv
|
||||
@@ -456,8 +378,6 @@ void cv::Sobel( InputArray _src, OutputArray _dst, int ddepth, int dx, int dy,
|
||||
CALL_HAL(sobel, cv_hal_sobel, src.ptr(), src.step, dst.ptr(), dst.step, src.cols, src.rows, sdepth, ddepth, cn,
|
||||
ofs.x, ofs.y, wsz.width - src.cols - ofs.x, wsz.height - src.rows - ofs.y, dx, dy, ksize, scale, delta, borderType&~BORDER_ISOLATED);
|
||||
|
||||
CV_OVX_RUN(true,
|
||||
openvx_sobel(src, dst, dx, dy, ksize, scale, delta, borderType))
|
||||
|
||||
//CV_IPP_RUN_FAST(ipp_Deriv(src, dst, dx, dy, ksize, scale, delta, borderType));
|
||||
|
||||
|
||||
@@ -42,8 +42,6 @@
|
||||
#include "precomp.hpp"
|
||||
#include "opencl_kernels_imgproc.hpp"
|
||||
|
||||
#include "opencv2/core/openvx/ovx_defs.hpp"
|
||||
|
||||
#include <cstdio>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
@@ -274,95 +272,6 @@ static bool ocl_goodFeaturesToTrack( InputArray _image, OutputArray _corners,
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPENVX
|
||||
struct VxKeypointsComparator
|
||||
{
|
||||
bool operator () (const vx_keypoint_t& a, const vx_keypoint_t& b)
|
||||
{
|
||||
return a.strength > b.strength;
|
||||
}
|
||||
};
|
||||
|
||||
static bool openvx_harris(Mat image, OutputArray _corners,
|
||||
int _maxCorners, double _qualityLevel, double _minDistance,
|
||||
int _blockSize, int _gradientSize, double _harrisK)
|
||||
{
|
||||
using namespace ivx;
|
||||
|
||||
if(image.type() != CV_8UC1) return false;
|
||||
|
||||
//OpenVX implementations don't have to provide other sizes
|
||||
if(!(_blockSize == 3 || _blockSize == 5 || _blockSize == 7)) return false;
|
||||
|
||||
try
|
||||
{
|
||||
Context context = ovx::getOpenVXContext();
|
||||
|
||||
Image ovxImage = Image::createFromHandle(context, Image::matTypeToFormat(image.type()),
|
||||
Image::createAddressing(image), image.data);
|
||||
//The minimum threshold which to eliminate Harris Corner scores (computed using the normalized Sobel kernel).
|
||||
//set to 0, we'll filter it later by threshold
|
||||
ivx::Scalar strengthThresh = ivx::Scalar::create<VX_TYPE_FLOAT32>(context, 0);
|
||||
|
||||
//The gradient window size to use on the input.
|
||||
vx_int32 gradientSize = _gradientSize;
|
||||
|
||||
//The block window size used to compute the harris corner score
|
||||
vx_int32 blockSize = _blockSize;
|
||||
|
||||
//The scalar sensitivity threshold k from the Harris-Stephens equation
|
||||
ivx::Scalar sensivity = ivx::Scalar::create<VX_TYPE_FLOAT32>(context, _harrisK);
|
||||
|
||||
//The radial Euclidean distance for non-maximum suppression
|
||||
ivx::Scalar minDistance = ivx::Scalar::create<VX_TYPE_FLOAT32>(context, _minDistance);
|
||||
|
||||
vx_size capacity = image.cols * image.rows;
|
||||
Array corners = Array::create(context, VX_TYPE_KEYPOINT, capacity);
|
||||
ivx::Scalar numCorners = ivx::Scalar::create<VX_TYPE_SIZE>(context, 0);
|
||||
|
||||
IVX_CHECK_STATUS(vxuHarrisCorners(context, ovxImage, strengthThresh, minDistance, sensivity,
|
||||
gradientSize, blockSize, corners, numCorners));
|
||||
|
||||
std::vector<vx_keypoint_t> vxKeypoints;
|
||||
corners.copyTo(vxKeypoints);
|
||||
|
||||
std::sort(vxKeypoints.begin(), vxKeypoints.end(), VxKeypointsComparator());
|
||||
|
||||
vx_float32 maxStrength = 0.0f;
|
||||
if(vxKeypoints.size() > 0)
|
||||
maxStrength = vxKeypoints[0].strength;
|
||||
size_t maxKeypoints = min((size_t)_maxCorners, vxKeypoints.size());
|
||||
std::vector<Point2f> keypoints;
|
||||
keypoints.reserve(maxKeypoints);
|
||||
for(size_t i = 0; i < maxKeypoints; i++)
|
||||
{
|
||||
vx_keypoint_t kp = vxKeypoints[i];
|
||||
if(kp.strength < maxStrength*_qualityLevel) break;
|
||||
keypoints.push_back(Point2f((float)kp.x, (float)kp.y));
|
||||
}
|
||||
|
||||
Mat(keypoints).convertTo(_corners, _corners.fixedType() ? _corners.type() : CV_32F);
|
||||
|
||||
#ifdef VX_VERSION_1_1
|
||||
//we should take user memory back before release
|
||||
//(it's not done automatically according to standard)
|
||||
ovxImage.swapHandle();
|
||||
#endif
|
||||
}
|
||||
catch (const RuntimeError & e)
|
||||
{
|
||||
VX_DbgThrow(e.what());
|
||||
}
|
||||
catch (const WrapperError & e)
|
||||
{
|
||||
VX_DbgThrow(e.what());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void cv::goodFeaturesToTrack( InputArray image, OutputArray corners,
|
||||
@@ -403,11 +312,6 @@ void cv::goodFeaturesToTrack( InputArray _image, OutputArray _corners,
|
||||
return;
|
||||
}
|
||||
|
||||
// Disabled due to bad accuracy
|
||||
CV_OVX_RUN(false && useHarrisDetector && _mask.empty() &&
|
||||
!ovx::skipSmallImages<VX_KERNEL_HARRIS_CORNERS>(image.cols, image.rows),
|
||||
openvx_harris(image, _corners, maxCorners, qualityLevel, minDistance, blockSize, gradientSize, harrisK))
|
||||
|
||||
if( useHarrisDetector )
|
||||
cornerHarris( image, eig, blockSize, gradientSize, harrisK );
|
||||
else
|
||||
|
||||
@@ -43,8 +43,6 @@
|
||||
#include "opencl_kernels_imgproc.hpp"
|
||||
#include "opencv2/core/hal/intrin.hpp"
|
||||
|
||||
#include "opencv2/core/openvx/ovx_defs.hpp"
|
||||
|
||||
#include "opencv2/core/utils/tls.hpp"
|
||||
|
||||
void cvSetHistBinRanges( CvHistogram* hist, float** ranges, int uniform );
|
||||
@@ -838,64 +836,6 @@ private:
|
||||
|
||||
}
|
||||
|
||||
#ifdef HAVE_OPENVX
|
||||
namespace cv
|
||||
{
|
||||
namespace ovx {
|
||||
template <> inline bool skipSmallImages<VX_KERNEL_HISTOGRAM>(int w, int h) { return w*h < 2048 * 1536; }
|
||||
}
|
||||
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 = ovx::getOpenVXContext();
|
||||
#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 (const ivx::RuntimeError & e)
|
||||
{
|
||||
VX_DbgThrow(e.what());
|
||||
}
|
||||
catch (const ivx::WrapperError & e)
|
||||
{
|
||||
VX_DbgThrow(e.what());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_IPP
|
||||
#define IPP_HISTOGRAM_PARALLEL 1
|
||||
namespace cv
|
||||
@@ -956,14 +896,6 @@ void cv::calcHist( const Mat* images, int nimages, const int* channels,
|
||||
|
||||
CV_Assert(images && nimages > 0);
|
||||
|
||||
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] &&
|
||||
!ovx::skipSmallImages<VX_KERNEL_HISTOGRAM>(images[0].cols, images[0].rows),
|
||||
openvx_calchist(images[0], _hist, histSize[0], ranges[0]))
|
||||
|
||||
Mat mask = _mask.getMat();
|
||||
|
||||
CV_Assert(dims > 0 && histSize);
|
||||
@@ -2611,43 +2543,6 @@ static bool ocl_equalizeHist(InputArray _src, OutputArray _dst)
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPENVX
|
||||
namespace cv
|
||||
{
|
||||
static bool openvx_equalize_hist(Mat srcMat, Mat dstMat)
|
||||
{
|
||||
using namespace ivx;
|
||||
|
||||
try
|
||||
{
|
||||
Context context = ovx::getOpenVXContext();
|
||||
Image srcImage = Image::createFromHandle(context, Image::matTypeToFormat(srcMat.type()),
|
||||
Image::createAddressing(srcMat), srcMat.data);
|
||||
Image dstImage = Image::createFromHandle(context, Image::matTypeToFormat(dstMat.type()),
|
||||
Image::createAddressing(dstMat), dstMat.data);
|
||||
|
||||
IVX_CHECK_STATUS(vxuEqualizeHist(context, srcImage, dstImage));
|
||||
|
||||
#ifdef VX_VERSION_1_1
|
||||
//we should take user memory back before release
|
||||
//(it's not done automatically according to standard)
|
||||
srcImage.swapHandle(); dstImage.swapHandle();
|
||||
#endif
|
||||
}
|
||||
catch (const RuntimeError & e)
|
||||
{
|
||||
VX_DbgThrow(e.what());
|
||||
}
|
||||
catch (const WrapperError & e)
|
||||
{
|
||||
VX_DbgThrow(e.what());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void cv::equalizeHist( InputArray _src, OutputArray _dst )
|
||||
{
|
||||
CV_INSTRUMENT_REGION();
|
||||
@@ -2664,9 +2559,6 @@ void cv::equalizeHist( InputArray _src, OutputArray _dst )
|
||||
_dst.create( src.size(), src.type() );
|
||||
Mat dst = _dst.getMat();
|
||||
|
||||
CV_OVX_RUN(!ovx::skipSmallImages<VX_KERNEL_EQUALIZE_HISTOGRAM>(src.cols, src.rows),
|
||||
openvx_equalize_hist(src, dst))
|
||||
|
||||
Mutex histogramLockInstance;
|
||||
|
||||
const int hist_sz = EqualizeHistCalcHist_Invoker::HIST_SZ;
|
||||
|
||||
@@ -52,7 +52,6 @@
|
||||
#include "hal_replacement.hpp"
|
||||
#include <opencv2/core/utils/configuration.private.hpp>
|
||||
#include "opencv2/core/hal/intrin.hpp"
|
||||
#include "opencv2/core/openvx/ovx_defs.hpp"
|
||||
#include "opencv2/core/softfloat.hpp"
|
||||
#include "imgwarp.hpp"
|
||||
|
||||
@@ -1573,94 +1572,6 @@ static bool ocl_logPolar(InputArray _src, OutputArray _dst,
|
||||
|
||||
#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:
|
||||
/* NEAREST_NEIGHBOR mode disabled since OpenCV round half to even while OpenVX sample implementation round half up
|
||||
#if VX_VERSION > VX_VERSION_1_0
|
||||
inter_type = VX_INTERPOLATION_NEAREST_NEIGHBOR;
|
||||
#else
|
||||
inter_type = VX_INTERPOLATION_TYPE_NEAREST_NEIGHBOR;
|
||||
#endif
|
||||
if (!map1.empty())
|
||||
for (int y = 0; y < map1.rows; ++y)
|
||||
{
|
||||
float* line = map1.ptr<float>(y);
|
||||
for (int x = 0; x < map1.cols; ++x)
|
||||
line[x] = cvRound(line[x]);
|
||||
}
|
||||
if (!map2.empty())
|
||||
for (int y = 0; y < map2.rows; ++y)
|
||||
{
|
||||
float* line = map2.ptr<float>(y);
|
||||
for (int x = 0; x < map2.cols; ++x)
|
||||
line[x] = cvRound(line[x]);
|
||||
}
|
||||
break;
|
||||
*/
|
||||
case INTER_AREA://AREA interpolation mode is unsupported
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ivx::Context ctx = ovx::getOpenVXContext();
|
||||
|
||||
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 standard 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 (const ivx::RuntimeError & e)
|
||||
{
|
||||
CV_Error(cv::Error::StsInternal, e.what());
|
||||
return false;
|
||||
}
|
||||
catch (const ivx::WrapperError & e)
|
||||
{
|
||||
CV_Error(cv::Error::StsInternal, e.what());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined HAVE_IPP && !IPP_DISABLE_REMAP
|
||||
|
||||
typedef IppStatus (CV_STDCALL * ippiRemap)(const void * pSrc, IppiSize srcSize, int srcStep, IppiRect srcRoi,
|
||||
@@ -1800,17 +1711,6 @@ void cv::remap( InputArray _src, OutputArray _dst,
|
||||
Mat dst = _dst.getMat();
|
||||
|
||||
|
||||
CV_OVX_RUN(
|
||||
src.type() == CV_8UC1 && dst.type() == CV_8UC1 &&
|
||||
!ovx::skipSmallImages<VX_KERNEL_REMAP>(src.cols, src.rows) &&
|
||||
(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()) &&
|
||||
!hasRelativeFlag,
|
||||
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 );
|
||||
|
||||
if( dst.data == src.data )
|
||||
|
||||
@@ -48,8 +48,6 @@
|
||||
#include "opencv2/core/hal/intrin.hpp"
|
||||
#include "opencl_kernels_imgproc.hpp"
|
||||
|
||||
#include "opencv2/core/openvx/ovx_defs.hpp"
|
||||
|
||||
#include "median_blur.simd.hpp"
|
||||
#include "median_blur.simd_declarations.hpp" // defines CV_CPU_DISPATCH_MODES_ALL=AVX2,...,BASELINE based on CMakeLists.txt content
|
||||
|
||||
@@ -112,97 +110,6 @@ static bool ocl_medianFilter(InputArray _src, OutputArray _dst, int m)
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPENVX
|
||||
namespace ovx {
|
||||
template <> inline bool skipSmallImages<VX_KERNEL_MEDIAN_3x3>(int w, int h) { return w*h < 1280 * 720; }
|
||||
}
|
||||
static bool openvx_medianFilter(InputArray _src, OutputArray _dst, int ksize)
|
||||
{
|
||||
if (_src.type() != CV_8UC1 || _dst.type() != CV_8U
|
||||
#ifndef VX_VERSION_1_1
|
||||
|| ksize != 3
|
||||
#endif
|
||||
)
|
||||
return false;
|
||||
|
||||
Mat src = _src.getMat();
|
||||
Mat dst = _dst.getMat();
|
||||
|
||||
if (
|
||||
#ifdef VX_VERSION_1_1
|
||||
ksize != 3 ? ovx::skipSmallImages<VX_KERNEL_NON_LINEAR_FILTER>(src.cols, src.rows) :
|
||||
#endif
|
||||
ovx::skipSmallImages<VX_KERNEL_MEDIAN_3x3>(src.cols, src.rows)
|
||||
)
|
||||
return false;
|
||||
|
||||
try
|
||||
{
|
||||
ivx::Context ctx = ovx::getOpenVXContext();
|
||||
#ifdef VX_VERSION_1_1
|
||||
if ((vx_size)ksize > ctx.nonlinearMaxDimension())
|
||||
return false;
|
||||
#endif
|
||||
|
||||
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 standard says nothing about thread-safety for now
|
||||
ivx::border_t prevBorder = ctx.immediateBorder();
|
||||
ctx.setImmediateBorder(VX_BORDER_REPLICATE);
|
||||
#ifdef VX_VERSION_1_1
|
||||
if (ksize == 3)
|
||||
#endif
|
||||
{
|
||||
ivx::IVX_CHECK_STATUS(vxuMedian3x3(ctx, ia, ib));
|
||||
}
|
||||
#ifdef VX_VERSION_1_1
|
||||
else
|
||||
{
|
||||
ivx::Matrix mtx;
|
||||
if(ksize == 5)
|
||||
mtx = ivx::Matrix::createFromPattern(ctx, VX_PATTERN_BOX, ksize, ksize);
|
||||
else
|
||||
{
|
||||
vx_size supportedSize;
|
||||
ivx::IVX_CHECK_STATUS(vxQueryContext(ctx, VX_CONTEXT_NONLINEAR_MAX_DIMENSION, &supportedSize, sizeof(supportedSize)));
|
||||
if ((vx_size)ksize > supportedSize)
|
||||
{
|
||||
ctx.setImmediateBorder(prevBorder);
|
||||
return false;
|
||||
}
|
||||
Mat mask(ksize, ksize, CV_8UC1, Scalar(255));
|
||||
mtx = ivx::Matrix::create(ctx, VX_TYPE_UINT8, ksize, ksize);
|
||||
mtx.copyFrom(mask);
|
||||
}
|
||||
ivx::IVX_CHECK_STATUS(vxuNonLinearFilter(ctx, VX_NONLINEAR_FILTER_MEDIAN, ia, mtx, ib));
|
||||
}
|
||||
#endif
|
||||
ctx.setImmediateBorder(prevBorder);
|
||||
}
|
||||
catch (const ivx::RuntimeError & e)
|
||||
{
|
||||
VX_DbgThrow(e.what());
|
||||
}
|
||||
catch (const ivx::WrapperError & e)
|
||||
{
|
||||
VX_DbgThrow(e.what());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0 //defined HAVE_IPP
|
||||
static bool ipp_medianFilter(Mat &src0, Mat &dst, int ksize)
|
||||
{
|
||||
@@ -300,9 +207,6 @@ void medianBlur( InputArray _src0, OutputArray _dst, int ksize )
|
||||
CALL_HAL(medianBlur, cv_hal_medianBlur, src0.data, src0.step, dst.data, dst.step, src0.cols, src0.rows, src0.depth(),
|
||||
src0.channels(), ksize);
|
||||
|
||||
CV_OVX_RUN(true,
|
||||
openvx_medianFilter(_src0, _dst, ksize))
|
||||
|
||||
//CV_IPP_RUN_FAST(ipp_medianFilter(src0, dst, ksize));
|
||||
|
||||
CV_CPU_DISPATCH(medianBlur, (src0, dst, ksize),
|
||||
|
||||
@@ -45,7 +45,6 @@
|
||||
#include "opencl_kernels_imgproc.hpp"
|
||||
#include "opencv2/core/hal/intrin.hpp"
|
||||
|
||||
#include "opencv2/core/openvx/ovx_defs.hpp"
|
||||
|
||||
namespace cv
|
||||
{
|
||||
@@ -1329,85 +1328,6 @@ static bool ipp_pyrdown( InputArray _src, OutputArray _dst, const Size& _dsz, in
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPENVX
|
||||
namespace cv
|
||||
{
|
||||
static bool openvx_pyrDown( InputArray _src, OutputArray _dst, const Size& _dsz, int borderType )
|
||||
{
|
||||
using namespace ivx;
|
||||
|
||||
Mat srcMat = _src.getMat();
|
||||
|
||||
if (ovx::skipSmallImages<VX_KERNEL_HALFSCALE_GAUSSIAN>(srcMat.cols, srcMat.rows))
|
||||
return false;
|
||||
|
||||
CV_Assert(!srcMat.empty());
|
||||
|
||||
Size ssize = _src.size();
|
||||
Size acceptableSize = Size((ssize.width + 1) / 2, (ssize.height + 1) / 2);
|
||||
|
||||
// OpenVX limitations
|
||||
if((srcMat.type() != CV_8U) ||
|
||||
(borderType != BORDER_REPLICATE) ||
|
||||
(_dsz != acceptableSize && !_dsz.empty()))
|
||||
return false;
|
||||
|
||||
// The only border mode which is supported by both cv::pyrDown() and OpenVX
|
||||
// and produces predictable results
|
||||
ivx::border_t borderMode;
|
||||
borderMode.mode = VX_BORDER_REPLICATE;
|
||||
|
||||
_dst.create( acceptableSize, srcMat.type() );
|
||||
Mat dstMat = _dst.getMat();
|
||||
|
||||
CV_Assert( ssize.width > 0 && ssize.height > 0 &&
|
||||
std::abs(acceptableSize.width*2 - ssize.width) <= 2 &&
|
||||
std::abs(acceptableSize.height*2 - ssize.height) <= 2 );
|
||||
|
||||
try
|
||||
{
|
||||
Context context = ovx::getOpenVXContext();
|
||||
if(context.vendorID() == VX_ID_KHRONOS)
|
||||
{
|
||||
// This implementation performs floor-like rounding
|
||||
// (OpenCV uses floor(x+0.5)-like rounding)
|
||||
// and ignores border mode (and loses 1px size border)
|
||||
return false;
|
||||
}
|
||||
|
||||
Image srcImg = Image::createFromHandle(context, Image::matTypeToFormat(srcMat.type()),
|
||||
Image::createAddressing(srcMat), (void*)srcMat.data);
|
||||
Image dstImg = Image::createFromHandle(context, Image::matTypeToFormat(dstMat.type()),
|
||||
Image::createAddressing(dstMat), (void*)dstMat.data);
|
||||
|
||||
ivx::Scalar kernelSize = ivx::Scalar::create<VX_TYPE_INT32>(context, 5);
|
||||
Graph graph = Graph::create(context);
|
||||
ivx::Node halfNode = ivx::Node::create(graph, VX_KERNEL_HALFSCALE_GAUSSIAN, srcImg, dstImg, kernelSize);
|
||||
halfNode.setBorder(borderMode);
|
||||
graph.verify();
|
||||
graph.process();
|
||||
|
||||
#ifdef VX_VERSION_1_1
|
||||
//we should take user memory back before release
|
||||
//(it's not done automatically according to standard)
|
||||
srcImg.swapHandle(); dstImg.swapHandle();
|
||||
#endif
|
||||
}
|
||||
catch (const RuntimeError & e)
|
||||
{
|
||||
VX_DbgThrow(e.what());
|
||||
}
|
||||
catch (const WrapperError & e)
|
||||
{
|
||||
VX_DbgThrow(e.what());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
void cv::pyrDown( InputArray _src, OutputArray _dst, const Size& _dsz, int borderType )
|
||||
{
|
||||
CV_INSTRUMENT_REGION();
|
||||
@@ -1417,9 +1337,6 @@ void cv::pyrDown( InputArray _src, OutputArray _dst, const Size& _dsz, int borde
|
||||
CV_OCL_RUN(_src.dims() <= 2 && _dst.isUMat(),
|
||||
ocl_pyrDown(_src, _dst, _dsz, borderType))
|
||||
|
||||
CV_OVX_RUN(_src.dims() <= 2,
|
||||
openvx_pyrDown(_src, _dst, _dsz, borderType))
|
||||
|
||||
Mat src = _src.getMat();
|
||||
Size dsz = _dsz.empty() ? Size((src.cols + 1)/2, (src.rows + 1)/2) : _dsz;
|
||||
_dst.create( dsz, src.type() );
|
||||
|
||||
@@ -53,7 +53,6 @@
|
||||
#include "opencv2/core/hal/intrin.hpp"
|
||||
#include "opencv2/core/utils/buffer_area.private.hpp"
|
||||
|
||||
#include "opencv2/core/openvx/ovx_defs.hpp"
|
||||
#include "resize.hpp"
|
||||
|
||||
#include "opencv2/core/softfloat.hpp"
|
||||
|
||||
@@ -53,8 +53,6 @@
|
||||
#include "opencv2/core/hal/intrin.hpp"
|
||||
#include "opencl_kernels_imgproc.hpp"
|
||||
|
||||
#include "opencv2/core/openvx/ovx_defs.hpp"
|
||||
|
||||
#include "filter.hpp"
|
||||
|
||||
#include "opencv2/core/softfloat.hpp"
|
||||
@@ -386,88 +384,6 @@ static bool ocl_GaussianBlur_8UC1(InputArray _src, OutputArray _dst, Size ksize,
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPENVX
|
||||
|
||||
namespace ovx {
|
||||
template <> inline bool skipSmallImages<VX_KERNEL_GAUSSIAN_3x3>(int w, int h) { return w*h < 320 * 240; }
|
||||
}
|
||||
static bool openvx_gaussianBlur(InputArray _src, OutputArray _dst, Size ksize,
|
||||
double sigma1, double sigma2, int borderType)
|
||||
{
|
||||
if (sigma2 <= 0)
|
||||
sigma2 = sigma1;
|
||||
// automatic detection of kernel size from sigma
|
||||
if (ksize.width <= 0 && sigma1 > 0)
|
||||
ksize.width = cvRound(sigma1*6 + 1) | 1;
|
||||
if (ksize.height <= 0 && sigma2 > 0)
|
||||
ksize.height = cvRound(sigma2*6 + 1) | 1;
|
||||
|
||||
if (_src.type() != CV_8UC1 ||
|
||||
_src.cols() < 3 || _src.rows() < 3 ||
|
||||
ksize.width != 3 || ksize.height != 3)
|
||||
return false;
|
||||
|
||||
sigma1 = std::max(sigma1, 0.);
|
||||
sigma2 = std::max(sigma2, 0.);
|
||||
|
||||
if (!(sigma1 == 0.0 || (sigma1 - 0.8) < DBL_EPSILON) || !(sigma2 == 0.0 || (sigma2 - 0.8) < DBL_EPSILON) ||
|
||||
ovx::skipSmallImages<VX_KERNEL_GAUSSIAN_3x3>(_src.cols(), _src.rows()))
|
||||
return false;
|
||||
|
||||
Mat src = _src.getMat();
|
||||
Mat dst = _dst.getMat();
|
||||
|
||||
if ((borderType & BORDER_ISOLATED) == 0 && src.isSubmatrix())
|
||||
return false; //Process isolated borders only
|
||||
vx_enum border;
|
||||
switch (borderType & ~BORDER_ISOLATED)
|
||||
{
|
||||
case BORDER_CONSTANT:
|
||||
border = VX_BORDER_CONSTANT;
|
||||
break;
|
||||
case BORDER_REPLICATE:
|
||||
border = VX_BORDER_REPLICATE;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ivx::Context ctx = ovx::getOpenVXContext();
|
||||
|
||||
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 standard says nothing about thread-safety for now
|
||||
ivx::border_t prevBorder = ctx.immediateBorder();
|
||||
ctx.setImmediateBorder(border, (vx_uint8)(0));
|
||||
ivx::IVX_CHECK_STATUS(vxuGaussian3x3(ctx, ia, ib));
|
||||
ctx.setImmediateBorder(prevBorder);
|
||||
}
|
||||
catch (const ivx::RuntimeError & e)
|
||||
{
|
||||
VX_DbgThrow(e.what());
|
||||
}
|
||||
catch (const ivx::WrapperError & e)
|
||||
{
|
||||
VX_DbgThrow(e.what());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined ENABLE_IPP_GAUSSIAN_BLUR // see CMake's OPENCV_IPP_GAUSSIAN_BLUR option
|
||||
|
||||
#define IPP_DISABLE_GAUSSIAN_BLUR_LARGE_KERNELS_1TH 1
|
||||
@@ -746,9 +662,6 @@ void GaussianBlur(InputArray _src, OutputArray _dst, Size ksize,
|
||||
ofs.x, ofs.y, wsz.width - src.cols - ofs.x, wsz.height - src.rows - ofs.y, ksize.width, ksize.height,
|
||||
sigma1, sigma2, borderType&~BORDER_ISOLATED);
|
||||
|
||||
CV_OVX_RUN(true,
|
||||
openvx_gaussianBlur(src, dst, ksize, sigma1, sigma2, borderType))
|
||||
|
||||
#if defined ENABLE_IPP_GAUSSIAN_BLUR
|
||||
// IPP is not bit-exact to OpenCV implementation
|
||||
CV_IPP_RUN_FAST(ipp_GaussianBlur(src, dst, ksize, sigma1, sigma2, borderType));
|
||||
|
||||
@@ -44,8 +44,6 @@
|
||||
#include "opencl_kernels_imgproc.hpp"
|
||||
#include "opencv2/core/hal/intrin.hpp"
|
||||
|
||||
#include "opencv2/core/openvx/ovx_defs.hpp"
|
||||
|
||||
namespace cv
|
||||
{
|
||||
|
||||
@@ -1443,98 +1441,6 @@ static bool ocl_threshold( InputArray _src, OutputArray _dst, double & thresh, d
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HAVE_OPENVX
|
||||
#define IMPL_OPENVX_TOZERO 1
|
||||
static bool openvx_threshold(Mat src, Mat dst, int thresh, int maxval, int type)
|
||||
{
|
||||
Mat a = src;
|
||||
|
||||
int trueVal, falseVal;
|
||||
switch (type)
|
||||
{
|
||||
case THRESH_BINARY:
|
||||
#ifndef VX_VERSION_1_1
|
||||
if (maxval != 255)
|
||||
return false;
|
||||
#endif
|
||||
trueVal = maxval;
|
||||
falseVal = 0;
|
||||
break;
|
||||
case THRESH_TOZERO:
|
||||
#if IMPL_OPENVX_TOZERO
|
||||
trueVal = 255;
|
||||
falseVal = 0;
|
||||
if (dst.data == src.data)
|
||||
{
|
||||
a = Mat(src.size(), src.type());
|
||||
src.copyTo(a);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case THRESH_BINARY_INV:
|
||||
#ifdef VX_VERSION_1_1
|
||||
trueVal = 0;
|
||||
falseVal = maxval;
|
||||
break;
|
||||
#endif
|
||||
case THRESH_TOZERO_INV:
|
||||
#ifdef VX_VERSION_1_1
|
||||
#if IMPL_OPENVX_TOZERO
|
||||
trueVal = 0;
|
||||
falseVal = 255;
|
||||
if (dst.data == src.data)
|
||||
{
|
||||
a = Mat(src.size(), src.type());
|
||||
src.copyTo(a);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
case THRESH_TRUNC:
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ivx::Context ctx = ovx::getOpenVXContext();
|
||||
|
||||
ivx::Threshold thh = ivx::Threshold::createBinary(ctx, VX_TYPE_UINT8, thresh);
|
||||
thh.setValueTrue(trueVal);
|
||||
thh.setValueFalse(falseVal);
|
||||
|
||||
ivx::Image
|
||||
ia = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8,
|
||||
ivx::Image::createAddressing(a.cols*a.channels(), a.rows, 1, (vx_int32)(a.step)), src.data),
|
||||
ib = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8,
|
||||
ivx::Image::createAddressing(dst.cols*dst.channels(), dst.rows, 1, (vx_int32)(dst.step)), dst.data);
|
||||
|
||||
ivx::IVX_CHECK_STATUS(vxuThreshold(ctx, ia, thh, ib));
|
||||
#if IMPL_OPENVX_TOZERO
|
||||
if (type == THRESH_TOZERO || type == THRESH_TOZERO_INV)
|
||||
{
|
||||
ivx::Image
|
||||
ic = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8,
|
||||
ivx::Image::createAddressing(dst.cols*dst.channels(), dst.rows, 1, (vx_int32)(dst.step)), dst.data);
|
||||
ivx::IVX_CHECK_STATUS(vxuAnd(ctx, ib, ia, ic));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
catch (const ivx::RuntimeError & e)
|
||||
{
|
||||
VX_DbgThrow(e.what());
|
||||
}
|
||||
catch (const ivx::WrapperError & e)
|
||||
{
|
||||
VX_DbgThrow(e.what());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
double cv::threshold( InputArray _src, OutputArray _dst, double thresh, double maxval, int type )
|
||||
@@ -1590,8 +1496,6 @@ double cv::threshold( InputArray _src, OutputArray _dst, double thresh, double m
|
||||
return thresh;
|
||||
}
|
||||
|
||||
CV_OVX_RUN(!ovx::skipSmallImages<VX_KERNEL_THRESHOLD>(src.cols, src.rows),
|
||||
openvx_threshold(src, dst, ithresh, imaxval, type), (double)ithresh)
|
||||
|
||||
thresh = ithresh;
|
||||
maxval = imaxval;
|
||||
|
||||
@@ -316,108 +316,5 @@ int CV_CannyTest::validate_test_results( int test_case_idx )
|
||||
TEST(Imgproc_Canny, accuracy) { CV_CannyTest test; test.safe_run(); }
|
||||
TEST(Imgproc_Canny, accuracy_deriv) { CV_CannyTest test(true); test.safe_run(); }
|
||||
|
||||
|
||||
/*
|
||||
* Comparing OpenVX based implementation with the main one
|
||||
*/
|
||||
|
||||
#ifndef IMPLEMENT_PARAM_CLASS
|
||||
#define IMPLEMENT_PARAM_CLASS(name, type) \
|
||||
class name \
|
||||
{ \
|
||||
public: \
|
||||
name ( type arg = type ()) : val_(arg) {} \
|
||||
operator type () const {return val_;} \
|
||||
private: \
|
||||
type val_; \
|
||||
}; \
|
||||
inline void PrintTo( name param, std::ostream* os) \
|
||||
{ \
|
||||
*os << #name << "(" << testing::PrintToString(static_cast< type >(param)) << ")"; \
|
||||
}
|
||||
#endif // IMPLEMENT_PARAM_CLASS
|
||||
|
||||
IMPLEMENT_PARAM_CLASS(ImagePath, string)
|
||||
IMPLEMENT_PARAM_CLASS(ApertureSize, int)
|
||||
IMPLEMENT_PARAM_CLASS(L2gradient, bool)
|
||||
|
||||
PARAM_TEST_CASE(CannyVX, ImagePath, ApertureSize, L2gradient)
|
||||
{
|
||||
string imgPath;
|
||||
int kSize;
|
||||
bool useL2;
|
||||
Mat src, dst;
|
||||
|
||||
virtual void SetUp()
|
||||
{
|
||||
imgPath = GET_PARAM(0);
|
||||
kSize = GET_PARAM(1);
|
||||
useL2 = GET_PARAM(2);
|
||||
}
|
||||
|
||||
void loadImage()
|
||||
{
|
||||
src = cv::imread(cvtest::TS::ptr()->get_data_path() + imgPath, IMREAD_GRAYSCALE);
|
||||
ASSERT_FALSE(src.empty()) << "can't load image: " << imgPath;
|
||||
}
|
||||
};
|
||||
|
||||
TEST_P(CannyVX, Accuracy)
|
||||
{
|
||||
if(haveOpenVX())
|
||||
{
|
||||
loadImage();
|
||||
|
||||
setUseOpenVX(false);
|
||||
Mat canny;
|
||||
cv::Canny(src, canny, 100, 150, 3);
|
||||
|
||||
setUseOpenVX(true);
|
||||
Mat cannyVX;
|
||||
cv::Canny(src, cannyVX, 100, 150, 3);
|
||||
|
||||
// 'smart' diff check (excluding isolated pixels)
|
||||
Mat diff, diff1;
|
||||
absdiff(canny, cannyVX, diff);
|
||||
boxFilter(diff, diff1, -1, Size(3,3));
|
||||
const int minPixelsAroud = 3; // empirical number
|
||||
diff1 = diff1 > 255/9 * minPixelsAroud;
|
||||
erode(diff1, diff1, Mat());
|
||||
double error = cv::norm(diff1, NORM_L1) / 255;
|
||||
const int maxError = std::min(10, diff.size().area()/100); // empirical number
|
||||
if(error > maxError)
|
||||
{
|
||||
string outPath =
|
||||
string("CannyVX-diff-") +
|
||||
imgPath + '-' +
|
||||
'k' + char(kSize+'0') + '-' +
|
||||
(useL2 ? "l2" : "l1");
|
||||
std::replace(outPath.begin(), outPath.end(), '/', '_');
|
||||
std::replace(outPath.begin(), outPath.end(), '\\', '_');
|
||||
std::replace(outPath.begin(), outPath.end(), '.', '_');
|
||||
imwrite(outPath+".png", diff);
|
||||
}
|
||||
ASSERT_LE(error, maxError);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
ImgProc, CannyVX,
|
||||
testing::Combine(
|
||||
testing::Values(
|
||||
string("shared/baboon.png"),
|
||||
string("shared/fruits.png"),
|
||||
string("shared/lena.png"),
|
||||
string("shared/pic1.png"),
|
||||
string("shared/pic3.png"),
|
||||
string("shared/pic5.png"),
|
||||
string("shared/pic6.png")
|
||||
),
|
||||
testing::Values(ApertureSize(3), ApertureSize(5)),
|
||||
testing::Values(L2gradient(false), L2gradient(true))
|
||||
)
|
||||
);
|
||||
|
||||
}} // namespace
|
||||
/* End of file. */
|
||||
|
||||
@@ -49,8 +49,6 @@
|
||||
#include "opencv2/3d.hpp"
|
||||
#endif
|
||||
|
||||
#include "opencv2/core/openvx/ovx_defs.hpp"
|
||||
|
||||
#define CV_DESCALE(x,n) (((x) + (1 << ((n)-1))) >> (n))
|
||||
|
||||
namespace
|
||||
@@ -1084,154 +1082,6 @@ namespace
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPENVX
|
||||
bool openvx_pyrlk(InputArray _prevImg, InputArray _nextImg, InputArray _prevPts, InputOutputArray _nextPts,
|
||||
OutputArray _status, OutputArray _err)
|
||||
{
|
||||
using namespace ivx;
|
||||
|
||||
// Pyramids as inputs are not acceptable because there's no (direct or simple) way
|
||||
// to build vx_pyramid on user data
|
||||
if(_prevImg.kind() != _InputArray::MAT || _nextImg.kind() != _InputArray::MAT)
|
||||
return false;
|
||||
|
||||
Mat prevImgMat = _prevImg.getMat(), nextImgMat = _nextImg.getMat();
|
||||
|
||||
if(prevImgMat.type() != CV_8UC1 || nextImgMat.type() != CV_8UC1)
|
||||
return false;
|
||||
|
||||
if (ovx::skipSmallImages<VX_KERNEL_OPTICAL_FLOW_PYR_LK>(prevImgMat.cols, prevImgMat.rows))
|
||||
return false;
|
||||
|
||||
CV_Assert(prevImgMat.size() == nextImgMat.size());
|
||||
Mat prevPtsMat = _prevPts.getMat();
|
||||
int checkPrev = prevPtsMat.checkVector(2, CV_32F, false);
|
||||
CV_Assert( checkPrev >= 0 );
|
||||
size_t npoints = checkPrev;
|
||||
|
||||
if( !(flags & OPTFLOW_USE_INITIAL_FLOW) )
|
||||
_nextPts.create(prevPtsMat.size(), prevPtsMat.type(), -1, true);
|
||||
Mat nextPtsMat = _nextPts.getMat();
|
||||
CV_Assert( nextPtsMat.checkVector(2, CV_32F, false) == (int)npoints );
|
||||
|
||||
_status.create((int)npoints, 1, CV_8U, -1, true);
|
||||
Mat statusMat = _status.getMat();
|
||||
uchar* status = statusMat.ptr();
|
||||
for(size_t i = 0; i < npoints; i++ )
|
||||
status[i] = true;
|
||||
|
||||
// OpenVX doesn't return detection errors
|
||||
if( _err.needed() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Context context = ovx::getOpenVXContext();
|
||||
|
||||
if(context.vendorID() == VX_ID_KHRONOS)
|
||||
{
|
||||
// PyrLK in OVX 1.0.1 performs vxCommitImagePatch incorrecty and crashes
|
||||
if(VX_VERSION == VX_VERSION_1_0)
|
||||
return false;
|
||||
// Implementation ignores border mode
|
||||
// So check that minimal size of image in pyramid is big enough
|
||||
int width = prevImgMat.cols, height = prevImgMat.rows;
|
||||
for(int i = 0; i < maxLevel+1; i++)
|
||||
{
|
||||
if(width < winSize.width + 1 || height < winSize.height + 1)
|
||||
return false;
|
||||
else
|
||||
{
|
||||
width /= 2; height /= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Image prevImg = Image::createFromHandle(context, Image::matTypeToFormat(prevImgMat.type()),
|
||||
Image::createAddressing(prevImgMat), (void*)prevImgMat.data);
|
||||
Image nextImg = Image::createFromHandle(context, Image::matTypeToFormat(nextImgMat.type()),
|
||||
Image::createAddressing(nextImgMat), (void*)nextImgMat.data);
|
||||
|
||||
Graph graph = Graph::create(context);
|
||||
|
||||
Pyramid prevPyr = Pyramid::createVirtual(graph, (vx_size)maxLevel+1, VX_SCALE_PYRAMID_HALF,
|
||||
prevImg.width(), prevImg.height(), prevImg.format());
|
||||
Pyramid nextPyr = Pyramid::createVirtual(graph, (vx_size)maxLevel+1, VX_SCALE_PYRAMID_HALF,
|
||||
nextImg.width(), nextImg.height(), nextImg.format());
|
||||
|
||||
ivx::Node::create(graph, VX_KERNEL_GAUSSIAN_PYRAMID, prevImg, prevPyr);
|
||||
ivx::Node::create(graph, VX_KERNEL_GAUSSIAN_PYRAMID, nextImg, nextPyr);
|
||||
|
||||
Array prevPts = Array::create(context, VX_TYPE_KEYPOINT, npoints);
|
||||
Array estimatedPts = Array::create(context, VX_TYPE_KEYPOINT, npoints);
|
||||
Array nextPts = Array::create(context, VX_TYPE_KEYPOINT, npoints);
|
||||
|
||||
std::vector<vx_keypoint_t> vxPrevPts(npoints), vxEstPts(npoints), vxNextPts(npoints);
|
||||
for(size_t i = 0; i < npoints; i++)
|
||||
{
|
||||
vx_keypoint_t& prevPt = vxPrevPts[i]; vx_keypoint_t& estPt = vxEstPts[i];
|
||||
prevPt.x = prevPtsMat.at<Point2f>(i).x; prevPt.y = prevPtsMat.at<Point2f>(i).y;
|
||||
estPt.x = nextPtsMat.at<Point2f>(i).x; estPt.y = nextPtsMat.at<Point2f>(i).y;
|
||||
prevPt.tracking_status = estPt.tracking_status = vx_true_e;
|
||||
}
|
||||
prevPts.addItems(vxPrevPts); estimatedPts.addItems(vxEstPts);
|
||||
|
||||
if( (criteria.type & TermCriteria::COUNT) == 0 )
|
||||
criteria.maxCount = 30;
|
||||
else
|
||||
criteria.maxCount = std::min(std::max(criteria.maxCount, 0), 100);
|
||||
if( (criteria.type & TermCriteria::EPS) == 0 )
|
||||
criteria.epsilon = 0.01;
|
||||
else
|
||||
criteria.epsilon = std::min(std::max(criteria.epsilon, 0.), 10.);
|
||||
criteria.epsilon *= criteria.epsilon;
|
||||
|
||||
vx_enum termEnum = (criteria.type == TermCriteria::COUNT) ? VX_TERM_CRITERIA_ITERATIONS :
|
||||
(criteria.type == TermCriteria::EPS) ? VX_TERM_CRITERIA_EPSILON :
|
||||
VX_TERM_CRITERIA_BOTH;
|
||||
|
||||
//minEigThreshold is fixed to 0.0001f
|
||||
ivx::Scalar termination = ivx::Scalar::create<VX_TYPE_ENUM>(context, termEnum);
|
||||
ivx::Scalar epsilon = ivx::Scalar::create<VX_TYPE_FLOAT32>(context, criteria.epsilon);
|
||||
ivx::Scalar numIterations = ivx::Scalar::create<VX_TYPE_UINT32>(context, criteria.maxCount);
|
||||
ivx::Scalar useInitial = ivx::Scalar::create<VX_TYPE_BOOL>(context, (vx_bool)(flags & OPTFLOW_USE_INITIAL_FLOW));
|
||||
//assume winSize is square
|
||||
ivx::Scalar windowSize = ivx::Scalar::create<VX_TYPE_SIZE>(context, (vx_size)winSize.width);
|
||||
|
||||
ivx::Node::create(graph, VX_KERNEL_OPTICAL_FLOW_PYR_LK, prevPyr, nextPyr, prevPts, estimatedPts,
|
||||
nextPts, termination, epsilon, numIterations, useInitial, windowSize);
|
||||
|
||||
graph.verify();
|
||||
graph.process();
|
||||
|
||||
nextPts.copyTo(vxNextPts);
|
||||
for(size_t i = 0; i < npoints; i++)
|
||||
{
|
||||
vx_keypoint_t kp = vxNextPts[i];
|
||||
nextPtsMat.at<Point2f>(i) = Point2f(kp.x, kp.y);
|
||||
statusMat.at<uchar>(i) = (bool)kp.tracking_status;
|
||||
}
|
||||
|
||||
#ifdef VX_VERSION_1_1
|
||||
//we should take user memory back before release
|
||||
//(it's not done automatically according to standard)
|
||||
prevImg.swapHandle(); nextImg.swapHandle();
|
||||
#endif
|
||||
}
|
||||
catch (const RuntimeError & e)
|
||||
{
|
||||
VX_DbgThrow(e.what());
|
||||
}
|
||||
catch (const WrapperError & e)
|
||||
{
|
||||
VX_DbgThrow(e.what());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@@ -1247,10 +1097,6 @@ void SparsePyrLKOpticalFlowImpl::calc( InputArray _prevImg, InputArray _nextImg,
|
||||
ocl::Image2D::isFormatSupported(CV_32F, 1, false),
|
||||
ocl_calcOpticalFlowPyrLK(_prevImg, _nextImg, _prevPts, _nextPts, _status, _err))
|
||||
|
||||
// Disabled due to bad accuracy
|
||||
CV_OVX_RUN(false,
|
||||
openvx_pyrlk(_prevImg, _nextImg, _prevPts, _nextPts, _status, _err))
|
||||
|
||||
Mat prevPtsMat = _prevPts.getMat();
|
||||
const int derivDepth = DataType<cv::detail::deriv_type>::depth;
|
||||
|
||||
|
||||
@@ -103,7 +103,6 @@ class Builder:
|
||||
"-DWITH_WEBP=OFF",
|
||||
"-DWITH_OPENEXR=OFF",
|
||||
"-DWITH_OPENGL=OFF",
|
||||
"-DWITH_OPENVX=OFF",
|
||||
"-DWITH_OPENNI=OFF",
|
||||
"-DWITH_OPENNI2=OFF",
|
||||
"-DWITH_PNG=OFF",
|
||||
|
||||
@@ -33,9 +33,6 @@ endif()
|
||||
if((NOT ANDROID) AND HAVE_OPENGL)
|
||||
add_subdirectory(opengl)
|
||||
endif()
|
||||
if(HAVE_OPENVX)
|
||||
add_subdirectory(openvx)
|
||||
endif()
|
||||
if(UNIX AND NOT ANDROID AND HAVE_VA)
|
||||
add_subdirectory(va_intel)
|
||||
endif()
|
||||
@@ -131,7 +128,6 @@ add_subdirectory(dnn)
|
||||
add_subdirectory(opencl)
|
||||
add_subdirectory(sycl)
|
||||
# add_subdirectory(opengl)
|
||||
# add_subdirectory(openvx)
|
||||
add_subdirectory(tapi)
|
||||
# add_subdirectory(va_intel)
|
||||
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
ocv_install_example_src(cpp *.cpp *.hpp CMakeLists.txt)
|
||||
|
||||
cmake_minimum_required(VERSION 2.8.12.2)
|
||||
|
||||
set(OPENCV_OPENVX_SAMPLE_REQUIRED_DEPS
|
||||
opencv_core
|
||||
opencv_imgproc
|
||||
opencv_imgcodecs
|
||||
opencv_videoio
|
||||
opencv_highgui)
|
||||
ocv_check_dependencies(${OPENCV_OPENVX_SAMPLE_REQUIRED_DEPS})
|
||||
|
||||
if(NOT BUILD_EXAMPLES OR NOT OCV_DEPENDENCIES_FOUND)
|
||||
return()
|
||||
endif()
|
||||
|
||||
project(openvx_samples)
|
||||
ocv_include_modules_recurse(${OPENCV_OPENVX_SAMPLE_REQUIRED_DEPS})
|
||||
add_definitions(-DIVX_USE_OPENCV)
|
||||
add_definitions(-DIVX_HIDE_INFO_WARNINGS)
|
||||
file(GLOB_RECURSE cpp_samples RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp)
|
||||
foreach(sample_filename ${cpp_samples})
|
||||
ocv_define_sample(tgt ${sample_filename} openvx)
|
||||
ocv_target_link_libraries(${tgt} PRIVATE ${OPENCV_LINKER_LIBS} ${OPENCV_OPENVX_SAMPLE_REQUIRED_DEPS})
|
||||
endforeach()
|
||||
@@ -1,385 +0,0 @@
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
|
||||
//OpenVX includes
|
||||
#include <VX/vx.h>
|
||||
|
||||
//OpenCV includes
|
||||
#include "opencv2/core.hpp"
|
||||
#include "opencv2/imgproc.hpp"
|
||||
#include "opencv2/imgcodecs.hpp"
|
||||
#include "opencv2/highgui.hpp"
|
||||
|
||||
#ifndef VX_VERSION_1_1
|
||||
const vx_enum VX_IMAGE_FORMAT = VX_IMAGE_ATTRIBUTE_FORMAT;
|
||||
const vx_enum VX_IMAGE_WIDTH = VX_IMAGE_ATTRIBUTE_WIDTH;
|
||||
const vx_enum VX_IMAGE_HEIGHT = VX_IMAGE_ATTRIBUTE_HEIGHT;
|
||||
const vx_enum VX_MEMORY_TYPE_HOST = VX_IMPORT_TYPE_HOST;
|
||||
const vx_enum VX_MEMORY_TYPE_NONE = VX_IMPORT_TYPE_NONE;
|
||||
const vx_enum VX_THRESHOLD_THRESHOLD_VALUE = VX_THRESHOLD_ATTRIBUTE_THRESHOLD_VALUE;
|
||||
const vx_enum VX_THRESHOLD_THRESHOLD_LOWER = VX_THRESHOLD_ATTRIBUTE_THRESHOLD_LOWER;
|
||||
const vx_enum VX_THRESHOLD_THRESHOLD_UPPER = VX_THRESHOLD_ATTRIBUTE_THRESHOLD_UPPER;
|
||||
typedef uintptr_t vx_map_id;
|
||||
#endif
|
||||
|
||||
enum UserMemoryMode
|
||||
{
|
||||
COPY, USER_MEM
|
||||
};
|
||||
|
||||
vx_image convertCvMatToVxImage(vx_context context, cv::Mat image, bool toCopy);
|
||||
cv::Mat copyVxImageToCvMat(vx_image ovxImage);
|
||||
void swapVxImage(vx_image ovxImage);
|
||||
vx_status createProcessingGraph(vx_image inputImage, vx_image outputImage, vx_graph& graph);
|
||||
int ovxDemo(std::string inputPath, UserMemoryMode mode);
|
||||
|
||||
|
||||
vx_image convertCvMatToVxImage(vx_context context, cv::Mat image, bool toCopy)
|
||||
{
|
||||
if (!(!image.empty() && image.dims <= 2 && image.channels() == 1))
|
||||
throw std::runtime_error("Invalid format");
|
||||
|
||||
vx_uint32 width = image.cols;
|
||||
vx_uint32 height = image.rows;
|
||||
|
||||
vx_df_image color;
|
||||
switch (image.depth())
|
||||
{
|
||||
case CV_8U:
|
||||
color = VX_DF_IMAGE_U8;
|
||||
break;
|
||||
case CV_16U:
|
||||
color = VX_DF_IMAGE_U16;
|
||||
break;
|
||||
case CV_16S:
|
||||
color = VX_DF_IMAGE_S16;
|
||||
break;
|
||||
case CV_32S:
|
||||
color = VX_DF_IMAGE_S32;
|
||||
break;
|
||||
default:
|
||||
throw std::runtime_error("Invalid format");
|
||||
break;
|
||||
}
|
||||
|
||||
vx_imagepatch_addressing_t addr;
|
||||
addr.dim_x = width;
|
||||
addr.dim_y = height;
|
||||
addr.stride_x = (vx_uint32)image.elemSize();
|
||||
addr.stride_y = (vx_uint32)image.step.p[0];
|
||||
vx_uint8* ovxData = image.data;
|
||||
|
||||
vx_image ovxImage;
|
||||
if (toCopy)
|
||||
{
|
||||
ovxImage = vxCreateImage(context, width, height, color);
|
||||
if (vxGetStatus((vx_reference)ovxImage) != VX_SUCCESS)
|
||||
throw std::runtime_error("Failed to create image");
|
||||
vx_rectangle_t rect;
|
||||
|
||||
vx_status status = vxGetValidRegionImage(ovxImage, &rect);
|
||||
if (status != VX_SUCCESS)
|
||||
throw std::runtime_error("Failed to get valid region");
|
||||
|
||||
#ifdef VX_VERSION_1_1
|
||||
status = vxCopyImagePatch(ovxImage, &rect, 0, &addr, ovxData, VX_WRITE_ONLY, VX_MEMORY_TYPE_HOST);
|
||||
if (status != VX_SUCCESS)
|
||||
throw std::runtime_error("Failed to copy image patch");
|
||||
#else
|
||||
status = vxAccessImagePatch(ovxImage, &rect, 0, &addr, (void**)&ovxData, VX_WRITE_ONLY);
|
||||
if (status != VX_SUCCESS)
|
||||
throw std::runtime_error("Failed to access image patch");
|
||||
status = vxCommitImagePatch(ovxImage, &rect, 0, &addr, ovxData);
|
||||
if (status != VX_SUCCESS)
|
||||
throw std::runtime_error("Failed to commit image patch");
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
ovxImage = vxCreateImageFromHandle(context, color, &addr, (void**)&ovxData, VX_MEMORY_TYPE_HOST);
|
||||
if (vxGetStatus((vx_reference)ovxImage) != VX_SUCCESS)
|
||||
throw std::runtime_error("Failed to create image from handle");
|
||||
}
|
||||
|
||||
return ovxImage;
|
||||
}
|
||||
|
||||
|
||||
cv::Mat copyVxImageToCvMat(vx_image ovxImage)
|
||||
{
|
||||
vx_status status;
|
||||
vx_df_image df_image = 0;
|
||||
vx_uint32 width, height;
|
||||
status = vxQueryImage(ovxImage, VX_IMAGE_FORMAT, &df_image, sizeof(vx_df_image));
|
||||
if (status != VX_SUCCESS)
|
||||
throw std::runtime_error("Failed to query image");
|
||||
status = vxQueryImage(ovxImage, VX_IMAGE_WIDTH, &width, sizeof(vx_uint32));
|
||||
if (status != VX_SUCCESS)
|
||||
throw std::runtime_error("Failed to query image");
|
||||
status = vxQueryImage(ovxImage, VX_IMAGE_HEIGHT, &height, sizeof(vx_uint32));
|
||||
if (status != VX_SUCCESS)
|
||||
throw std::runtime_error("Failed to query image");
|
||||
|
||||
if (!(width > 0 && height > 0)) throw std::runtime_error("Invalid format");
|
||||
|
||||
int depth;
|
||||
switch (df_image)
|
||||
{
|
||||
case VX_DF_IMAGE_U8:
|
||||
depth = CV_8U;
|
||||
break;
|
||||
case VX_DF_IMAGE_U16:
|
||||
depth = CV_16U;
|
||||
break;
|
||||
case VX_DF_IMAGE_S16:
|
||||
depth = CV_16S;
|
||||
break;
|
||||
case VX_DF_IMAGE_S32:
|
||||
depth = CV_32S;
|
||||
break;
|
||||
default:
|
||||
throw std::runtime_error("Invalid format");
|
||||
break;
|
||||
}
|
||||
|
||||
cv::Mat image(height, width, CV_MAKE_TYPE(depth, 1));
|
||||
|
||||
vx_rectangle_t rect;
|
||||
rect.start_x = rect.start_y = 0;
|
||||
rect.end_x = width; rect.end_y = height;
|
||||
|
||||
vx_imagepatch_addressing_t addr;
|
||||
addr.dim_x = width;
|
||||
addr.dim_y = height;
|
||||
addr.stride_x = (vx_uint32)image.elemSize();
|
||||
addr.stride_y = (vx_uint32)image.step.p[0];
|
||||
vx_uint8* matData = image.data;
|
||||
|
||||
#ifdef VX_VERSION_1_1
|
||||
status = vxCopyImagePatch(ovxImage, &rect, 0, &addr, matData, VX_READ_ONLY, VX_MEMORY_TYPE_HOST);
|
||||
if (status != VX_SUCCESS)
|
||||
throw std::runtime_error("Failed to copy image patch");
|
||||
#else
|
||||
status = vxAccessImagePatch(ovxImage, &rect, 0, &addr, (void**)&matData, VX_READ_ONLY);
|
||||
if (status != VX_SUCCESS)
|
||||
throw std::runtime_error("Failed to access image patch");
|
||||
status = vxCommitImagePatch(ovxImage, &rect, 0, &addr, matData);
|
||||
if (status != VX_SUCCESS)
|
||||
throw std::runtime_error("Failed to commit image patch");
|
||||
#endif
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
|
||||
void swapVxImage(vx_image ovxImage)
|
||||
{
|
||||
#ifdef VX_VERSION_1_1
|
||||
vx_status status;
|
||||
vx_memory_type_e memType;
|
||||
status = vxQueryImage(ovxImage, VX_IMAGE_MEMORY_TYPE, &memType, sizeof(vx_memory_type_e));
|
||||
if (status != VX_SUCCESS)
|
||||
throw std::runtime_error("Failed to query image");
|
||||
if (memType == VX_MEMORY_TYPE_NONE)
|
||||
{
|
||||
//was created by copying user data
|
||||
throw std::runtime_error("Image wasn't created from user handle");
|
||||
}
|
||||
else
|
||||
{
|
||||
//was created from user handle
|
||||
status = vxSwapImageHandle(ovxImage, NULL, NULL, 0);
|
||||
if (status != VX_SUCCESS)
|
||||
throw std::runtime_error("Failed to swap image handle");
|
||||
}
|
||||
#else
|
||||
//not supported until OpenVX 1.1
|
||||
(void) ovxImage;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
vx_status createProcessingGraph(vx_image inputImage, vx_image outputImage, vx_graph& graph)
|
||||
{
|
||||
vx_status status;
|
||||
vx_context context = vxGetContext((vx_reference)inputImage);
|
||||
status = vxGetStatus((vx_reference)context);
|
||||
if(status != VX_SUCCESS) return status;
|
||||
|
||||
graph = vxCreateGraph(context);
|
||||
status = vxGetStatus((vx_reference)graph);
|
||||
if (status != VX_SUCCESS) return status;
|
||||
|
||||
vx_uint32 width, height;
|
||||
status = vxQueryImage(inputImage, VX_IMAGE_WIDTH, &width, sizeof(vx_uint32));
|
||||
if (status != VX_SUCCESS) return status;
|
||||
status = vxQueryImage(inputImage, VX_IMAGE_HEIGHT, &height, sizeof(vx_uint32));
|
||||
if (status != VX_SUCCESS) return status;
|
||||
|
||||
// Intermediate images
|
||||
vx_image
|
||||
smoothed = vxCreateVirtualImage(graph, 0, 0, VX_DF_IMAGE_VIRT),
|
||||
cannied = vxCreateVirtualImage(graph, 0, 0, VX_DF_IMAGE_VIRT),
|
||||
halfImg = vxCreateImage(context, width, height, VX_DF_IMAGE_U8),
|
||||
halfCanny = vxCreateImage(context, width, height, VX_DF_IMAGE_U8);
|
||||
|
||||
vx_image virtualImages[] = {smoothed, cannied, halfImg, halfCanny};
|
||||
for(size_t i = 0; i < sizeof(virtualImages)/sizeof(vx_image); i++)
|
||||
{
|
||||
status = vxGetStatus((vx_reference)virtualImages[i]);
|
||||
if (status != VX_SUCCESS) return status;
|
||||
}
|
||||
|
||||
// Constants
|
||||
vx_uint32 threshValue = 50;
|
||||
vx_threshold thresh = vxCreateThreshold(context, VX_THRESHOLD_TYPE_BINARY, VX_TYPE_UINT8);
|
||||
vxSetThresholdAttribute(thresh, VX_THRESHOLD_THRESHOLD_VALUE,
|
||||
&threshValue, sizeof(threshValue));
|
||||
|
||||
vx_uint32 threshCannyMin = 127;
|
||||
vx_uint32 threshCannyMax = 192;
|
||||
vx_threshold threshCanny = vxCreateThreshold(context, VX_THRESHOLD_TYPE_RANGE, VX_TYPE_UINT8);
|
||||
vxSetThresholdAttribute(threshCanny, VX_THRESHOLD_THRESHOLD_LOWER, &threshCannyMin,
|
||||
sizeof(threshCannyMin));
|
||||
vxSetThresholdAttribute(threshCanny, VX_THRESHOLD_THRESHOLD_UPPER, &threshCannyMax,
|
||||
sizeof(threshCannyMax));
|
||||
vx_float32 alphaValue = 0.5;
|
||||
vx_scalar alpha = vxCreateScalar(context, VX_TYPE_FLOAT32, &alphaValue);
|
||||
|
||||
// Sequence of meaningless image operations
|
||||
vx_node nodes[] = {
|
||||
vxGaussian3x3Node(graph, inputImage, smoothed),
|
||||
vxCannyEdgeDetectorNode(graph, smoothed, threshCanny, 3, VX_NORM_L2, cannied),
|
||||
vxAccumulateWeightedImageNode(graph, inputImage, alpha, halfImg),
|
||||
vxAccumulateWeightedImageNode(graph, cannied, alpha, halfCanny),
|
||||
vxAddNode(graph, halfImg, halfCanny, VX_CONVERT_POLICY_SATURATE, outputImage)
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < sizeof(nodes) / sizeof(vx_node); i++)
|
||||
{
|
||||
status = vxGetStatus((vx_reference)nodes[i]);
|
||||
if (status != VX_SUCCESS) return status;
|
||||
}
|
||||
|
||||
status = vxVerifyGraph(graph);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
int ovxDemo(std::string inputPath, UserMemoryMode mode)
|
||||
{
|
||||
cv::Mat image = cv::imread(inputPath, cv::IMREAD_GRAYSCALE);
|
||||
if (image.empty()) return -1;
|
||||
|
||||
//check image format
|
||||
if (image.depth() != CV_8U || image.channels() != 1) return -1;
|
||||
|
||||
vx_status status;
|
||||
vx_context context = vxCreateContext();
|
||||
status = vxGetStatus((vx_reference)context);
|
||||
if (status != VX_SUCCESS) return status;
|
||||
|
||||
//put user data from cv::Mat to vx_image
|
||||
vx_image ovxImage;
|
||||
ovxImage = convertCvMatToVxImage(context, image, mode == COPY);
|
||||
|
||||
vx_uint32 width = image.cols, height = image.rows;
|
||||
|
||||
vx_image ovxResult;
|
||||
cv::Mat output;
|
||||
if (mode == COPY)
|
||||
{
|
||||
//we will copy data from vx_image to cv::Mat
|
||||
ovxResult = vxCreateImage(context, width, height, VX_DF_IMAGE_U8);
|
||||
if (vxGetStatus((vx_reference)ovxResult) != VX_SUCCESS)
|
||||
throw std::runtime_error("Failed to create image");
|
||||
}
|
||||
else
|
||||
{
|
||||
//create vx_image based on user data, no copying required
|
||||
output = cv::Mat(height, width, CV_8U, cv::Scalar(0));
|
||||
ovxResult = convertCvMatToVxImage(context, output, false);
|
||||
}
|
||||
|
||||
vx_graph graph;
|
||||
status = createProcessingGraph(ovxImage, ovxResult, graph);
|
||||
if (status != VX_SUCCESS) return status;
|
||||
|
||||
// Graph execution
|
||||
status = vxProcessGraph(graph);
|
||||
if (status != VX_SUCCESS) return status;
|
||||
|
||||
//getting resulting image in cv::Mat
|
||||
if (mode == COPY)
|
||||
{
|
||||
output = copyVxImageToCvMat(ovxResult);
|
||||
}
|
||||
else
|
||||
{
|
||||
//we should take user memory back from vx_image before using it (even before reading)
|
||||
swapVxImage(ovxResult);
|
||||
}
|
||||
|
||||
//here output goes
|
||||
cv::imshow("processing result", output);
|
||||
cv::waitKey(0);
|
||||
|
||||
//we need to take user memory back before releasing the image
|
||||
if (mode == USER_MEM)
|
||||
swapVxImage(ovxImage);
|
||||
|
||||
cv::destroyAllWindows();
|
||||
|
||||
status = vxReleaseContext(&context);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
const std::string keys =
|
||||
"{help h usage ? | | }"
|
||||
"{image | <none> | image to be processed}"
|
||||
"{mode | copy | user memory interaction mode: \n"
|
||||
"copy: create VX images and copy data to/from them\n"
|
||||
"user_mem: use handles to user-allocated memory}"
|
||||
;
|
||||
|
||||
cv::CommandLineParser parser(argc, argv, keys);
|
||||
parser.about("OpenVX interoperability sample demonstrating standard OpenVX API."
|
||||
"The application loads an image, processes it with OpenVX graph and outputs result in a window");
|
||||
if (parser.has("help"))
|
||||
{
|
||||
parser.printMessage();
|
||||
return 0;
|
||||
}
|
||||
std::string imgPath = parser.get<std::string>("image");
|
||||
std::string modeString = parser.get<std::string>("mode");
|
||||
UserMemoryMode mode;
|
||||
if(modeString == "copy")
|
||||
{
|
||||
mode = COPY;
|
||||
}
|
||||
else if(modeString == "user_mem")
|
||||
{
|
||||
mode = USER_MEM;
|
||||
}
|
||||
else if(modeString == "map")
|
||||
{
|
||||
std::cerr << modeString << " is not implemented in this sample" << std::endl;
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << modeString << ": unknown memory mode" << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!parser.check())
|
||||
{
|
||||
parser.printErrors();
|
||||
return -1;
|
||||
}
|
||||
|
||||
return ovxDemo(imgPath, mode);
|
||||
}
|
||||
@@ -1,214 +0,0 @@
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
|
||||
//wrappers
|
||||
#include "ivx.hpp"
|
||||
|
||||
//OpenCV includes
|
||||
#include "opencv2/core.hpp"
|
||||
#include "opencv2/imgproc.hpp"
|
||||
#include "opencv2/imgcodecs.hpp"
|
||||
#include "opencv2/highgui.hpp"
|
||||
|
||||
enum UserMemoryMode
|
||||
{
|
||||
COPY, USER_MEM, MAP
|
||||
};
|
||||
|
||||
ivx::Graph createProcessingGraph(ivx::Image& inputImage, ivx::Image& outputImage);
|
||||
int ovxDemo(std::string inputPath, UserMemoryMode mode);
|
||||
|
||||
|
||||
ivx::Graph createProcessingGraph(ivx::Image& inputImage, ivx::Image& outputImage)
|
||||
{
|
||||
using namespace ivx;
|
||||
|
||||
Context context = inputImage.get<Context>();
|
||||
Graph graph = Graph::create(context);
|
||||
|
||||
vx_uint32 width = inputImage.width();
|
||||
vx_uint32 height = inputImage.height();
|
||||
|
||||
// Intermediate images
|
||||
Image
|
||||
smoothed = Image::createVirtual(graph),
|
||||
cannied = Image::createVirtual(graph),
|
||||
halfImg = Image::create(context, width, height, VX_DF_IMAGE_U8),
|
||||
halfCanny = Image::create(context, width, height, VX_DF_IMAGE_U8);
|
||||
|
||||
// Constants
|
||||
vx_uint32 threshCannyMin = 127;
|
||||
vx_uint32 threshCannyMax = 192;
|
||||
Threshold threshCanny = Threshold::createRange(context, VX_TYPE_UINT8, threshCannyMin, threshCannyMax);
|
||||
|
||||
ivx::Scalar alpha = ivx::Scalar::create<VX_TYPE_FLOAT32>(context, 0.5);
|
||||
|
||||
// Sequence of some image operations
|
||||
// Node can also be added in function-like style
|
||||
nodes::gaussian3x3(graph, inputImage, smoothed);
|
||||
Node::create(graph, VX_KERNEL_CANNY_EDGE_DETECTOR, smoothed, threshCanny,
|
||||
ivx::Scalar::create<VX_TYPE_INT32>(context, 3),
|
||||
ivx::Scalar::create<VX_TYPE_ENUM>(context, VX_NORM_L2), cannied);
|
||||
Node::create(graph, VX_KERNEL_ACCUMULATE_WEIGHTED, inputImage, alpha, halfImg);
|
||||
Node::create(graph, VX_KERNEL_ACCUMULATE_WEIGHTED, cannied, alpha, halfCanny);
|
||||
Node::create(graph, VX_KERNEL_ADD, halfImg, halfCanny,
|
||||
ivx::Scalar::create<VX_TYPE_ENUM>(context, VX_CONVERT_POLICY_SATURATE), outputImage);
|
||||
|
||||
graph.verify();
|
||||
|
||||
return graph;
|
||||
}
|
||||
|
||||
|
||||
int ovxDemo(std::string inputPath, UserMemoryMode mode)
|
||||
{
|
||||
using namespace cv;
|
||||
using namespace ivx;
|
||||
|
||||
Mat image = imread(inputPath, IMREAD_GRAYSCALE);
|
||||
if (image.empty()) return -1;
|
||||
|
||||
//check image format
|
||||
if (image.depth() != CV_8U || image.channels() != 1) return -1;
|
||||
|
||||
try
|
||||
{
|
||||
Context context = Context::create();
|
||||
//put user data from cv::Mat to vx_image
|
||||
vx_df_image color = Image::matTypeToFormat(image.type());
|
||||
vx_uint32 width = image.cols, height = image.rows;
|
||||
Image ivxImage;
|
||||
if (mode == COPY)
|
||||
{
|
||||
ivxImage = Image::create(context, width, height, color);
|
||||
ivxImage.copyFrom(0, image);
|
||||
}
|
||||
else
|
||||
{
|
||||
ivxImage = Image::createFromHandle(context, color, Image::createAddressing(image), image.data);
|
||||
}
|
||||
|
||||
Image ivxResult;
|
||||
Image::Patch resultPatch;
|
||||
Mat output;
|
||||
if (mode == COPY || mode == MAP)
|
||||
{
|
||||
//we will copy or map data from vx_image to cv::Mat
|
||||
ivxResult = ivx::Image::create(context, width, height, VX_DF_IMAGE_U8);
|
||||
}
|
||||
else // if (mode == MAP_TO_VX)
|
||||
{
|
||||
//create vx_image based on user data, no copying required
|
||||
output = cv::Mat(height, width, CV_8U, cv::Scalar(0));
|
||||
ivxResult = Image::createFromHandle(context, Image::matTypeToFormat(CV_8U),
|
||||
Image::createAddressing(output), output.data);
|
||||
}
|
||||
|
||||
Graph graph = createProcessingGraph(ivxImage, ivxResult);
|
||||
|
||||
// Graph execution
|
||||
graph.process();
|
||||
|
||||
//getting resulting image in cv::Mat
|
||||
if (mode == COPY)
|
||||
{
|
||||
ivxResult.copyTo(0, output);
|
||||
}
|
||||
else if (mode == MAP)
|
||||
{
|
||||
//create cv::Mat based on vx_image mapped data
|
||||
resultPatch.map(ivxResult, 0, ivxResult.getValidRegion());
|
||||
//generally this is very bad idea!
|
||||
//but in our case unmap() won't happen until output is in use
|
||||
output = resultPatch.getMat();
|
||||
}
|
||||
else // if (mode == MAP_TO_VX)
|
||||
{
|
||||
#ifdef VX_VERSION_1_1
|
||||
//we should take user memory back from vx_image before using it (even before reading)
|
||||
ivxResult.swapHandle();
|
||||
#endif
|
||||
}
|
||||
|
||||
//here output goes
|
||||
cv::imshow("processing result", output);
|
||||
cv::waitKey(0);
|
||||
|
||||
cv::destroyAllWindows();
|
||||
|
||||
#ifdef VX_VERSION_1_1
|
||||
if (mode != COPY)
|
||||
{
|
||||
//we should take user memory back before release
|
||||
//(it's not done automatically according to standard)
|
||||
ivxImage.swapHandle();
|
||||
if (mode == USER_MEM) ivxResult.swapHandle();
|
||||
}
|
||||
#endif
|
||||
|
||||
//the line is unnecessary since unmapping is done on destruction of patch
|
||||
//resultPatch.unmap();
|
||||
}
|
||||
catch (const ivx::RuntimeError& e)
|
||||
{
|
||||
std::cerr << "Error: code = " << e.status() << ", message = " << e.what() << std::endl;
|
||||
return e.status();
|
||||
}
|
||||
catch (const ivx::WrapperError& e)
|
||||
{
|
||||
std::cerr << "Error: message = " << e.what() << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
const std::string keys =
|
||||
"{help h usage ? | | }"
|
||||
"{image | <none> | image to be processed}"
|
||||
"{mode | copy | user memory interaction mode: \n"
|
||||
"copy: create VX images and copy data to/from them\n"
|
||||
"user_mem: use handles to user-allocated memory\n"
|
||||
"map: map resulting VX image to user memory}"
|
||||
;
|
||||
|
||||
cv::CommandLineParser parser(argc, argv, keys);
|
||||
parser.about("OpenVX interoperability sample demonstrating OpenVX wrappers usage."
|
||||
"The application loads an image, processes it with OpenVX graph and outputs result in a window");
|
||||
if (parser.has("help"))
|
||||
{
|
||||
parser.printMessage();
|
||||
return 0;
|
||||
}
|
||||
std::string imgPath = parser.get<std::string>("image");
|
||||
std::string modeString = parser.get<std::string>("mode");
|
||||
UserMemoryMode mode;
|
||||
if(modeString == "copy")
|
||||
{
|
||||
mode = COPY;
|
||||
}
|
||||
else if(modeString == "user_mem")
|
||||
{
|
||||
mode = USER_MEM;
|
||||
}
|
||||
else if(modeString == "map")
|
||||
{
|
||||
mode = MAP;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << modeString << ": unknown memory mode" << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!parser.check())
|
||||
{
|
||||
parser.printErrors();
|
||||
return -1;
|
||||
}
|
||||
|
||||
return ovxDemo(imgPath, mode);
|
||||
}
|
||||
@@ -1,250 +0,0 @@
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
|
||||
//wrappers
|
||||
#include "ivx.hpp"
|
||||
|
||||
//OpenCV includes
|
||||
#include "opencv2/core.hpp"
|
||||
#include "opencv2/imgproc.hpp"
|
||||
#include "opencv2/imgcodecs.hpp"
|
||||
#include "opencv2/highgui.hpp"
|
||||
|
||||
enum UserMemoryMode
|
||||
{
|
||||
COPY, USER_MEM, MAP
|
||||
};
|
||||
|
||||
ivx::Graph createProcessingGraph(ivx::Image& inputImage, ivx::Image& outputImage);
|
||||
int ovxDemo(std::string inputPath, UserMemoryMode mode);
|
||||
|
||||
|
||||
ivx::Graph createProcessingGraph(ivx::Image& inputImage, ivx::Image& outputImage)
|
||||
{
|
||||
using namespace ivx;
|
||||
|
||||
Context context = inputImage.get<Context>();
|
||||
Graph graph = Graph::create(context);
|
||||
|
||||
vx_uint32 width = inputImage.width();
|
||||
vx_uint32 height = inputImage.height();
|
||||
|
||||
// Intermediate images
|
||||
Image
|
||||
yuv = Image::createVirtual(graph, 0, 0, VX_DF_IMAGE_YUV4),
|
||||
gray = Image::createVirtual(graph),
|
||||
smoothed = Image::createVirtual(graph),
|
||||
cannied = Image::createVirtual(graph),
|
||||
halfImg = Image::create(context, width, height, VX_DF_IMAGE_U8),
|
||||
halfCanny = Image::create(context, width, height, VX_DF_IMAGE_U8);
|
||||
|
||||
// Constants
|
||||
vx_uint32 threshCannyMin = 127;
|
||||
vx_uint32 threshCannyMax = 192;
|
||||
Threshold threshCanny = Threshold::createRange(context, VX_TYPE_UINT8, threshCannyMin, threshCannyMax);
|
||||
|
||||
ivx::Scalar alpha = ivx::Scalar::create<VX_TYPE_FLOAT32>(context, 0.5);
|
||||
|
||||
// Sequence of some image operations
|
||||
Node::create(graph, VX_KERNEL_COLOR_CONVERT, inputImage, yuv);
|
||||
Node::create(graph, VX_KERNEL_CHANNEL_EXTRACT, yuv,
|
||||
ivx::Scalar::create<VX_TYPE_ENUM>(context, VX_CHANNEL_Y), gray);
|
||||
//node can also be added in function-like style
|
||||
nodes::gaussian3x3(graph, gray, smoothed);
|
||||
Node::create(graph, VX_KERNEL_CANNY_EDGE_DETECTOR, smoothed, threshCanny,
|
||||
ivx::Scalar::create<VX_TYPE_INT32>(context, 3),
|
||||
ivx::Scalar::create<VX_TYPE_ENUM>(context, VX_NORM_L2), cannied);
|
||||
Node::create(graph, VX_KERNEL_ACCUMULATE_WEIGHTED, gray, alpha, halfImg);
|
||||
Node::create(graph, VX_KERNEL_ACCUMULATE_WEIGHTED, cannied, alpha, halfCanny);
|
||||
Node::create(graph, VX_KERNEL_ADD, halfImg, halfCanny,
|
||||
ivx::Scalar::create<VX_TYPE_ENUM>(context, VX_CONVERT_POLICY_SATURATE), outputImage);
|
||||
|
||||
graph.verify();
|
||||
|
||||
return graph;
|
||||
}
|
||||
|
||||
|
||||
int ovxDemo(std::string inputPath, UserMemoryMode mode)
|
||||
{
|
||||
using namespace cv;
|
||||
using namespace ivx;
|
||||
|
||||
Mat frame;
|
||||
VideoCapture vc(inputPath);
|
||||
if (!vc.isOpened())
|
||||
return -1;
|
||||
|
||||
vc >> frame;
|
||||
if (frame.empty()) return -1;
|
||||
|
||||
//check frame format
|
||||
if (frame.type() != CV_8UC3) return -1;
|
||||
|
||||
try
|
||||
{
|
||||
Context context = Context::create();
|
||||
//put user data from cv::Mat to vx_image
|
||||
vx_df_image color = Image::matTypeToFormat(frame.type());
|
||||
vx_uint32 width = frame.cols, height = frame.rows;
|
||||
Image ivxImage;
|
||||
if (mode == COPY)
|
||||
{
|
||||
ivxImage = Image::create(context, width, height, color);
|
||||
}
|
||||
else
|
||||
{
|
||||
ivxImage = Image::createFromHandle(context, color, Image::createAddressing(frame), frame.data);
|
||||
}
|
||||
|
||||
Image ivxResult;
|
||||
|
||||
Mat output;
|
||||
if (mode == COPY || mode == MAP)
|
||||
{
|
||||
//we will copy or map data from vx_image to cv::Mat
|
||||
ivxResult = ivx::Image::create(context, width, height, VX_DF_IMAGE_U8);
|
||||
}
|
||||
else // if (mode == MAP_TO_VX)
|
||||
{
|
||||
//create vx_image based on user data, no copying required
|
||||
output = cv::Mat(height, width, CV_8U, cv::Scalar(0));
|
||||
ivxResult = Image::createFromHandle(context, Image::matTypeToFormat(CV_8U),
|
||||
Image::createAddressing(output), output.data);
|
||||
}
|
||||
|
||||
Graph graph = createProcessingGraph(ivxImage, ivxResult);
|
||||
|
||||
bool stop = false;
|
||||
while (!stop)
|
||||
{
|
||||
if (mode == COPY) ivxImage.copyFrom(0, frame);
|
||||
|
||||
// Graph execution
|
||||
graph.process();
|
||||
|
||||
//getting resulting image in cv::Mat
|
||||
Image::Patch resultPatch;
|
||||
std::vector<void*> ptrs;
|
||||
std::vector<void*> prevPtrs(ivxResult.planes());
|
||||
if (mode == COPY)
|
||||
{
|
||||
ivxResult.copyTo(0, output);
|
||||
}
|
||||
else if (mode == MAP)
|
||||
{
|
||||
//create cv::Mat based on vx_image mapped data
|
||||
resultPatch.map(ivxResult, 0, ivxResult.getValidRegion(), VX_READ_AND_WRITE);
|
||||
//generally this is very bad idea!
|
||||
//but in our case unmap() won't happen until output is in use
|
||||
output = resultPatch.getMat();
|
||||
}
|
||||
else // if(mode == MAP_TO_VX)
|
||||
{
|
||||
#ifdef VX_VERSION_1_1
|
||||
//we should take user memory back from vx_image before using it (even before reading)
|
||||
ivxResult.swapHandle(ptrs, prevPtrs);
|
||||
#endif
|
||||
}
|
||||
|
||||
//here output goes
|
||||
imshow("press q to quit", output);
|
||||
if ((char)waitKey(1) == 'q') stop = true;
|
||||
|
||||
#ifdef VX_VERSION_1_1
|
||||
//restore handle
|
||||
if (mode == USER_MEM)
|
||||
{
|
||||
ivxResult.swapHandle(prevPtrs, ptrs);
|
||||
}
|
||||
#endif
|
||||
|
||||
//this line is unnecessary since unmapping is done on destruction of patch
|
||||
//resultPatch.unmap();
|
||||
|
||||
//grab next frame
|
||||
Mat temp = frame;
|
||||
vc >> frame;
|
||||
if (frame.empty()) stop = true;
|
||||
if (mode != COPY && frame.data != temp.data)
|
||||
{
|
||||
//frame was reallocated, pointer to data changed
|
||||
frame.copyTo(temp);
|
||||
}
|
||||
}
|
||||
|
||||
destroyAllWindows();
|
||||
|
||||
#ifdef VX_VERSION_1_1
|
||||
if (mode != COPY)
|
||||
{
|
||||
//we should take user memory back before release
|
||||
//(it's not done automatically according to standard)
|
||||
ivxImage.swapHandle();
|
||||
if (mode == USER_MEM) ivxResult.swapHandle();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
catch (const ivx::RuntimeError& e)
|
||||
{
|
||||
std::cerr << "Error: code = " << e.status() << ", message = " << e.what() << std::endl;
|
||||
return e.status();
|
||||
}
|
||||
catch (const ivx::WrapperError& e)
|
||||
{
|
||||
std::cerr << "Error: message = " << e.what() << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
const std::string keys =
|
||||
"{help h usage ? | | }"
|
||||
"{video | <none> | video file to be processed}"
|
||||
"{mode | copy | user memory interaction mode: \n"
|
||||
"copy: create VX images and copy data to/from them\n"
|
||||
"user_mem: use handles to user-allocated memory\n"
|
||||
"map: map resulting VX image to user memory}"
|
||||
;
|
||||
|
||||
cv::CommandLineParser parser(argc, argv, keys);
|
||||
parser.about("OpenVX interoperability sample demonstrating OpenVX wrappers usage."
|
||||
"The application opens a video and processes it with OpenVX graph while outputting result in a window");
|
||||
if (parser.has("help"))
|
||||
{
|
||||
parser.printMessage();
|
||||
return 0;
|
||||
}
|
||||
std::string videoPath = parser.get<std::string>("video");
|
||||
std::string modeString = parser.get<std::string>("mode");
|
||||
UserMemoryMode mode;
|
||||
if(modeString == "copy")
|
||||
{
|
||||
mode = COPY;
|
||||
}
|
||||
else if(modeString == "user_mem")
|
||||
{
|
||||
mode = USER_MEM;
|
||||
}
|
||||
else if(modeString == "map")
|
||||
{
|
||||
mode = MAP;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << modeString << ": unknown memory mode" << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!parser.check())
|
||||
{
|
||||
parser.printErrors();
|
||||
return -1;
|
||||
}
|
||||
|
||||
return ovxDemo(videoPath, mode);
|
||||
}
|
||||
Reference in New Issue
Block a user