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
5c969d19
Commit
5c969d19
authored
Sep 01, 2016
by
Rostislav Vasilikhin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
interoperability OpenVX samples added
parent
b54bc2db
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
891 additions
and
0 deletions
+891
-0
CMakeLists.txt
samples/CMakeLists.txt
+4
-0
CMakeLists.txt
samples/openvx/CMakeLists.txt
+36
-0
no_wrappers.cpp
samples/openvx/no_wrappers.cpp
+382
-0
wrappers.cpp
samples/openvx/wrappers.cpp
+216
-0
wrappers_video.cpp
samples/openvx/wrappers_video.cpp
+253
-0
No files found.
samples/CMakeLists.txt
View file @
5c969d19
...
...
@@ -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 @
5c969d19
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
)
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 @
5c969d19
#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
,
MAP_TO_VX
};
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
{
#ifdef VX_VERSION_1_1
ovxImage
=
vxCreateImageFromHandle
(
context
,
color
,
&
addr
,
(
void
*
const
*
)
&
ovxData
,
VX_MEMORY_TYPE_HOST
);
#else
ovxImage
=
vxCreateImageFromHandle
(
context
,
color
,
&
addr
,
(
void
**
)
&
ovxData
,
VX_MEMORY_TYPE_HOST
);
#endif
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
==
MAP_TO_VX
)
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
"
"map_to_vx: 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
==
"map_to_vx"
)
{
mode
=
MAP_TO_VX
;
}
else
if
(
modeString
==
"map_from_vx"
)
{
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
);
}
samples/openvx/wrappers.cpp
0 → 100644
View file @
5c969d19
#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
,
MAP_TO_VX
,
MAP_FROM_VX
};
ivx
::
Graph
createProcessingGraph
(
ivx
::
Image
&
inputImage
,
ivx
::
Image
&
outputImage
)
{
using
namespace
ivx
;
Context
context
=
inputImage
.
getContext
();
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
{
vx_imagepatch_addressing_t
addressing
=
Image
::
createAddressing
(
image
);
const
std
::
vector
<
vx_imagepatch_addressing_t
>
addrs
(
1
,
addressing
);
const
std
::
vector
<
void
*>
ptrs
(
1
,
image
.
data
);
ivxImage
=
Image
::
createFromHandle
(
context
,
color
,
addrs
,
ptrs
);
}
Image
ivxResult
;
Image
::
Patch
resultPatch
;
Mat
output
;
if
(
mode
==
COPY
||
mode
==
MAP_FROM_VX
)
{
//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
));
vx_imagepatch_addressing_t
addressing
=
Image
::
createAddressing
(
output
);
const
std
::
vector
<
vx_imagepatch_addressing_t
>
addrs
(
1
,
addressing
);
const
std
::
vector
<
void
*>
ptrs
(
1
,
output
.
data
);
ivxResult
=
Image
::
createFromHandle
(
context
,
Image
::
matTypeToFormat
(
CV_8U
),
addrs
,
ptrs
);
}
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_FROM_VX
)
{
//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
==
MAP_TO_VX
)
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
"
"map_to_vx: use handles to user-allocated memory
\n
"
"map_from_vx: 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
==
"map_to_vx"
)
{
mode
=
MAP_TO_VX
;
}
else
if
(
modeString
==
"map_from_vx"
)
{
mode
=
MAP_FROM_VX
;
}
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 @
5c969d19
#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
,
MAP_TO_VX
,
MAP_FROM_VX
};
ivx
::
Graph
createProcessingGraph
(
ivx
::
Image
&
inputImage
,
ivx
::
Image
&
outputImage
)
{
using
namespace
ivx
;
Context
context
=
inputImage
.
getContext
();
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
{
vx_imagepatch_addressing_t
addressing
=
Image
::
createAddressing
(
frame
);
const
std
::
vector
<
vx_imagepatch_addressing_t
>
addrs
(
1
,
addressing
);
const
std
::
vector
<
void
*>
ptrs
(
1
,
frame
.
data
);
ivxImage
=
Image
::
createFromHandle
(
context
,
color
,
addrs
,
ptrs
);
}
Image
ivxResult
;
Mat
output
;
if
(
mode
==
COPY
||
mode
==
MAP_FROM_VX
)
{
//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
));
vx_imagepatch_addressing_t
addressing
=
Image
::
createAddressing
(
output
);
const
std
::
vector
<
vx_imagepatch_addressing_t
>
addrs
(
1
,
addressing
);
const
std
::
vector
<
void
*>
ptrs
(
1
,
output
.
data
);
ivxResult
=
Image
::
createFromHandle
(
context
,
Image
::
matTypeToFormat
(
CV_8U
),
addrs
,
ptrs
);
}
Graph
graph
=
createProcessingGraph
(
ivxImage
,
ivxResult
);
std
::
vector
<
void
*>
ptrs
;
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
*>
prevPtrs
;
if
(
mode
==
COPY
)
{
ivxResult
.
copyTo
(
0
,
output
);
}
else
if
(
mode
==
MAP_FROM_VX
)
{
//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
==
MAP_TO_VX
)
{
ivxResult
.
swapHandle
(
prevPtrs
);
}
#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
==
MAP_TO_VX
)
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
"
"map_to_vx: use handles to user-allocated memory
\n
"
"map_from_vx: 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
==
"map_to_vx"
)
{
mode
=
MAP_TO_VX
;
}
else
if
(
modeString
==
"map_from_vx"
)
{
mode
=
MAP_FROM_VX
;
}
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