mirror of
https://github.com/opencv/opencv.git
synced 2025-08-06 14:36:36 +08:00
Merge pull request #7163 from savuor:openvx_sample
This commit is contained in:
commit
8151be9abc
106
3rdparty/openvx/include/ivx.hpp
vendored
106
3rdparty/openvx/include/ivx.hpp
vendored
@ -58,6 +58,11 @@ Details: TBD
|
||||
|
||||
#ifndef IVX_USE_CXX98
|
||||
#include <type_traits>
|
||||
namespace ivx
|
||||
{
|
||||
using std::is_same;
|
||||
using std::is_pointer;
|
||||
}
|
||||
#else
|
||||
namespace ivx
|
||||
{
|
||||
@ -76,6 +81,21 @@ Details: TBD
|
||||
#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
|
||||
{
|
||||
|
||||
@ -84,8 +104,8 @@ class RuntimeError : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
/// Constructor
|
||||
explicit RuntimeError(vx_status status, const std::string& msg = "")
|
||||
: runtime_error(msg), _status(status)
|
||||
explicit RuntimeError(vx_status st, const std::string& msg = "")
|
||||
: runtime_error(msg), _status(st)
|
||||
{}
|
||||
|
||||
/// OpenVX error code
|
||||
@ -137,7 +157,7 @@ template <vx_enum E> using EnumToType_t = typename EnumToType<E>::type;
|
||||
#endif
|
||||
|
||||
/// Gets size in bytes for the provided OpenVX type enum
|
||||
vx_size enumToTypeSize(vx_enum type)
|
||||
inline vx_size enumToTypeSize(vx_enum type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
@ -268,12 +288,12 @@ template <> struct RefTypeTraits <vx_threshold>
|
||||
/// Casting to vx_reference with compile-time check
|
||||
|
||||
// takes 'vx_reference' itself and RefWrapper<T> via 'operator vx_reference()'
|
||||
vx_reference castToReference(vx_reference ref)
|
||||
inline vx_reference castToReference(vx_reference ref)
|
||||
{ return ref; }
|
||||
|
||||
// takes vx_reference extensions that have RefTypeTraits<T> specializations
|
||||
template<typename T>
|
||||
vx_reference castToReference(const T& ref, typename RefTypeTraits<T>::vxType dummy = 0)
|
||||
inline vx_reference castToReference(const T& ref, typename RefTypeTraits<T>::vxType dummy = 0)
|
||||
{ (void)dummy; return (vx_reference)ref; }
|
||||
|
||||
#else
|
||||
@ -297,7 +317,7 @@ struct is_ref<T, decltype(RefTypeTraits<T>::vxTypeEnum, void())> : std::true_typ
|
||||
/// Casting to vx_reference with compile-time check
|
||||
|
||||
template<typename T>
|
||||
vx_reference castToReference(const T& obj)
|
||||
inline vx_reference castToReference(const T& obj)
|
||||
{
|
||||
static_assert(is_ref<T>::value, "unsupported conversion");
|
||||
return (vx_reference) obj;
|
||||
@ -405,7 +425,6 @@ public:
|
||||
{ return ref != 0; }
|
||||
#endif
|
||||
|
||||
#ifdef IVX_USE_CXX98
|
||||
/// Getting a context that is kept in each OpenVX 'object' (call get<Context>())
|
||||
template<typename C>
|
||||
C get() const
|
||||
@ -415,7 +434,8 @@ public:
|
||||
// vxGetContext doesn't increment ref count, let do it in wrapper c-tor
|
||||
return C(c, true);
|
||||
}
|
||||
#else
|
||||
|
||||
#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
|
||||
@ -527,7 +547,6 @@ public:
|
||||
operator vx_reference() const
|
||||
{ return castToReference(ref); }
|
||||
|
||||
#ifdef IVX_USE_CXX98
|
||||
/// Getting a context that is kept in each OpenVX 'object' (call get<Context>())
|
||||
template<typename C>
|
||||
C get() const
|
||||
@ -537,7 +556,8 @@ public:
|
||||
// vxGetContext doesn't increment ref count, let do it in wrapper c-tor
|
||||
return C(c, true);
|
||||
}
|
||||
#else
|
||||
|
||||
#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
|
||||
@ -866,6 +886,16 @@ public:
|
||||
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
|
||||
|
||||
/// Planes number for the specified image format (fourcc)
|
||||
/// \return 0 for unknown formats
|
||||
static vx_size planes(vx_df_image format)
|
||||
@ -949,6 +979,13 @@ public:
|
||||
#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
|
||||
@ -968,6 +1005,17 @@ public:
|
||||
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) ); }
|
||||
@ -1129,12 +1177,12 @@ static const vx_enum
|
||||
/// 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 memType = VX_MEMORY_TYPE_HOST )
|
||||
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, memType));
|
||||
IVX_CHECK_STATUS(vxCopyImagePatch(ref, &rect, planeIdx, &addr, (void*)data, usage, memoryType));
|
||||
#else
|
||||
(void)memType;
|
||||
(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));
|
||||
@ -1246,6 +1294,14 @@ static const vx_enum
|
||||
//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());
|
||||
}
|
||||
|
||||
/*
|
||||
static Image createFromHandle(vx_context context, const cv::Mat& mat)
|
||||
{ throw WrapperError(std::string(__func__)+"(): NYI"); }
|
||||
|
||||
cv::Mat swapHandle(const cv::Mat& newMat)
|
||||
{ throw WrapperError(std::string(__func__)+"(): NYI"); }
|
||||
*/
|
||||
#endif //IVX_USE_OPENCV
|
||||
|
||||
struct Patch;
|
||||
@ -1273,16 +1329,16 @@ public:
|
||||
{ return _mapId; }
|
||||
#else
|
||||
/// reference to vx_rectangle_t for the current mapping
|
||||
const vx_rectangle_t& rect() const
|
||||
const vx_rectangle_t& rectangle() const
|
||||
{ return _rect; }
|
||||
|
||||
/// Image plane index for the current mapping
|
||||
vx_uint32 planeIdx() const
|
||||
vx_uint32 planeIndex() const
|
||||
{ return _planeIdx; }
|
||||
#endif // VX_VERSION_1_1
|
||||
|
||||
/// vx_image for the current mapping
|
||||
vx_image img() const
|
||||
vx_image image() const
|
||||
{ return _img; }
|
||||
|
||||
/// where this patch is mapped
|
||||
@ -1352,6 +1408,7 @@ public:
|
||||
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
|
||||
@ -1517,15 +1574,15 @@ static const vx_enum
|
||||
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, &val1, sizeof(val1)) );
|
||||
IVX_CHECK_STATUS( vxSetThresholdAttribute(thr.ref, VX_THRESHOLD_THRESHOLD_UPPER, &val2, sizeof(val2)) );
|
||||
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& value) const
|
||||
{ IVX_CHECK_STATUS( vxQueryThreshold(ref, att, &value, sizeof(value)) ); }
|
||||
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
|
||||
@ -1611,4 +1668,13 @@ Node gaussian3x3(vx_graph graph, vx_image inImg, vx_image outImg)
|
||||
|
||||
} // 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
|
||||
|
@ -22,6 +22,10 @@ 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 OR HAVE_VA_INTEL))
|
||||
add_subdirectory(va_intel)
|
||||
endif()
|
||||
|
37
samples/openvx/CMakeLists.txt
Normal file
37
samples/openvx/CMakeLists.txt
Normal file
@ -0,0 +1,37 @@
|
||||
cmake_minimum_required(VERSION 2.8.9)
|
||||
|
||||
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(BUILD_EXAMPLES AND OCV_DEPENDENCIES_FOUND)
|
||||
set(group "openvx")
|
||||
set(name_wrapped "interop")
|
||||
set(name_orig "interop_orig")
|
||||
set(name_video "interop_video")
|
||||
|
||||
project("${group}_sample")
|
||||
|
||||
ocv_include_modules_recurse(${OPENCV_OPENVX_SAMPLE_REQUIRED_DEPS})
|
||||
|
||||
add_definitions(-DIVX_USE_OPENCV)
|
||||
add_definitions(-DIVX_HIDE_INFO_WARNINGS)
|
||||
|
||||
file(GLOB srcs_wrapped wrappers.cpp *.hpp)
|
||||
file(GLOB srcs_orig no_wrappers.cpp *.hpp)
|
||||
file(GLOB srcs_video wrappers_video.cpp *.hpp)
|
||||
|
||||
MACRO(OPENVX_DEFINE_SAMPLE name srcs)
|
||||
set(target "example_${group}_${name}")
|
||||
add_executable(${target} ${srcs})
|
||||
ocv_target_link_libraries(${target} ${OPENCV_LINKER_LIBS} ${OPENCV_OPENVX_SAMPLE_REQUIRED_DEPS} ${OPENVX_LIBRARIES})
|
||||
if(ENABLE_SOLUTION_FOLDERS)
|
||||
set_target_properties(${target} PROPERTIES FOLDER "samples//${group}")
|
||||
endif()
|
||||
ENDMACRO()
|
||||
|
||||
OPENVX_DEFINE_SAMPLE(${name_wrapped} ${srcs_wrapped})
|
||||
OPENVX_DEFINE_SAMPLE(${name_orig} ${srcs_orig})
|
||||
OPENVX_DEFINE_SAMPLE(${name_video} ${srcs_video})
|
||||
|
||||
endif()
|
385
samples/openvx/no_wrappers.cpp
Normal file
385
samples/openvx/no_wrappers.cpp
Normal file
@ -0,0 +1,385 @@
|
||||
#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);
|
||||
}
|
214
samples/openvx/wrappers.cpp
Normal file
214
samples/openvx/wrappers.cpp
Normal file
@ -0,0 +1,214 @@
|
||||
#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);
|
||||
}
|
250
samples/openvx/wrappers_video.cpp
Normal file
250
samples/openvx/wrappers_video.cpp
Normal file
@ -0,0 +1,250 @@
|
||||
#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);
|
||||
}
|
Loading…
Reference in New Issue
Block a user