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
8 years ago
by
Alexander Alekhin
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #7163 from savuor:openvx_sample
parents
c1ee7982
f89ea6d7
No related merge requests found
Expand all
Show 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
This diff is collapsed.
Click to expand it.
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
()
...
...
This diff is collapsed.
Click to expand it.
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
()
This diff is collapsed.
Click to expand it.
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
);
}
This diff is collapsed.
Click to expand it.
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
);
}
This diff is collapsed.
Click to expand it.
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