Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
O
opencv
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
opencv
Commits
8151be9a
Commit
8151be9a
authored
Nov 22, 2016
by
Alexander Alekhin
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #7163 from savuor:openvx_sample
parents
c1ee7982
f89ea6d7
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
591 additions
and
20 deletions
+591
-20
ivx.hpp
3rdparty/openvx/include/ivx.hpp
+86
-20
CMakeLists.txt
samples/CMakeLists.txt
+4
-0
CMakeLists.txt
samples/openvx/CMakeLists.txt
+37
-0
no_wrappers.cpp
samples/openvx/no_wrappers.cpp
+0
-0
wrappers.cpp
samples/openvx/wrappers.cpp
+214
-0
wrappers_video.cpp
samples/openvx/wrappers_video.cpp
+250
-0
No files found.
3rdparty/openvx/include/ivx.hpp
View file @
8151be9a
...
...
@@ -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
st
atus
,
const
std
::
string
&
msg
=
""
)
:
runtime_error
(
msg
),
_status
(
st
atus
)
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
mem
ory
Type
=
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
,
mem
ory
Type
));
#else
(
void
)
memType
;
(
void
)
mem
ory
Type
;
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
&
rect
angle
()
const
{
return
_rect
;
}
/// Image plane index for the current mapping
vx_uint32
planeI
d
x
()
const
vx_uint32
planeI
nde
x
()
const
{
return
_planeIdx
;
}
#endif // VX_VERSION_1_1
/// vx_image for the current mapping
vx_image
im
g
()
const
vx_image
im
age
()
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
,
&
val
1
,
sizeof
(
val1
))
);
IVX_CHECK_STATUS
(
vxSetThresholdAttribute
(
thr
.
ref
,
VX_THRESHOLD_THRESHOLD_UPPER
,
&
val
2
,
sizeof
(
val2
))
);
IVX_CHECK_STATUS
(
vxSetThresholdAttribute
(
thr
.
ref
,
VX_THRESHOLD_THRESHOLD_LOWER
,
&
val
Lower
,
sizeof
(
valLower
))
);
IVX_CHECK_STATUS
(
vxSetThresholdAttribute
(
thr
.
ref
,
VX_THRESHOLD_THRESHOLD_UPPER
,
&
val
Upper
,
sizeof
(
valUpper
))
);
return
thr
;
}
/// vxQueryThreshold() wrapper
template
<
typename
T
>
void
query
(
vx_enum
att
,
T
&
val
ue
)
const
{
IVX_CHECK_STATUS
(
vxQueryThreshold
(
ref
,
att
,
&
val
ue
,
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
samples/CMakeLists.txt
View file @
8151be9a
...
...
@@ -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
()
...
...
samples/openvx/CMakeLists.txt
0 → 100644
View file @
8151be9a
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
()
samples/openvx/no_wrappers.cpp
0 → 100644
View file @
8151be9a
This diff is collapsed.
Click to expand it.
samples/openvx/wrappers.cpp
0 → 100644
View file @
8151be9a
#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
);
}
samples/openvx/wrappers_video.cpp
0 → 100644
View file @
8151be9a
#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
);
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment