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
c0ee03fa
Commit
c0ee03fa
authored
Jul 21, 2015
by
Alexander Alekhin
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #4192 from avershov:opencl-opengl-buffer
parents
c976c119
89392b2a
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
193 additions
and
11 deletions
+193
-11
opengl.hpp
modules/core/include/opencv2/core/opengl.hpp
+21
-0
opengl.cpp
modules/core/src/opengl.cpp
+80
-0
opengl_interop.cpp
samples/opengl/opengl_interop.cpp
+92
-11
No files found.
modules/core/include/opencv2/core/opengl.hpp
View file @
c0ee03fa
...
...
@@ -537,6 +537,27 @@ CV_EXPORTS void convertToGLTexture2D(InputArray src, Texture2D& texture);
*/
CV_EXPORTS
void
convertFromGLTexture2D
(
const
Texture2D
&
texture
,
OutputArray
dst
);
/** @brief Maps Buffer object to process on CL side (convert to UMat).
Function creates CL buffer from GL one, and then constructs UMat that can be used
to process buffer data with OpenCV functions. Note that in current implementation
UMat constructed this way doesn't own corresponding GL buffer object, so it is
the user responsibility to close down CL/GL buffers relationships by explicitly
calling unmapGLBuffer() function.
@param buffer - source Buffer object.
@param accessFlags - data access flags (ACCESS_READ|ACCESS_WRITE).
@return Returns UMat object
*/
CV_EXPORTS
UMat
mapGLBuffer
(
const
Buffer
&
buffer
,
int
accessFlags
=
ACCESS_READ
|
ACCESS_WRITE
);
/** @brief Unmaps Buffer object (releases UMat, previously mapped from Buffer).
Function must be called explicitly by the user for each UMat previously constructed
by the call to mapGLBuffer() function.
@param u - source UMat, created by mapGLBuffer().
*/
CV_EXPORTS
void
unmapGLBuffer
(
UMat
&
u
);
}}
// namespace cv::ogl
namespace
cv
{
namespace
cuda
{
...
...
modules/core/src/opengl.cpp
View file @
c0ee03fa
...
...
@@ -1804,4 +1804,84 @@ void convertFromGLTexture2D(const Texture2D& texture, OutputArray dst)
#endif
}
//void mapGLBuffer(const Buffer& buffer, UMat& dst, int accessFlags)
UMat
mapGLBuffer
(
const
Buffer
&
buffer
,
int
accessFlags
)
{
(
void
)
buffer
;
(
void
)
accessFlags
;
#if !defined(HAVE_OPENGL)
NO_OPENGL_SUPPORT_ERROR
;
#elif !defined(HAVE_OPENCL)
NO_OPENCL_SUPPORT_ERROR
;
#else
using
namespace
cv
::
ocl
;
Context
&
ctx
=
Context
::
getDefault
();
cl_context
context
=
(
cl_context
)
ctx
.
ptr
();
cl_command_queue
clQueue
=
(
cl_command_queue
)
Queue
::
getDefault
().
ptr
();
int
clAccessFlags
=
0
;
switch
(
accessFlags
&
(
ACCESS_READ
|
ACCESS_WRITE
))
{
default
:
case
ACCESS_READ
|
ACCESS_WRITE
:
clAccessFlags
=
CL_MEM_READ_WRITE
;
break
;
case
ACCESS_READ
:
clAccessFlags
=
CL_MEM_READ_ONLY
;
break
;
case
ACCESS_WRITE
:
clAccessFlags
=
CL_MEM_WRITE_ONLY
;
break
;
}
cl_int
status
=
0
;
cl_mem
clBuffer
=
clCreateFromGLBuffer
(
context
,
clAccessFlags
,
buffer
.
bufId
(),
&
status
);
if
(
status
!=
CL_SUCCESS
)
CV_Error
(
cv
::
Error
::
OpenCLApiCallError
,
"OpenCL: clCreateFromGLBuffer failed"
);
gl
::
Finish
();
status
=
clEnqueueAcquireGLObjects
(
clQueue
,
1
,
&
clBuffer
,
0
,
NULL
,
NULL
);
if
(
status
!=
CL_SUCCESS
)
CV_Error
(
cv
::
Error
::
OpenCLApiCallError
,
"OpenCL: clEnqueueAcquireGLObjects failed"
);
size_t
step
=
buffer
.
cols
()
*
buffer
.
elemSize
();
int
rows
=
buffer
.
rows
();
int
cols
=
buffer
.
cols
();
int
type
=
buffer
.
type
();
UMat
u
;
convertFromBuffer
(
clBuffer
,
step
,
rows
,
cols
,
type
,
u
);
return
u
;
#endif
}
void
unmapGLBuffer
(
UMat
&
u
)
{
(
void
)
u
;
#if !defined(HAVE_OPENGL)
NO_OPENGL_SUPPORT_ERROR
;
#elif !defined(HAVE_OPENCL)
NO_OPENCL_SUPPORT_ERROR
;
#else
using
namespace
cv
::
ocl
;
cl_command_queue
clQueue
=
(
cl_command_queue
)
Queue
::
getDefault
().
ptr
();
cl_mem
clBuffer
=
(
cl_mem
)
u
.
handle
(
ACCESS_READ
);
u
.
release
();
cl_int
status
=
clEnqueueReleaseGLObjects
(
clQueue
,
1
,
&
clBuffer
,
0
,
NULL
,
NULL
);
if
(
status
!=
CL_SUCCESS
)
CV_Error
(
cv
::
Error
::
OpenCLApiCallError
,
"OpenCL: clEnqueueReleaseGLObjects failed"
);
status
=
clFinish
(
clQueue
);
if
(
status
!=
CL_SUCCESS
)
CV_Error
(
cv
::
Error
::
OpenCLApiCallError
,
"OpenCL: clFinish failed"
);
status
=
clReleaseMemObject
(
clBuffer
);
if
(
status
!=
CL_SUCCESS
)
CV_Error
(
cv
::
Error
::
OpenCLApiCallError
,
"OpenCL: clReleaseMemObject failed"
);
#endif
}
}}
// namespace cv::ogl
samples/opengl/opengl_interop.cpp
View file @
c0ee03fa
/*
// Sample demonstrating interoperability of OpenCV UMat with OpenGL texture.
// At first, the data obtained from video file or camera and placed onto
// OpenGL texture, following mapping of this OpenGL texture to OpenCV UMat
// and call cv::Blur function. The result is mapped back to OpenGL texture
// and rendered through OpenGL API.
*/
#if defined(WIN32) || defined(_WIN32)
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
...
...
@@ -25,6 +32,16 @@
# pragma comment(lib, "glu32.lib")
#endif
/*
// Press key to
// 0 no processing
// 1 processing on CPU
// 2 processing on GPU
// 9 toggle texture/buffer
// space toggle processing on/off, preserve mode
// esc quit
*/
class
GLWinApp
:
public
WinApp
{
public
:
...
...
@@ -33,9 +50,12 @@ public:
{
m_shutdown
=
false
;
m_mode
=
0
;
m_modeStr
[
0
]
=
cv
::
String
(
"No processing"
);
m_modeStr
[
1
]
=
cv
::
String
(
"Processing on CPU"
);
m_modeStr
[
2
]
=
cv
::
String
(
"Processing on GPU"
);
m_modeStr
[
0
]
=
cv
::
String
(
"Texture/No processing"
);
m_modeStr
[
1
]
=
cv
::
String
(
"Texture/Processing on CPU"
);
m_modeStr
[
2
]
=
cv
::
String
(
"Texture/Processing on GPU"
);
m_modeStr
[
3
]
=
cv
::
String
(
"Buffer/No processing"
);
m_modeStr
[
4
]
=
cv
::
String
(
"Buffer/Processing on CPU"
);
m_modeStr
[
5
]
=
cv
::
String
(
"Buffer/Processing on GPU"
);
m_disableProcessing
=
false
;
m_cap
=
cap
;
}
...
...
@@ -60,7 +80,12 @@ public:
case
WM_CHAR
:
if
(
wParam
>=
'0'
&&
wParam
<=
'2'
)
{
m_mode
=
(
char
)
wParam
-
'0'
;
set_mode
((
char
)
wParam
-
'0'
);
return
0
;
}
else
if
(
wParam
==
'9'
)
{
toggle_buffer
();
return
0
;
}
else
if
(
wParam
==
VK_SPACE
)
...
...
@@ -131,13 +156,16 @@ public:
m_disableProcessing
=
!
m_disableProcessing
;
break
;
case
XK_0
:
m_mode
=
0
;
set_mode
(
0
)
;
break
;
case
XK_1
:
m_mode
=
1
;
set_mode
(
1
)
;
break
;
case
XK_2
:
m_mode
=
2
;
set_mode
(
2
);
break
;
case
XK_9
:
toggle_buffer
();
break
;
case
XK_Escape
:
m_end_loop
=
true
;
...
...
@@ -187,13 +215,16 @@ public:
return
0
;
}
// init()
int
get_
texture
(
cv
::
ogl
::
Texture2D
&
texture
)
int
get_
frame
(
cv
::
ogl
::
Texture2D
&
texture
,
cv
::
ogl
::
Buffer
&
buffer
)
{
if
(
!
m_cap
.
read
(
m_frame_bgr
))
return
-
1
;
cv
::
cvtColor
(
m_frame_bgr
,
m_frame_rgba
,
CV_RGB2RGBA
);
if
(
use_buffer
())
buffer
.
copyFrom
(
m_frame_rgba
);
else
texture
.
copyFrom
(
m_frame_rgba
);
return
0
;
...
...
@@ -254,14 +285,16 @@ public:
int
r
;
cv
::
ogl
::
Texture2D
texture
;
cv
::
ogl
::
Buffer
buffer
;
r
=
get_
texture
(
texture
);
r
=
get_
frame
(
texture
,
buffer
);
if
(
r
!=
0
)
{
return
-
1
;
}
switch
(
m_mode
)
bool
do_buffer
=
use_buffer
();
switch
(
get_mode
())
{
case
0
:
// no processing
...
...
@@ -272,12 +305,20 @@ public:
// process video frame on CPU
cv
::
Mat
m
(
m_height
,
m_width
,
CV_8UC4
);
if
(
do_buffer
)
buffer
.
copyTo
(
m
);
else
texture
.
copyTo
(
m
);
if
(
!
m_disableProcessing
)
{
// blur texture image with OpenCV on CPU
cv
::
blur
(
m
,
m
,
cv
::
Size
(
15
,
15
),
cv
::
Point
(
-
7
,
-
7
));
}
if
(
do_buffer
)
buffer
.
copyFrom
(
m
);
else
texture
.
copyFrom
(
m
);
break
;
...
...
@@ -288,12 +329,20 @@ public:
// process video frame on GPU
cv
::
UMat
u
;
if
(
do_buffer
)
u
=
cv
::
ogl
::
mapGLBuffer
(
buffer
);
else
cv
::
ogl
::
convertFromGLTexture2D
(
texture
,
u
);
if
(
!
m_disableProcessing
)
{
// blur texture image with OpenCV on GPU with OpenCL
cv
::
blur
(
u
,
u
,
cv
::
Size
(
15
,
15
),
cv
::
Point
(
-
7
,
-
7
));
}
if
(
do_buffer
)
cv
::
ogl
::
unmapGLBuffer
(
u
);
else
cv
::
ogl
::
convertToGLTexture2D
(
u
,
texture
);
break
;
...
...
@@ -301,6 +350,13 @@ public:
}
// switch
if
(
do_buffer
)
// buffer -> texture
{
cv
::
Mat
m
(
m_height
,
m_width
,
CV_8UC4
);
buffer
.
copyTo
(
m
);
texture
.
copyFrom
(
m
);
}
#if defined(__linux__)
XWindowAttributes
window_attributes
;
XGetWindowAttributes
(
m_display
,
m_window
,
&
window_attributes
);
...
...
@@ -393,10 +449,35 @@ protected:
}
#endif
// modes: 0,1,2 - use texture
// 3,4,5 - use buffer
bool
use_buffer
()
{
return
bool
(
m_mode
>=
3
);
}
void
toggle_buffer
()
{
if
(
m_mode
<
3
)
m_mode
+=
3
;
else
m_mode
-=
3
;
}
int
get_mode
()
{
return
(
m_mode
%
3
);
}
void
set_mode
(
int
mode
)
{
bool
do_buffer
=
bool
(
m_mode
>=
3
);
m_mode
=
(
mode
%
3
);
if
(
do_buffer
)
m_mode
+=
3
;
}
private
:
bool
m_shutdown
;
int
m_mode
;
cv
::
String
m_modeStr
[
3
];
cv
::
String
m_modeStr
[
3
*
2
];
int
m_disableProcessing
;
#if defined(WIN32) || defined(_WIN32)
HDC
m_hDC
;
...
...
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