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
fad96b95
Commit
fad96b95
authored
May 24, 2013
by
yao
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add results verification to facedetect and hog samples
parent
036b0579
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
229 additions
and
125 deletions
+229
-125
facedetect.cpp
samples/ocl/facedetect.cpp
+167
-123
hog.cpp
samples/ocl/hog.cpp
+62
-2
No files found.
samples/ocl/facedetect.cpp
View file @
fad96b95
//This sample is inherited from facedetect.cpp in smaple/c
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
...
...
@@ -9,78 +7,84 @@
using
namespace
std
;
using
namespace
cv
;
#define LOOP_NUM 10
const
static
Scalar
colors
[]
=
{
CV_RGB
(
0
,
0
,
255
),
CV_RGB
(
0
,
128
,
255
),
CV_RGB
(
0
,
255
,
255
),
CV_RGB
(
0
,
255
,
0
),
CV_RGB
(
255
,
128
,
0
),
CV_RGB
(
255
,
255
,
0
),
CV_RGB
(
255
,
0
,
0
),
CV_RGB
(
255
,
0
,
255
)}
;
static
void
help
()
int64
work_begin
=
0
;
int64
work_end
=
0
;
static
void
workBegin
()
{
work_begin
=
getTickCount
();
}
static
void
workEnd
()
{
cout
<<
"
\n
This program demonstrates the cascade recognizer.
\n
"
"This classifier can recognize many ~rigid objects, it's most known use is for faces.
\n
"
"Usage:
\n
"
"./facedetect [--cascade=<cascade_path> this is the primary trained classifier such as frontal face]
\n
"
" [--scale=<image scale greater or equal to 1, try 1.3 for example>
\n
"
" [filename|camera_index]
\n\n
"
"see facedetect.cmd for one call:
\n
"
"./facedetect --cascade=
\"
../../data/haarcascades/haarcascade_frontalface_alt.xml
\"
--scale=1.3
\n
"
"Hit any key to quit.
\n
"
"Using OpenCV version "
<<
CV_VERSION
<<
"
\n
"
<<
endl
;
work_end
+=
(
getTickCount
()
-
work_begin
);
}
struct
getRect
{
Rect
operator
()(
const
CvAvgComp
&
e
)
const
{
return
e
.
rect
;
}
};
void
detectAndDraw
(
Mat
&
img
,
cv
::
ocl
::
OclCascadeClassifier
&
cascade
,
CascadeClassifier
&
nestedCascade
,
double
scale
);
static
double
getTime
(){
return
work_end
/
((
double
)
cvGetTickFrequency
()
*
1000.
);
}
void
detect
(
Mat
&
img
,
vector
<
Rect
>&
faces
,
cv
::
ocl
::
OclCascadeClassifierBuf
&
cascade
,
double
scale
,
bool
calTime
);
String
cascadeName
=
"../../../data/haarcascades/haarcascade_frontalface_alt.xml"
;
void
detectCPU
(
Mat
&
img
,
vector
<
Rect
>&
faces
,
CascadeClassifier
&
cascade
,
double
scale
,
bool
calTime
);
void
Draw
(
Mat
&
img
,
vector
<
Rect
>&
faces
,
double
scale
);
// This function test if gpu_rst matches cpu_rst.
// If the two vectors are not equal, it will return the difference in vector size
// Else if will return (total diff of each cpu and gpu rects covered pixels)/(total cpu rects covered pixels)
double
checkRectSimilarity
(
Size
sz
,
std
::
vector
<
Rect
>&
cpu_rst
,
std
::
vector
<
Rect
>&
gpu_rst
);
int
main
(
int
argc
,
const
char
**
argv
)
{
CvCapture
*
capture
=
0
;
Mat
frame
,
frameCopy
,
image
;
const
String
scaleOpt
=
"--scale="
;
size_t
scaleOptLen
=
scaleOpt
.
length
();
const
String
cascadeOpt
=
"--cascade="
;
size_t
cascadeOptLen
=
cascadeOpt
.
length
();
String
inputName
;
help
();
cv
::
ocl
::
OclCascadeClassifier
cascade
;
CascadeClassifier
nestedCascade
;
double
scale
=
1
;
for
(
int
i
=
1
;
i
<
argc
;
i
++
)
const
char
*
keys
=
"{ h | help | false | print help message }"
"{ i | input | | specify input image }"
"{ t | template | ../../../data/haarcascades/haarcascade_frontalface_alt.xml | specify template file }"
"{ c | scale | 1.0 | scale image }"
"{ s | use_cpu | false | use cpu or gpu to process the image }"
;
CommandLineParser
cmd
(
argc
,
argv
,
keys
);
if
(
cmd
.
get
<
bool
>
(
"help"
))
{
cout
<<
"Processing "
<<
i
<<
" "
<<
argv
[
i
]
<<
endl
;
if
(
cascadeOpt
.
compare
(
0
,
cascadeOptLen
,
argv
[
i
],
cascadeOptLen
)
==
0
)
{
cascadeName
.
assign
(
argv
[
i
]
+
cascadeOptLen
);
cout
<<
" from which we have cascadeName= "
<<
cascadeName
<<
endl
;
}
else
if
(
scaleOpt
.
compare
(
0
,
scaleOptLen
,
argv
[
i
],
scaleOptLen
)
==
0
)
{
if
(
!
sscanf
(
argv
[
i
]
+
scaleOpt
.
length
(),
"%lf"
,
&
scale
)
||
scale
<
1
)
scale
=
1
;
cout
<<
" from which we read scale = "
<<
scale
<<
endl
;
}
else
if
(
argv
[
i
][
0
]
==
'-'
)
{
cerr
<<
"WARNING: Unknown option %s"
<<
argv
[
i
]
<<
endl
;
}
else
inputName
.
assign
(
argv
[
i
]
);
cout
<<
"Avaible options:"
<<
endl
;
cmd
.
printParams
();
return
0
;
}
CvCapture
*
capture
=
0
;
Mat
frame
,
frameCopy
,
image
;
if
(
!
cascade
.
load
(
cascadeName
)
)
bool
useCPU
=
cmd
.
get
<
bool
>
(
"s"
);
string
inputName
=
cmd
.
get
<
string
>
(
"i"
);
string
cascadeName
=
cmd
.
get
<
string
>
(
"t"
);
double
scale
=
cmd
.
get
<
double
>
(
"c"
);
cv
::
ocl
::
OclCascadeClassifierBuf
cascade
;
CascadeClassifier
cpu_cascade
;
if
(
!
cascade
.
load
(
cascadeName
)
||
!
cpu_cascade
.
load
(
cascadeName
)
)
{
cerr
<<
"ERROR: Could not load classifier cascade"
<<
endl
;
cerr
<<
"Usage: facedetect [--cascade=<cascade_path>]
\n
"
" [--scale[=<image scale>
\n
"
" [filename|camera_index]
\n
"
<<
endl
;
return
-
1
;
}
if
(
inputName
.
empty
()
||
(
isdigit
(
inputName
.
c_str
()[
0
])
&&
inputName
.
c_str
()[
1
]
==
'\0'
)
)
if
(
inputName
.
empty
()
)
{
capture
=
cvCaptureFromCAM
(
inputName
.
empty
()
?
0
:
inputName
.
c_str
()[
0
]
-
'0'
);
i
nt
c
=
inputName
.
empty
()
?
0
:
inputName
.
c_str
()[
0
]
-
'0'
;
if
(
!
capture
)
cout
<<
"Capture from CAM "
<<
c
<<
"
didn't work"
<<
endl
;
capture
=
cvCaptureFromCAM
(
0
);
i
f
(
!
capture
)
cout
<<
"Capture from CAM 0
didn't work"
<<
endl
;
}
else
if
(
inputName
.
size
()
)
{
...
...
@@ -88,26 +92,30 @@ int main( int argc, const char** argv )
if
(
image
.
empty
()
)
{
capture
=
cvCaptureFromAVI
(
inputName
.
c_str
()
);
if
(
!
capture
)
cout
<<
"Capture from AVI didn't work"
<<
endl
;
if
(
!
capture
)
cout
<<
"Capture from AVI didn't work"
<<
endl
;
return
-
1
;
}
}
else
{
image
=
imread
(
"lena.jpg"
,
1
);
if
(
image
.
empty
())
cout
<<
"Couldn't read lena.jpg"
<<
endl
;
if
(
image
.
empty
())
cout
<<
"Couldn't read lena.jpg"
<<
endl
;
return
-
1
;
}
cvNamedWindow
(
"result"
,
1
);
std
::
vector
<
cv
::
ocl
::
Info
>
oclinfo
;
int
devnums
=
cv
::
ocl
::
getDevice
(
oclinfo
);
if
(
devnums
<
1
)
if
(
devnums
<
1
)
{
std
::
cout
<<
"no device found
\n
"
;
return
-
1
;
}
//if you want to use undefault device, set it here
//setDevice(oclinfo[0]);
//setBinpath(CLBINPATH
);
ocl
::
setBinpath
(
"./"
);
if
(
capture
)
{
cout
<<
"In capture ..."
<<
endl
;
...
...
@@ -115,15 +123,20 @@ int main( int argc, const char** argv )
{
IplImage
*
iplImg
=
cvQueryFrame
(
capture
);
frame
=
iplImg
;
vector
<
Rect
>
faces
;
if
(
frame
.
empty
()
)
break
;
if
(
iplImg
->
origin
==
IPL_ORIGIN_TL
)
frame
.
copyTo
(
frameCopy
);
else
flip
(
frame
,
frameCopy
,
0
);
detectAndDraw
(
frameCopy
,
cascade
,
nestedCascade
,
scale
);
if
(
useCPU
){
detectCPU
(
frameCopy
,
faces
,
cpu_cascade
,
scale
,
false
);
}
else
{
detect
(
frameCopy
,
faces
,
cascade
,
scale
,
false
);
}
Draw
(
frameCopy
,
faces
,
scale
);
if
(
waitKey
(
10
)
>=
0
)
goto
_cleanup_
;
}
...
...
@@ -136,42 +149,34 @@ _cleanup_:
else
{
cout
<<
"In image read"
<<
endl
;
if
(
!
image
.
empty
()
)
{
detectAndDraw
(
image
,
cascade
,
nestedCascade
,
scale
);
waitKey
(
0
);
}
else
if
(
!
inputName
.
empty
()
)
vector
<
Rect
>
faces
;
vector
<
Rect
>
ref_rst
;
double
accuracy
=
0.
;
for
(
int
i
=
0
;
i
<=
LOOP_NUM
;
i
++
)
{
/* assume it is a text file containing the
list of the image filenames to be processed - one per line */
FILE
*
f
=
fopen
(
inputName
.
c_str
(),
"rt"
);
if
(
f
)
cout
<<
"loop"
<<
i
<<
endl
;
if
(
useCPU
){
detectCPU
(
image
,
faces
,
cpu_cascade
,
scale
,
i
==
0
?
false
:
true
);
}
else
{
detect
(
image
,
faces
,
cascade
,
scale
,
i
==
0
?
false
:
true
);
if
(
i
==
0
){
detectCPU
(
image
,
ref_rst
,
cpu_cascade
,
scale
,
false
);
accuracy
=
checkRectSimilarity
(
image
.
size
(),
ref_rst
,
faces
);
}
}
if
(
i
==
LOOP_NUM
)
{
char
buf
[
1000
+
1
];
while
(
fgets
(
buf
,
1000
,
f
)
)
{
int
len
=
(
int
)
strlen
(
buf
),
c
;
while
(
len
>
0
&&
isspace
(
buf
[
len
-
1
])
)
len
--
;
buf
[
len
]
=
'\0'
;
cout
<<
"file "
<<
buf
<<
endl
;
image
=
imread
(
buf
,
1
);
if
(
!
image
.
empty
()
)
{
detectAndDraw
(
image
,
cascade
,
nestedCascade
,
scale
);
c
=
waitKey
(
0
);
if
(
c
==
27
||
c
==
'q'
||
c
==
'Q'
)
break
;
}
else
{
cerr
<<
"Aw snap, couldn't read image "
<<
buf
<<
endl
;
}
}
fclose
(
f
);
if
(
useCPU
)
cout
<<
"average CPU time (noCamera) : "
;
else
cout
<<
"average GPU time (noCamera) : "
;
cout
<<
getTime
()
/
LOOP_NUM
<<
" ms"
<<
endl
;
cout
<<
"accuracy value: "
<<
accuracy
<<
endl
;
}
}
Draw
(
image
,
faces
,
scale
);
waitKey
(
0
);
}
cvDestroyWindow
(
"result"
);
...
...
@@ -179,44 +184,44 @@ _cleanup_:
return
0
;
}
void
detect
AndDraw
(
Mat
&
img
,
cv
::
ocl
::
OclCascadeClassifier
&
cascade
,
CascadeClassifier
&
,
double
scale
)
void
detect
(
Mat
&
img
,
vector
<
Rect
>&
faces
,
cv
::
ocl
::
OclCascadeClassifier
Buf
&
cascade
,
double
scale
,
bool
calTime
)
{
int
i
=
0
;
double
t
=
0
;
vector
<
Rect
>
faces
;
const
static
Scalar
colors
[]
=
{
CV_RGB
(
0
,
0
,
255
),
CV_RGB
(
0
,
128
,
255
),
CV_RGB
(
0
,
255
,
255
),
CV_RGB
(
0
,
255
,
0
),
CV_RGB
(
255
,
128
,
0
),
CV_RGB
(
255
,
255
,
0
),
CV_RGB
(
255
,
0
,
0
),
CV_RGB
(
255
,
0
,
255
)}
;
cv
::
ocl
::
oclMat
image
(
img
);
cv
::
ocl
::
oclMat
gray
,
smallImg
(
cvRound
(
img
.
rows
/
scale
),
cvRound
(
img
.
cols
/
scale
),
CV_8UC1
);
if
(
calTime
)
workBegin
();
cv
::
ocl
::
cvtColor
(
image
,
gray
,
CV_BGR2GRAY
);
cv
::
ocl
::
resize
(
gray
,
smallImg
,
smallImg
.
size
(),
0
,
0
,
INTER_LINEAR
);
cv
::
ocl
::
equalizeHist
(
smallImg
,
smallImg
);
CvSeq
*
_objects
;
MemStorage
storage
(
cvCreateMemStorage
(
0
));
t
=
(
double
)
cvGetTickCount
();
_objects
=
cascade
.
oclHaarDetectObjects
(
smallImg
,
storage
,
1.1
,
cascade
.
detectMultiScale
(
smallImg
,
faces
,
1.1
,
3
,
0
|
CV_HAAR_SCALE_IMAGE
,
Size
(
30
,
30
),
Size
(
0
,
0
)
);
vector
<
CvAvgComp
>
vecAvgComp
;
Seq
<
CvAvgComp
>
(
_objects
).
copyTo
(
vecAvgComp
);
faces
.
resize
(
vecAvgComp
.
size
());
std
::
transform
(
vecAvgComp
.
begin
(),
vecAvgComp
.
end
(),
faces
.
begin
(),
getRect
());
t
=
(
double
)
cvGetTickCount
()
-
t
;
printf
(
"detection time = %g ms
\n
"
,
t
/
((
double
)
cvGetTickFrequency
()
*
1000.
)
);
if
(
calTime
)
workEnd
();
}
void
detectCPU
(
Mat
&
img
,
vector
<
Rect
>&
faces
,
CascadeClassifier
&
cascade
,
double
scale
,
bool
calTime
)
{
if
(
calTime
)
workBegin
();
Mat
cpu_gray
,
cpu_smallImg
(
cvRound
(
img
.
rows
/
scale
),
cvRound
(
img
.
cols
/
scale
),
CV_8UC1
);
cvtColor
(
img
,
cpu_gray
,
CV_BGR2GRAY
);
resize
(
cpu_gray
,
cpu_smallImg
,
cpu_smallImg
.
size
(),
0
,
0
,
INTER_LINEAR
);
equalizeHist
(
cpu_smallImg
,
cpu_smallImg
);
cascade
.
detectMultiScale
(
cpu_smallImg
,
faces
,
1.1
,
3
,
0
|
CV_HAAR_SCALE_IMAGE
,
Size
(
30
,
30
),
Size
(
0
,
0
));
if
(
calTime
)
workEnd
();
}
void
Draw
(
Mat
&
img
,
vector
<
Rect
>&
faces
,
double
scale
)
{
int
i
=
0
;
for
(
vector
<
Rect
>::
const_iterator
r
=
faces
.
begin
();
r
!=
faces
.
end
();
r
++
,
i
++
)
{
Mat
smallImgROI
;
Point
center
;
Scalar
color
=
colors
[
i
%
8
];
int
radius
;
...
...
@@ -227,3 +232,42 @@ void detectAndDraw( Mat& img,
}
cv
::
imshow
(
"result"
,
img
);
}
double
checkRectSimilarity
(
Size
sz
,
std
::
vector
<
Rect
>&
ob1
,
std
::
vector
<
Rect
>&
ob2
)
{
double
final_test_result
=
0.0
;
size_t
sz1
=
ob1
.
size
();
size_t
sz2
=
ob2
.
size
();
if
(
sz1
!=
sz2
)
return
sz1
>
sz2
?
(
double
)(
sz1
-
sz2
)
:
(
double
)(
sz2
-
sz1
);
else
{
cv
::
Mat
cpu_result
(
sz
,
CV_8UC1
);
cpu_result
.
setTo
(
0
);
for
(
vector
<
Rect
>::
const_iterator
r
=
ob1
.
begin
();
r
!=
ob1
.
end
();
r
++
)
{
cv
::
Mat
cpu_result_roi
(
cpu_result
,
*
r
);
cpu_result_roi
.
setTo
(
1
);
cpu_result
.
copyTo
(
cpu_result
);
}
int
cpu_area
=
cv
::
countNonZero
(
cpu_result
>
0
);
cv
::
Mat
gpu_result
(
sz
,
CV_8UC1
);
gpu_result
.
setTo
(
0
);
for
(
vector
<
Rect
>::
const_iterator
r2
=
ob2
.
begin
();
r2
!=
ob2
.
end
();
r2
++
)
{
cv
::
Mat
gpu_result_roi
(
gpu_result
,
*
r2
);
gpu_result_roi
.
setTo
(
1
);
gpu_result
.
copyTo
(
gpu_result
);
}
cv
::
Mat
result_
;
multiply
(
cpu_result
,
gpu_result
,
result_
);
int
result
=
cv
::
countNonZero
(
result_
>
0
);
final_test_result
=
1.0
-
(
double
)
result
/
(
double
)
cpu_area
;
}
return
final_test_result
;
}
samples/ocl/hog.cpp
View file @
fad96b95
...
...
@@ -45,7 +45,6 @@ public:
bool
gamma_corr
;
};
class
App
{
public
:
...
...
@@ -64,6 +63,13 @@ public:
string
message
()
const
;
// This function test if gpu_rst matches cpu_rst.
// If the two vectors are not equal, it will return the difference in vector size
// Else if will return
// (total diff of each cpu and gpu rects covered pixels)/(total cpu rects covered pixels)
double
checkRectSimilarity
(
Size
sz
,
std
::
vector
<
Rect
>&
cpu_rst
,
std
::
vector
<
Rect
>&
gpu_rst
);
private
:
App
operator
=
(
App
&
);
...
...
@@ -290,6 +296,7 @@ void App::run()
ocl
::
oclMat
gpu_img
;
// Iterate over all frames
bool
verify
=
false
;
while
(
running
&&
!
frame
.
empty
())
{
workBegin
();
...
...
@@ -316,7 +323,18 @@ void App::run()
gpu_img
.
upload
(
img
);
gpu_hog
.
detectMultiScale
(
gpu_img
,
found
,
hit_threshold
,
win_stride
,
Size
(
0
,
0
),
scale
,
gr_threshold
);
}
if
(
!
verify
)
{
// verify if GPU output same objects with CPU at 1st run
verify
=
true
;
vector
<
Rect
>
ref_rst
;
cvtColor
(
img
,
img
,
CV_BGRA2BGR
);
cpu_hog
.
detectMultiScale
(
img
,
ref_rst
,
hit_threshold
,
win_stride
,
Size
(
0
,
0
),
scale
,
gr_threshold
-
2
);
double
accuracy
=
checkRectSimilarity
(
img
.
size
(),
ref_rst
,
found
);
cout
<<
"
\n
accuracy value: "
<<
accuracy
<<
endl
;
}
}
else
cpu_hog
.
detectMultiScale
(
img
,
found
,
hit_threshold
,
win_stride
,
Size
(
0
,
0
),
scale
,
gr_threshold
);
hogWorkEnd
();
...
...
@@ -457,3 +475,45 @@ inline string App::workFps() const
return
ss
.
str
();
}
double
App
::
checkRectSimilarity
(
Size
sz
,
std
::
vector
<
Rect
>&
ob1
,
std
::
vector
<
Rect
>&
ob2
)
{
double
final_test_result
=
0.0
;
size_t
sz1
=
ob1
.
size
();
size_t
sz2
=
ob2
.
size
();
if
(
sz1
!=
sz2
)
return
sz1
>
sz2
?
(
double
)(
sz1
-
sz2
)
:
(
double
)(
sz2
-
sz1
);
else
{
cv
::
Mat
cpu_result
(
sz
,
CV_8UC1
);
cpu_result
.
setTo
(
0
);
for
(
vector
<
Rect
>::
const_iterator
r
=
ob1
.
begin
();
r
!=
ob1
.
end
();
r
++
)
{
cv
::
Mat
cpu_result_roi
(
cpu_result
,
*
r
);
cpu_result_roi
.
setTo
(
1
);
cpu_result
.
copyTo
(
cpu_result
);
}
int
cpu_area
=
cv
::
countNonZero
(
cpu_result
>
0
);
cv
::
Mat
gpu_result
(
sz
,
CV_8UC1
);
gpu_result
.
setTo
(
0
);
for
(
vector
<
Rect
>::
const_iterator
r2
=
ob2
.
begin
();
r2
!=
ob2
.
end
();
r2
++
)
{
cv
::
Mat
gpu_result_roi
(
gpu_result
,
*
r2
);
gpu_result_roi
.
setTo
(
1
);
gpu_result
.
copyTo
(
gpu_result
);
}
cv
::
Mat
result_
;
multiply
(
cpu_result
,
gpu_result
,
result_
);
int
result
=
cv
::
countNonZero
(
result_
>
0
);
final_test_result
=
1.0
-
(
double
)
result
/
(
double
)
cpu_area
;
}
return
final_test_result
;
}
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