mirror of https://github.com/opencv/opencv.git
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/25007pull/25225/head
parent
5319772a56
commit
55426ee195
46 changed files with 2 additions and 7362 deletions
@ -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) |
@ -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. |
@ -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 "") |
@ -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` |
File diff suppressed because it is too large
Load Diff
@ -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 |
File diff suppressed because it is too large
Load Diff
@ -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
|
@ -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,5 +0,0 @@ |
||||
#include <VX/vx.h> |
||||
int main() |
||||
{ |
||||
return VX_REFERENCE_COUNT == VX_REFERENCE_TYPE ? VX_REFERENCE_NAME : 0; |
||||
} |
@ -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
|
@ -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
|
@ -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); |
||||
} |
Loading…
Reference in new issue