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
da948c82
Commit
da948c82
authored
Aug 03, 2015
by
Alexander Alekhin
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #5106 from vladimir-dudnik:opencl-opengl-upd
parents
0f8c46f3
5c4c8bce
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
207 additions
and
134 deletions
+207
-134
opengl_interop.cpp
samples/opengl/opengl_interop.cpp
+157
-133
winapp.hpp
samples/opengl/winapp.hpp
+50
-1
No files found.
samples/opengl/opengl_interop.cpp
View file @
da948c82
...
...
@@ -34,7 +34,6 @@
/*
// Press key to
// 0 no processing
// 1 processing on CPU
// 2 processing on GPU
// 9 toggle texture/buffer
...
...
@@ -45,19 +44,22 @@
class
GLWinApp
:
public
WinApp
{
public
:
enum
MODE
{
MODE_CPU
=
0
,
MODE_GPU
};
GLWinApp
(
int
width
,
int
height
,
std
::
string
&
window_name
,
cv
::
VideoCapture
&
cap
)
:
WinApp
(
width
,
height
,
window_name
)
{
m_shutdown
=
false
;
m_mode
=
0
;
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
;
m_shutdown
=
false
;
m_use_buffer
=
false
;
m_demo_processing
=
true
;
m_mode
=
MODE_CPU
;
m_modeStr
[
0
]
=
cv
::
String
(
"Processing on CPU"
);
m_modeStr
[
1
]
=
cv
::
String
(
"Processing on GPU"
);
m_cap
=
cap
;
}
~
GLWinApp
()
{}
...
...
@@ -78,9 +80,14 @@ public:
switch
(
message
)
{
case
WM_CHAR
:
if
(
wParam
>=
'0'
&&
wParam
<=
'2'
)
if
(
wParam
==
'1'
)
{
set_mode
(
MODE_CPU
);
return
0
;
}
if
(
wParam
==
'2'
)
{
set_mode
(
(
char
)
wParam
-
'0'
);
set_mode
(
MODE_GPU
);
return
0
;
}
else
if
(
wParam
==
'9'
)
...
...
@@ -90,7 +97,7 @@ public:
}
else
if
(
wParam
==
VK_SPACE
)
{
m_d
isableProcessing
=
!
m_disableP
rocessing
;
m_d
emo_processing
=
!
m_demo_p
rocessing
;
return
0
;
}
else
if
(
wParam
==
VK_ESCAPE
)
...
...
@@ -113,23 +120,6 @@ public:
}
#endif
static
float
getFps
()
{
static
std
::
queue
<
int64
>
time_queue
;
int64
now
=
cv
::
getTickCount
();
int64
then
=
0
;
time_queue
.
push
(
now
);
if
(
time_queue
.
size
()
>=
2
)
then
=
time_queue
.
front
();
if
(
time_queue
.
size
()
>=
25
)
time_queue
.
pop
();
return
time_queue
.
size
()
*
(
float
)
cv
::
getTickFrequency
()
/
(
now
-
then
);
}
#if defined(__linux__)
int
handle_event
(
XEvent
&
e
)
{
...
...
@@ -153,16 +143,13 @@ public:
switch
(
keycode_to_keysym
(
e
.
xkey
.
keycode
))
{
case
XK_space
:
m_disableProcessing
=
!
m_disableProcessing
;
break
;
case
XK_0
:
set_mode
(
0
);
m_demo_processing
=
!
m_demo_processing
;
break
;
case
XK_1
:
set_mode
(
1
);
set_mode
(
MODE_CPU
);
break
;
case
XK_2
:
set_mode
(
2
);
set_mode
(
MODE_GPU
);
break
;
case
XK_9
:
toggle_buffer
();
...
...
@@ -215,22 +202,22 @@ public:
return
0
;
}
// init()
int
get_frame
(
cv
::
ogl
::
Texture2D
&
texture
,
cv
::
ogl
::
Buffer
&
buffer
)
int
get_frame
(
cv
::
ogl
::
Texture2D
&
texture
,
cv
::
ogl
::
Buffer
&
buffer
,
bool
do_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
);
if
(
do_buffer
)
buffer
.
copyFrom
(
m_frame_rgba
,
cv
::
ogl
::
Buffer
::
PIXEL_UNPACK_BUFFER
,
true
);
else
texture
.
copyFrom
(
m_frame_rgba
);
texture
.
copyFrom
(
m_frame_rgba
,
true
);
return
0
;
}
void
print_info
(
int
mode
,
float
fps
,
cv
::
String
oclDevName
)
void
print_info
(
MODE
mode
,
float
time
,
cv
::
String
&
oclDevName
)
{
#if defined(WIN32) || defined(_WIN32)
HDC
hDC
=
m_hDC
;
...
...
@@ -248,12 +235,12 @@ public:
int
y
=
0
;
buf
[
0
]
=
0
;
sprintf_s
(
buf
,
sizeof
(
buf
)
-
1
,
"Mode: %s
"
,
m_modeStr
[
mode
].
c_str
()
);
sprintf_s
(
buf
,
sizeof
(
buf
)
-
1
,
"Mode: %s
OpenGL %s"
,
m_modeStr
[
mode
].
c_str
(),
use_buffer
()
?
"buffer"
:
"texture"
);
::
TextOut
(
hDC
,
0
,
y
,
buf
,
(
int
)
strlen
(
buf
));
y
+=
tm
.
tmHeight
;
buf
[
0
]
=
0
;
sprintf_s
(
buf
,
sizeof
(
buf
)
-
1
,
"
FPS: %2.1f"
,
fps
);
sprintf_s
(
buf
,
sizeof
(
buf
)
-
1
,
"
Time, msec: %2.1f"
,
time
);
::
TextOut
(
hDC
,
0
,
y
,
buf
,
(
int
)
strlen
(
buf
));
y
+=
tm
.
tmHeight
;
...
...
@@ -266,7 +253,7 @@ public:
#elif defined(__linux__)
char
buf
[
256
+
1
];
snprintf
(
buf
,
sizeof
(
buf
)
-
1
,
"
FPS: %2.1f Mode: %s Device: %s"
,
fps
,
m_modeStr
[
mode
].
c_str
()
,
oclDevName
.
c_str
());
snprintf
(
buf
,
sizeof
(
buf
)
-
1
,
"
Time, msec: %2.1f, Mode: %s OpenGL %s, Device: %s"
,
time
,
m_modeStr
[
mode
].
c_str
(),
use_buffer
()
?
"buffer"
:
"texture"
,
oclDevName
.
c_str
());
XStoreName
(
m_display
,
m_window
,
buf
);
#endif
}
...
...
@@ -287,74 +274,34 @@ public:
cv
::
ogl
::
Texture2D
texture
;
cv
::
ogl
::
Buffer
buffer
;
r
=
get_frame
(
texture
,
buffer
);
texture
.
setAutoRelease
(
true
);
buffer
.
setAutoRelease
(
true
);
MODE
mode
=
get_mode
();
bool
do_buffer
=
use_buffer
();
r
=
get_frame
(
texture
,
buffer
,
do_buffer
);
if
(
r
!=
0
)
{
return
-
1
;
}
bool
do_buffer
=
use_buffer
();
switch
(
get_mode
())
switch
(
mode
)
{
case
0
:
// no processing
case
MODE_CPU
:
// process frame on CPU
processFrameCPU
(
texture
,
buffer
,
do_buffer
);
break
;
case
1
:
{
// 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
);
case
MODE_GPU
:
// process frame on GPU
processFrameGPU
(
texture
,
buffer
,
do_buffer
);
break
;
}
case
2
:
{
// 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
;
}
}
// switch
if
(
do_buffer
)
// buffer -> texture
{
cv
::
Mat
m
(
m_height
,
m_width
,
CV_8UC4
);
buffer
.
copyTo
(
m
);
texture
.
copyFrom
(
m
);
texture
.
copyFrom
(
m
,
true
);
}
#if defined(__linux__)
...
...
@@ -382,7 +329,7 @@ public:
glXSwapBuffers
(
m_display
,
m_window
);
#endif
print_info
(
m
_mode
,
getFps
(
),
m_oclDevName
);
print_info
(
m
ode
,
m_timer
.
time
(
Timer
::
UNITS
::
MSEC
),
m_oclDevName
);
}
...
...
@@ -397,6 +344,56 @@ public:
protected
:
void
processFrameCPU
(
cv
::
ogl
::
Texture2D
&
texture
,
cv
::
ogl
::
Buffer
&
buffer
,
bool
do_buffer
)
{
cv
::
Mat
m
(
m_height
,
m_width
,
CV_8UC4
);
m_timer
.
start
();
if
(
do_buffer
)
buffer
.
copyTo
(
m
);
else
texture
.
copyTo
(
m
);
if
(
m_demo_processing
)
{
// 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
,
cv
::
ogl
::
Buffer
::
PIXEL_UNPACK_BUFFER
,
true
);
else
texture
.
copyFrom
(
m
,
true
);
m_timer
.
stop
();
}
void
processFrameGPU
(
cv
::
ogl
::
Texture2D
&
texture
,
cv
::
ogl
::
Buffer
&
buffer
,
bool
do_buffer
)
{
cv
::
UMat
u
;
m_timer
.
start
();
if
(
do_buffer
)
u
=
cv
::
ogl
::
mapGLBuffer
(
buffer
);
else
cv
::
ogl
::
convertFromGLTexture2D
(
texture
,
u
);
if
(
m_demo_processing
)
{
// 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
);
m_timer
.
stop
();
}
#if defined(WIN32) || defined(_WIN32)
int
setup_pixel_format
()
{
...
...
@@ -432,8 +429,10 @@ protected:
int
pfmt
=
ChoosePixelFormat
(
m_hDC
,
&
pfd
);
if
(
pfmt
==
0
)
return
-
1
;
if
(
SetPixelFormat
(
m_hDC
,
pfmt
,
&
pfd
)
==
0
)
return
-
2
;
return
0
;
}
#endif
...
...
@@ -449,36 +448,17 @@ 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
;
}
bool
use_buffer
()
{
return
m_use_buffer
;
}
void
toggle_buffer
()
{
m_use_buffer
=
!
m_use_buffer
;
}
MODE
get_mode
()
{
return
m_mode
;
}
void
set_mode
(
MODE
mode
)
{
m_mode
=
mode
;
}
private
:
bool
m_shutdown
;
int
m_mode
;
cv
::
String
m_modeStr
[
3
*
2
];
int
m_disableProcessing
;
bool
m_use_buffer
;
bool
m_demo_processing
;
MODE
m_mode
;
cv
::
String
m_modeStr
[
2
];
#if defined(WIN32) || defined(_WIN32)
HDC
m_hDC
;
HGLRC
m_hRC
;
...
...
@@ -491,20 +471,64 @@ private:
cv
::
String
m_oclDevName
;
};
static
void
help
()
{
printf
(
"
\n
Sample demonstrating interoperability of OpenGL and OpenCL with OpenCV.
\n
"
"Hot keys:
\n
"
" SPACE - turn processing on/off
\n
"
" 1 - process GL data through OpenCV on CPU
\n
"
" 2 - process GL data through OpenCV on GPU (via OpenCL)
\n
"
" 9 - toggle use of GL texture/GL buffer
\n
"
" ESC - exit
\n\n
"
);
}
static
const
char
*
keys
=
{
"{c camera | true | use camera or not}"
"{f file | | movie file name }"
"{h help | false | print help info }"
};
using
namespace
cv
;
using
namespace
std
;
int
main
(
int
argc
,
char
**
argv
)
{
cv
::
CommandLineParser
parser
(
argc
,
argv
,
keys
);
bool
useCamera
=
parser
.
has
(
"camera"
);
string
file
=
parser
.
get
<
string
>
(
"file"
);
bool
showHelp
=
parser
.
get
<
bool
>
(
"help"
);
if
(
showHelp
)
{
help
();
return
0
;
}
parser
.
printMessage
();
cv
::
VideoCapture
cap
;
if
(
argc
>
1
)
cap
.
open
(
argv
[
1
]);
else
if
(
useCamera
)
cap
.
open
(
0
);
else
cap
.
open
(
file
.
c_str
());
int
width
=
(
int
)
cap
.
get
(
CAP_PROP_FRAME_WIDTH
);
if
(
!
cap
.
isOpened
())
{
printf
(
"can not open camera or video file
\n
"
);
return
-
1
;
}
int
width
=
(
int
)
cap
.
get
(
CAP_PROP_FRAME_WIDTH
);
int
height
=
(
int
)
cap
.
get
(
CAP_PROP_FRAME_HEIGHT
);
std
::
string
wndname
=
"WGL Window"
;
#if defined(WIN32) || defined(_WIN32)
string
wndname
=
"WGL Window"
;
#elif defined(__linux__)
string
wndname
=
"GLX Window"
;
#endif
GLWinApp
app
(
width
,
height
,
wndname
,
cap
);
...
...
@@ -515,12 +539,12 @@ int main(int argc, char** argv)
}
catch
(
cv
::
Exception
&
e
)
{
std
::
cerr
<<
"Exception: "
<<
e
.
what
()
<<
std
::
endl
;
cerr
<<
"Exception: "
<<
e
.
what
()
<<
endl
;
return
10
;
}
catch
(...)
{
std
::
cerr
<<
"FATAL ERROR: Unknown exception"
<<
std
::
endl
;
cerr
<<
"FATAL ERROR: Unknown exception"
<<
endl
;
return
11
;
}
}
samples/opengl/winapp.hpp
View file @
da948c82
...
...
@@ -22,6 +22,54 @@
#define SAFE_RELEASE(p) if (p) { p->Release(); p = NULL; }
class
Timer
{
public
:
enum
UNITS
{
USEC
=
0
,
MSEC
,
SEC
};
Timer
()
:
m_t0
(
0
),
m_diff
(
0
)
{
m_tick_frequency
=
(
float
)
cv
::
getTickFrequency
();
m_unit_mul
[
USEC
]
=
1000000
;
m_unit_mul
[
MSEC
]
=
1000
;
m_unit_mul
[
SEC
]
=
1
;
}
void
clear
()
{
m_t0
=
m_diff
=
0
;
}
void
start
()
{
m_t0
=
cv
::
getTickCount
();
}
void
stop
()
{
m_diff
=
cv
::
getTickCount
()
-
m_t0
;
}
float
time
(
UNITS
u
=
UNITS
::
MSEC
)
{
float
sec
=
m_diff
/
m_tick_frequency
;
return
sec
*
m_unit_mul
[
u
];
}
public
:
float
m_tick_frequency
;
int64
m_t0
;
int64
m_diff
;
int
m_unit_mul
[
3
];
};
class
WinApp
{
public
:
...
...
@@ -162,9 +210,9 @@ public:
idle
();
}
}
while
(
!
m_end_loop
);
#endif
return
0
;
#endif
}
protected
:
...
...
@@ -218,4 +266,5 @@ protected:
int
m_width
;
int
m_height
;
std
::
string
m_window_name
;
Timer
m_timer
;
};
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