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
734212a4
Commit
734212a4
authored
Jan 14, 2015
by
Vladislav Vinogradov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
refactor CUDA CascadeClassifier
parent
8257dc3c
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
99 additions
and
119 deletions
+99
-119
cudaobjdetect.hpp
modules/cudaobjdetect/include/opencv2/cudaobjdetect.hpp
+48
-51
perf_objdetect.cpp
modules/cudaobjdetect/perf/perf_objdetect.cpp
+12
-14
cascadeclassifier.cpp
modules/cudaobjdetect/src/cascadeclassifier.cpp
+0
-0
test_objdetect.cpp
modules/cudaobjdetect/test/test_objdetect.cpp
+19
-14
cascadeclassifier.cpp
samples/gpu/cascadeclassifier.cpp
+20
-40
No files found.
modules/cudaobjdetect/include/opencv2/cudaobjdetect.hpp
View file @
734212a4
...
...
@@ -75,7 +75,7 @@ namespace cv { namespace cuda {
- (Python) An example applying the HOG descriptor for people detection can be found at
opencv_source_code/samples/python2/peopledetect.py
*/
class
CV_EXPORTS
HOG
:
public
cv
::
Algorithm
class
CV_EXPORTS
HOG
:
public
Algorithm
{
public
:
enum
...
...
@@ -204,87 +204,84 @@ public:
- A Nvidea API specific cascade classifier example can be found at
opencv_source_code/samples/gpu/cascadeclassifier_nvidia_api.cpp
*/
class
CV_EXPORTS
CascadeClassifier
_CUDA
class
CV_EXPORTS
CascadeClassifier
:
public
Algorithm
{
public
:
CascadeClassifier_CUDA
();
/** @brief Loads the classifier from a file. Cascade type is detected automatically by constructor parameter.
@param filename Name of the file from which the classifier is loaded. Only the old haar classifier
(trained by the haar training application) and NVIDIA's nvbin are supported for HAAR and only new
type of OpenCV XML cascade supported for LBP.
*/
CascadeClassifier_CUDA
(
const
String
&
filename
);
~
CascadeClassifier_CUDA
();
static
Ptr
<
CascadeClassifier
>
create
(
const
String
&
filename
);
/** @overload
*/
static
Ptr
<
CascadeClassifier
>
create
(
const
FileStorage
&
file
);
/
** @brief Checks whether the classifier is loaded or not.
*/
bool
empty
()
const
;
/** @brief Loads the classifier from a file. The previous content is destroyed.
/
/! Maximum possible object size. Objects larger than that are ignored. Used for
//! second signature and supported only for LBP cascades.
virtual
void
setMaxObjectSize
(
Size
maxObjectSize
)
=
0
;
virtual
Size
getMaxObjectSize
()
const
=
0
;
@param filename Name of the file from which the classifier is loaded. Only the old haar classifier
(trained by the haar training application) and NVIDIA's nvbin are supported for HAAR and only new
type of OpenCV XML cascade supported for LBP.
*/
bool
load
(
const
String
&
filename
);
/** @brief Destroys the loaded classifier.
*/
void
release
();
//! Minimum possible object size. Objects smaller than that are ignored.
virtual
void
setMinObjectSize
(
Size
minSize
)
=
0
;
virtual
Size
getMinObjectSize
()
const
=
0
;
//! Parameter specifying how much the image size is reduced at each image scale.
virtual
void
setScaleFactor
(
double
scaleFactor
)
=
0
;
virtual
double
getScaleFactor
()
const
=
0
;
//! Parameter specifying how many neighbors each candidate rectangle should have
//! to retain it.
virtual
void
setMinNeighbors
(
int
minNeighbors
)
=
0
;
virtual
int
getMinNeighbors
()
const
=
0
;
virtual
void
setFindLargestObject
(
bool
findLargestObject
)
=
0
;
virtual
bool
getFindLargestObject
()
=
0
;
virtual
void
setMaxNumObjects
(
int
maxNumObjects
)
=
0
;
virtual
int
getMaxNumObjects
()
const
=
0
;
virtual
Size
getClassifierSize
()
const
=
0
;
/** @overload */
int
detectMultiScale
(
const
GpuMat
&
image
,
GpuMat
&
objectsBuf
,
double
scaleFactor
=
1.2
,
int
minNeighbors
=
4
,
Size
minSize
=
Size
());
/** @brief Detects objects of different sizes in the input image.
@param image Matrix of type CV_8U containing an image where objects should be detected.
@param objectsBuf Buffer to store detected objects (rectangles). If it is empty, it is allocated
with the default size. If not empty, the function searches not more than N objects, where
N = sizeof(objectsBufer's data)/sizeof(cv::Rect).
@param maxObjectSize Maximum possible object size. Objects larger than that are ignored. Used for
second signature and supported only for LBP cascades.
@param scaleFactor Parameter specifying how much the image size is reduced at each image scale.
@param minNeighbors Parameter specifying how many neighbors each candidate rectangle should have
to retain it.
@param minSize Minimum possible object size. Objects smaller than that are ignored.
The detected objects are returned as a list of rectangles.
The function returns the number of detected objects, so you can retrieve them as in the following
example:
@param objects Buffer to store detected objects (rectangles).
To get final array of detected objects use CascadeClassifier::convert method.
@code
cuda::CascadeClassifier_CUDA cascade_gpu
(...);
Ptr<cuda::CascadeClassifier> cascade_gpu = cuda::CascadeClassifier::create
(...);
Mat image_cpu = imread(...)
GpuMat image_gpu(image_cpu);
GpuMat objbuf;
int detections_number = cascade_gpu.detectMultiScale( image_gpu,
objbuf, 1.2, minNeighbors);
cascade_gpu->detectMultiScale(image_gpu, objbuf);
Mat obj_host;
// download only detected number of rectangles
objbuf.colRange(0, detections_number).download(obj_host);
std::vector<Rect> faces;
cascade_gpu->convert(objbuf, faces);
Rect* faces = obj_host.ptr<Rect>();
for(int i = 0; i < detections_num; ++i)
cv::rectangle(image_cpu, faces[i], Scalar(255));
imshow("Faces", image_cpu);
@endcode
@sa CascadeClassifier::detectMultiScale
*/
int
detectMultiScale
(
const
GpuMat
&
image
,
GpuMat
&
objectsBuf
,
Size
maxObjectSize
,
Size
minSize
=
Size
(),
double
scaleFactor
=
1.1
,
int
minNeighbors
=
4
);
virtual
void
detectMultiScale
(
InputArray
image
,
OutputArray
objects
,
Stream
&
stream
=
Stream
::
Null
())
=
0
;
bool
findLargestObject
;
bool
visualizeInPlace
;
/** @brief Converts objects array from internal representation to standard vector.
Size
getClassifierSize
()
const
;
private
:
struct
CascadeClassifierImpl
;
CascadeClassifierImpl
*
impl
;
struct
HaarCascade
;
struct
LbpCascade
;
friend
class
CascadeClassifier_CUDA_LBP
;
@param gpu_objects Objects array in internal representation.
@param objects Resulting array.
*/
virtual
void
convert
(
OutputArray
gpu_objects
,
std
::
vector
<
Rect
>&
objects
)
=
0
;
};
//! @}
...
...
modules/cudaobjdetect/perf/perf_objdetect.cpp
View file @
734212a4
...
...
@@ -107,18 +107,17 @@ PERF_TEST_P(ImageAndCascade, ObjDetect_HaarClassifier,
if
(
PERF_RUN_CUDA
())
{
cv
::
cuda
::
CascadeClassifier_CUDA
d_cascade
;
ASSERT_TRUE
(
d_cascade
.
load
(
perf
::
TestBase
::
getDataPath
(
GetParam
().
second
)
));
cv
::
Ptr
<
cv
::
cuda
::
CascadeClassifier
>
d_cascade
=
cv
::
cuda
::
CascadeClassifier
::
create
(
perf
::
TestBase
::
getDataPath
(
GetParam
().
second
));
const
cv
::
cuda
::
GpuMat
d_img
(
img
);
cv
::
cuda
::
GpuMat
objects_buffer
;
int
detections_num
=
0
;
TEST_CYCLE
()
detections_num
=
d_cascade
.
detectMultiScale
(
d_img
,
objects_buffer
);
TEST_CYCLE
()
d_cascade
->
detectMultiScale
(
d_img
,
objects_buffer
);
std
::
vector
<
cv
::
Rect
>
gpu_rects
;
d_cascade
->
convert
(
objects_buffer
,
gpu_rects
);
std
::
vector
<
cv
::
Rect
>
gpu_rects
(
detections_num
);
cv
::
Mat
gpu_rects_mat
(
1
,
detections_num
,
cv
::
DataType
<
cv
::
Rect
>::
type
,
&
gpu_rects
[
0
]);
objects_buffer
.
colRange
(
0
,
detections_num
).
download
(
gpu_rects_mat
);
cv
::
groupRectangles
(
gpu_rects
,
3
,
0.2
);
SANITY_CHECK
(
gpu_rects
);
}
...
...
@@ -146,18 +145,17 @@ PERF_TEST_P(ImageAndCascade, ObjDetect_LBPClassifier,
if
(
PERF_RUN_CUDA
())
{
cv
::
cuda
::
CascadeClassifier_CUDA
d_cascade
;
ASSERT_TRUE
(
d_cascade
.
load
(
perf
::
TestBase
::
getDataPath
(
GetParam
().
second
)
));
cv
::
Ptr
<
cv
::
cuda
::
CascadeClassifier
>
d_cascade
=
cv
::
cuda
::
CascadeClassifier
::
create
(
perf
::
TestBase
::
getDataPath
(
GetParam
().
second
));
const
cv
::
cuda
::
GpuMat
d_img
(
img
);
cv
::
cuda
::
GpuMat
objects_buffer
;
int
detections_num
=
0
;
TEST_CYCLE
()
detections_num
=
d_cascade
.
detectMultiScale
(
d_img
,
objects_buffer
);
TEST_CYCLE
()
d_cascade
->
detectMultiScale
(
d_img
,
objects_buffer
);
std
::
vector
<
cv
::
Rect
>
gpu_rects
;
d_cascade
->
convert
(
objects_buffer
,
gpu_rects
);
std
::
vector
<
cv
::
Rect
>
gpu_rects
(
detections_num
);
cv
::
Mat
gpu_rects_mat
(
1
,
detections_num
,
cv
::
DataType
<
cv
::
Rect
>::
type
,
&
gpu_rects
[
0
]);
objects_buffer
.
colRange
(
0
,
detections_num
).
download
(
gpu_rects_mat
);
cv
::
groupRectangles
(
gpu_rects
,
3
,
0.2
);
SANITY_CHECK
(
gpu_rects
);
}
...
...
modules/cudaobjdetect/src/cascadeclassifier.cpp
View file @
734212a4
This diff is collapsed.
Click to expand it.
modules/cudaobjdetect/test/test_objdetect.cpp
View file @
734212a4
...
...
@@ -287,9 +287,15 @@ PARAM_TEST_CASE(LBP_Read_classifier, cv::cuda::DeviceInfo, int)
CUDA_TEST_P
(
LBP_Read_classifier
,
Accuracy
)
{
cv
::
cuda
::
CascadeClassifier_CUDA
classifier
;
std
::
string
classifierXmlPath
=
std
::
string
(
cvtest
::
TS
::
ptr
()
->
get_data_path
())
+
"lbpcascade/lbpcascade_frontalface.xml"
;
ASSERT_TRUE
(
classifier
.
load
(
classifierXmlPath
));
cv
::
Ptr
<
cv
::
cuda
::
CascadeClassifier
>
d_cascade
;
ASSERT_NO_THROW
(
d_cascade
=
cv
::
cuda
::
CascadeClassifier
::
create
(
classifierXmlPath
);
);
ASSERT_FALSE
(
d_cascade
.
empty
());
}
INSTANTIATE_TEST_CASE_P
(
CUDA_ObjDetect
,
LBP_Read_classifier
,
...
...
@@ -329,29 +335,28 @@ CUDA_TEST_P(LBP_classify, Accuracy)
for
(;
it
!=
rects
.
end
();
++
it
)
cv
::
rectangle
(
markedImage
,
*
it
,
cv
::
Scalar
(
255
,
0
,
0
));
cv
::
cuda
::
CascadeClassifier_CUDA
gpuClassifier
;
ASSERT_TRUE
(
gpuClassifier
.
load
(
classifierXmlPath
)
);
cv
::
Ptr
<
cv
::
cuda
::
CascadeClassifier
>
gpuClassifier
=
cv
::
cuda
::
CascadeClassifier
::
create
(
classifierXmlPath
);
cv
::
cuda
::
GpuMat
gpu_rects
;
cv
::
cuda
::
GpuMat
tested
(
grey
);
int
count
=
gpuClassifier
.
detectMultiScale
(
tested
,
gpu_rects
);
cv
::
cuda
::
GpuMat
gpu_rects_buf
;
gpuClassifier
->
detectMultiScale
(
tested
,
gpu_rects_buf
);
std
::
vector
<
cv
::
Rect
>
gpu_rects
;
gpuClassifier
->
convert
(
gpu_rects_buf
,
gpu_rects
);
#if defined (LOG_CASCADE_STATISTIC)
cv
::
Mat
downloaded
(
gpu_rects
);
const
cv
::
Rect
*
faces
=
downloaded
.
ptr
<
cv
::
Rect
>
();
for
(
int
i
=
0
;
i
<
count
;
i
++
)
for
(
size_t
i
=
0
;
i
<
gpu_rects
.
size
();
i
++
)
{
cv
::
Rect
r
=
face
s
[
i
];
cv
::
Rect
r
=
gpu_rect
s
[
i
];
std
::
cout
<<
r
.
x
<<
" "
<<
r
.
y
<<
" "
<<
r
.
width
<<
" "
<<
r
.
height
<<
std
::
endl
;
cv
::
rectangle
(
markedImage
,
r
,
CV_RGB
(
255
,
0
,
0
));
}
#endif
#if defined (LOG_CASCADE_STATISTIC)
cv
::
imshow
(
"Res"
,
markedImage
);
cv
::
waitKey
();
cv
::
imshow
(
"Res"
,
markedImage
);
cv
::
waitKey
();
#endif
(
void
)
count
;
}
INSTANTIATE_TEST_CASE_P
(
CUDA_ObjDetect
,
LBP_classify
,
...
...
samples/gpu/cascadeclassifier.cpp
View file @
734212a4
...
...
@@ -173,13 +173,9 @@ int main(int argc, const char *argv[])
}
}
CascadeClassifier_CUDA
cascade_gpu
;
if
(
!
cascade_gpu
.
load
(
cascadeName
))
{
return
cerr
<<
"ERROR: Could not load cascade classifier
\"
"
<<
cascadeName
<<
"
\"
"
<<
endl
,
help
(),
-
1
;
}
Ptr
<
cuda
::
CascadeClassifier
>
cascade_gpu
=
cuda
::
CascadeClassifier
::
create
(
cascadeName
);
CascadeClassifier
cascade_cpu
;
cv
::
CascadeClassifier
cascade_cpu
;
if
(
!
cascade_cpu
.
load
(
cascadeName
))
{
return
cerr
<<
"ERROR: Could not load cascade classifier
\"
"
<<
cascadeName
<<
"
\"
"
<<
endl
,
help
(),
-
1
;
...
...
@@ -206,8 +202,8 @@ int main(int argc, const char *argv[])
namedWindow
(
"result"
,
1
);
Mat
frame
,
frame_cpu
,
gray_cpu
,
resized_cpu
,
f
aces_downloaded
,
f
rameDisp
;
vector
<
Rect
>
faces
Buf_cpu
;
Mat
frame
,
frame_cpu
,
gray_cpu
,
resized_cpu
,
frameDisp
;
vector
<
Rect
>
faces
;
GpuMat
frame_gpu
,
gray_gpu
,
resized_gpu
,
facesBuf_gpu
;
...
...
@@ -218,7 +214,6 @@ int main(int argc, const char *argv[])
bool
filterRects
=
true
;
bool
helpScreen
=
false
;
int
detections_num
;
for
(;;)
{
if
(
isInputCamera
||
isInputVideo
)
...
...
@@ -241,40 +236,26 @@ int main(int argc, const char *argv[])
if
(
useGPU
)
{
//cascade_gpu.visualizeInPlace = true;
cascade_gpu
.
findLargestObject
=
findLargestObject
;
cascade_gpu
->
setFindLargestObject
(
findLargestObject
);
cascade_gpu
->
setScaleFactor
(
1.2
);
cascade_gpu
->
setMinNeighbors
((
filterRects
||
findLargestObject
)
?
4
:
0
);
detections_num
=
cascade_gpu
.
detectMultiScale
(
resized_gpu
,
facesBuf_gpu
,
1.2
,
(
filterRects
||
findLargestObject
)
?
4
:
0
);
facesBuf_gpu
.
colRange
(
0
,
detections_num
).
download
(
faces_downloaded
);
cascade_gpu
->
detectMultiScale
(
resized_gpu
,
facesBuf_gpu
);
cascade_gpu
->
convert
(
facesBuf_gpu
,
faces
);
}
else
{
Size
minSize
=
cascade_gpu
.
getClassifierSize
();
cascade_cpu
.
detectMultiScale
(
resized_cpu
,
faces
Buf_cpu
,
1.2
,
Size
minSize
=
cascade_gpu
->
getClassifierSize
();
cascade_cpu
.
detectMultiScale
(
resized_cpu
,
faces
,
1.2
,
(
filterRects
||
findLargestObject
)
?
4
:
0
,
(
findLargestObject
?
CASCADE_FIND_BIGGEST_OBJECT
:
0
)
|
CASCADE_SCALE_IMAGE
,
minSize
);
detections_num
=
(
int
)
facesBuf_cpu
.
size
();
}
if
(
!
useGPU
&&
detections_num
)
{
for
(
int
i
=
0
;
i
<
detections_num
;
++
i
)
{
rectangle
(
resized_cpu
,
facesBuf_cpu
[
i
],
Scalar
(
255
));
}
}
if
(
useGPU
)
for
(
size_t
i
=
0
;
i
<
faces
.
size
();
++
i
)
{
resized_gpu
.
download
(
resized_cpu
);
for
(
int
i
=
0
;
i
<
detections_num
;
++
i
)
{
rectangle
(
resized_cpu
,
faces_downloaded
.
ptr
<
cv
::
Rect
>
()[
i
],
Scalar
(
255
));
}
rectangle
(
resized_cpu
,
faces
[
i
],
Scalar
(
255
));
}
tm
.
stop
();
...
...
@@ -283,16 +264,15 @@ int main(int argc, const char *argv[])
//print detections to console
cout
<<
setfill
(
' '
)
<<
setprecision
(
2
);
cout
<<
setw
(
6
)
<<
fixed
<<
fps
<<
" FPS, "
<<
detections_num
<<
" det"
;
if
((
filterRects
||
findLargestObject
)
&&
detections_num
>
0
)
cout
<<
setw
(
6
)
<<
fixed
<<
fps
<<
" FPS, "
<<
faces
.
size
()
<<
" det"
;
if
((
filterRects
||
findLargestObject
)
&&
!
faces
.
empty
()
)
{
Rect
*
faceRects
=
useGPU
?
faces_downloaded
.
ptr
<
Rect
>
()
:
&
facesBuf_cpu
[
0
];
for
(
int
i
=
0
;
i
<
min
(
detections_num
,
2
);
++
i
)
for
(
size_t
i
=
0
;
i
<
faces
.
size
();
++
i
)
{
cout
<<
", ["
<<
setw
(
4
)
<<
face
Rect
s
[
i
].
x
<<
", "
<<
setw
(
4
)
<<
face
Rect
s
[
i
].
y
<<
", "
<<
setw
(
4
)
<<
face
Rect
s
[
i
].
width
<<
", "
<<
setw
(
4
)
<<
face
Rect
s
[
i
].
height
<<
"]"
;
cout
<<
", ["
<<
setw
(
4
)
<<
faces
[
i
].
x
<<
", "
<<
setw
(
4
)
<<
faces
[
i
].
y
<<
", "
<<
setw
(
4
)
<<
faces
[
i
].
width
<<
", "
<<
setw
(
4
)
<<
faces
[
i
].
height
<<
"]"
;
}
}
cout
<<
endl
;
...
...
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