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
d8415ed4
Commit
d8415ed4
authored
Dec 09, 2010
by
Kirill Kornyakov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
code cleaning of cascade classifier
parent
33c44fcd
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
87 additions
and
77 deletions
+87
-77
objdetect.hpp
modules/objdetect/include/opencv2/objdetect/objdetect.hpp
+7
-7
cascadedetect.cpp
modules/objdetect/src/cascadedetect.cpp
+75
-65
haar.cpp
modules/objdetect/src/haar.cpp
+5
-5
No files found.
modules/objdetect/include/opencv2/objdetect/objdetect.hpp
View file @
d8415ed4
...
...
@@ -64,7 +64,7 @@ extern "C" {
typedef
struct
CvHaarFeature
{
int
tilted
;
int
tilted
;
struct
{
CvRect
r
;
...
...
@@ -328,16 +328,16 @@ public:
CV_WRAP
bool
load
(
const
string
&
filename
);
bool
read
(
const
FileNode
&
node
);
CV_WRAP
void
detectMultiScale
(
const
Mat
&
image
,
CV_OUT
vector
<
Rect
>&
objects
,
double
scaleFactor
=
1.1
,
int
minNeighbors
=
3
,
int
flags
=
0
,
Size
minSize
=
Size
(),
Size
maxSize
=
Size
());
CV_OUT
vector
<
Rect
>&
objects
,
double
scaleFactor
=
1.1
,
int
minNeighbors
=
3
,
int
flags
=
0
,
Size
minSize
=
Size
(),
Size
maxSize
=
Size
());
bool
setImage
(
Ptr
<
FeatureEvaluator
>&
,
const
Mat
&
);
int
runAt
(
Ptr
<
FeatureEvaluator
>&
,
Point
);
bool
is
_stump_b
ased
;
bool
is
StumpB
ased
;
int
stageType
;
int
featureType
;
...
...
modules/objdetect/src/cascadedetect.cpp
View file @
d8415ed4
...
...
@@ -717,26 +717,30 @@ inline int predictCategorical( CascadeClassifier& cascade, Ptr<FeatureEvaluator>
template
<
class
FEval
>
inline
int
predictOrderedStump
(
CascadeClassifier
&
cascade
,
Ptr
<
FeatureEvaluator
>
&
_feval
)
{
int
si
,
nstages
=
(
int
)
cascade
.
stages
.
size
();
int
nodeOfs
=
0
,
leafOfs
=
0
;
FEval
&
feval
=
(
FEval
&
)
*
_feval
;
float
*
cascadeLeaves
=
&
cascade
.
leaves
[
0
];
CascadeClassifier
::
DTreeNode
*
cascadeNodes
=
&
cascade
.
nodes
[
0
];
CascadeClassifier
::
Stage
*
cascadeStages
=
&
cascade
.
stages
[
0
];
for
(
si
=
0
;
si
<
nstages
;
si
++
)
int
nstages
=
(
int
)
cascade
.
stages
.
size
();
for
(
int
stageIdx
=
0
;
stageIdx
<
nstages
;
stageIdx
++
)
{
CascadeClassifier
::
Stage
&
stage
=
cascadeStages
[
si
];
int
wi
,
ntrees
=
stage
.
ntrees
;
double
sum
=
0
;
for
(
wi
=
0
;
wi
<
ntrees
;
wi
++
,
nodeOfs
++
,
leafOfs
+=
2
)
CascadeClassifier
::
Stage
&
stage
=
cascadeStages
[
stageIdx
];
double
sum
=
0.0
;
int
ntrees
=
stage
.
ntrees
;
for
(
int
i
=
0
;
i
<
ntrees
;
i
++
,
nodeOfs
++
,
leafOfs
+=
2
)
{
CascadeClassifier
::
DTreeNode
&
node
=
cascadeNodes
[
nodeOfs
];
double
val
=
feval
(
node
.
featureIdx
);
sum
+=
cascadeLeaves
[
val
<
node
.
threshold
?
leafOfs
:
leafOfs
+
1
];
double
val
ue
=
feval
(
node
.
featureIdx
);
sum
+=
cascadeLeaves
[
val
ue
<
node
.
threshold
?
leafOfs
:
leafOfs
+
1
];
}
if
(
sum
<
stage
.
threshold
)
return
-
s
i
;
return
-
s
tageIdx
;
}
return
1
;
}
...
...
@@ -773,7 +777,7 @@ inline int predictCategoricalStump( CascadeClassifier& cascade, Ptr<FeatureEvalu
return
1
;
}
int
CascadeClassifier
::
runAt
(
Ptr
<
FeatureEvaluator
>
&
_feval
,
Point
pt
)
int
CascadeClassifier
::
runAt
(
Ptr
<
FeatureEvaluator
>
&
featureEvaluator
,
Point
pt
)
{
CV_Assert
(
oldCascade
.
empty
()
);
/*if( !oldCascade.empty() )
...
...
@@ -781,17 +785,17 @@ int CascadeClassifier::runAt( Ptr<FeatureEvaluator> &_feval, Point pt )
assert
(
featureType
==
FeatureEvaluator
::
HAAR
||
featureType
==
FeatureEvaluator
::
LBP
);
return
!
_feval
->
setWindow
(
pt
)
?
-
1
:
is_stump_based
?
(
featureType
==
FeatureEvaluator
::
HAAR
?
predictOrderedStump
<
HaarEvaluator
>
(
*
this
,
_feval
)
:
predictCategoricalStump
<
LBPEvaluator
>
(
*
this
,
_feval
)
)
:
return
!
featureEvaluator
->
setWindow
(
pt
)
?
-
1
:
isStumpBased
?
(
featureType
==
FeatureEvaluator
::
HAAR
?
predictOrderedStump
<
HaarEvaluator
>
(
*
this
,
featureEvaluator
)
:
predictCategoricalStump
<
LBPEvaluator
>
(
*
this
,
featureEvaluator
)
)
:
(
featureType
==
FeatureEvaluator
::
HAAR
?
predictOrdered
<
HaarEvaluator
>
(
*
this
,
_feval
)
:
predictCategorical
<
LBPEvaluator
>
(
*
this
,
_feval
)
);
predictOrdered
<
HaarEvaluator
>
(
*
this
,
featureEvaluator
)
:
predictCategorical
<
LBPEvaluator
>
(
*
this
,
featureEvaluator
)
);
}
bool
CascadeClassifier
::
setImage
(
Ptr
<
FeatureEvaluator
>
&
_feval
,
const
Mat
&
image
)
bool
CascadeClassifier
::
setImage
(
Ptr
<
FeatureEvaluator
>
&
featureEvaluator
,
const
Mat
&
image
)
{
/*if( !oldCascade.empty() )
{
...
...
@@ -803,45 +807,48 @@ bool CascadeClassifier::setImage( Ptr<FeatureEvaluator> &_feval, const Mat& imag
cvSetImagesForHaarClassifierCascade( oldCascade, &_sum, &_sqsum, &_tilted, 1. );
return true;
}*/
return
empty
()
?
false
:
_feval
->
setImage
(
image
,
origWinSize
);
return
empty
()
?
false
:
featureEvaluator
->
setImage
(
image
,
origWinSize
);
}
struct
CascadeClassifierInvoker
{
CascadeClassifierInvoker
(
CascadeClassifier
&
_cc
,
Size
_sz1
,
int
_stripSize
,
int
_yStep
,
double
_factor
,
ConcurrentRectVector
&
_vec
)
{
c
c
=
&
_cc
;
sz1
=
_sz1
;
c
lassifier
=
&
_cc
;
processingAreaSize
=
_sz1
;
stripSize
=
_stripSize
;
yStep
=
_yStep
;
f
actor
=
_factor
;
vec
=
&
_vec
;
scalingF
actor
=
_factor
;
rectangles
=
&
_vec
;
}
void
operator
()(
const
BlockedRange
&
range
)
const
{
Ptr
<
FeatureEvaluator
>
feval
=
cc
->
feval
->
clone
();
int
y1
=
range
.
begin
()
*
stripSize
,
y2
=
min
(
range
.
end
()
*
stripSize
,
sz1
.
height
);
Size
winSize
(
cvRound
(
cc
->
origWinSize
.
width
*
factor
),
cvRound
(
cc
->
origWinSize
.
height
*
factor
));
Ptr
<
FeatureEvaluator
>
evaluator
=
classifier
->
feval
->
clone
();
Size
winSize
(
cvRound
(
classifier
->
origWinSize
.
width
*
scalingFactor
),
cvRound
(
classifier
->
origWinSize
.
height
*
scalingFactor
));
int
y1
=
range
.
begin
()
*
stripSize
;
int
y2
=
min
(
range
.
end
()
*
stripSize
,
processingAreaSize
.
height
);
for
(
int
y
=
y1
;
y
<
y2
;
y
+=
yStep
)
for
(
int
x
=
0
;
x
<
sz1
.
width
;
x
+=
yStep
)
{
for
(
int
x
=
0
;
x
<
processingAreaSize
.
width
;
x
+=
yStep
)
{
int
r
=
cc
->
runAt
(
feval
,
Point
(
x
,
y
));
if
(
r
>
0
)
vec
->
push_back
(
Rect
(
cvRound
(
x
*
factor
),
cvRound
(
y
*
f
actor
),
winSize
.
width
,
winSize
.
height
));
if
(
r
==
0
)
int
r
esult
=
classifier
->
runAt
(
evaluator
,
Point
(
x
,
y
));
if
(
r
esult
>
0
)
rectangles
->
push_back
(
Rect
(
cvRound
(
x
*
scalingFactor
),
cvRound
(
y
*
scalingF
actor
),
winSize
.
width
,
winSize
.
height
));
if
(
r
esult
==
0
)
x
+=
yStep
;
}
}
}
CascadeClassifier
*
cc
;
Size
sz1
;
CascadeClassifier
*
classifier
;
ConcurrentRectVector
*
rectangles
;
Size
processingAreaSize
;
int
stripSize
,
yStep
;
double
factor
;
ConcurrentRectVector
*
vec
;
double
scalingFactor
;
};
...
...
@@ -849,7 +856,7 @@ struct getRect { Rect operator ()(const CvAvgComp& e) const { return e.rect; } }
void
CascadeClassifier
::
detectMultiScale
(
const
Mat
&
image
,
vector
<
Rect
>&
objects
,
double
scaleFactor
,
int
minNeighbors
,
int
flags
,
Size
min
Size
,
Size
max
Size
)
int
flags
,
Size
min
ObjectSize
,
Size
maxObject
Size
)
{
const
double
GROUP_EPS
=
0.2
;
...
...
@@ -863,7 +870,7 @@ void CascadeClassifier::detectMultiScale( const Mat& image, vector<Rect>& object
MemStorage
storage
(
cvCreateMemStorage
(
0
));
CvMat
_image
=
image
;
CvSeq
*
_objects
=
cvHaarDetectObjects
(
&
_image
,
oldCascade
,
storage
,
scaleFactor
,
minNeighbors
,
flags
,
minSize
);
minNeighbors
,
flags
,
min
Object
Size
);
vector
<
CvAvgComp
>
vecAvgComp
;
Seq
<
CvAvgComp
>
(
_objects
).
copyTo
(
vecAvgComp
);
objects
.
resize
(
vecAvgComp
.
size
());
...
...
@@ -871,57 +878,60 @@ void CascadeClassifier::detectMultiScale( const Mat& image, vector<Rect>& object
return
;
}
if
(
maxSize
.
height
==
0
||
maxSize
.
width
==
0
)
maxSize
=
image
.
size
();
objects
.
clear
();
if
(
maxObjectSize
.
height
==
0
||
maxObjectSize
.
width
==
0
)
maxObjectSize
=
image
.
size
();
Mat
img
=
image
,
imgbuf
(
image
.
rows
+
1
,
image
.
cols
+
1
,
CV_8U
);
if
(
img
.
channels
()
>
1
)
Mat
grayImage
=
image
;
if
(
grayImage
.
channels
()
>
1
)
{
Mat
temp
;
cvtColor
(
img
,
temp
,
CV_BGR2GRAY
);
img
=
temp
;
cvtColor
(
grayImage
,
temp
,
CV_BGR2GRAY
);
grayImage
=
temp
;
}
ConcurrentRectVector
allCandidates
;
Mat
imageBuffer
(
image
.
rows
+
1
,
image
.
cols
+
1
,
CV_8U
);
ConcurrentRectVector
candidates
;
for
(
double
factor
=
1
;
;
factor
*=
scaleFactor
)
{
int
stripCount
,
stripSize
;
Size
winSize
(
cvRound
(
origWinSize
.
width
*
factor
),
cvRound
(
origWinSize
.
height
*
factor
)
);
Size
sz
(
cvRound
(
img
.
cols
/
factor
),
cvRound
(
img
.
rows
/
factor
)
);
Size
sz1
(
sz
.
width
-
origWinSize
.
width
,
sz
.
height
-
origWinSize
.
height
);
Size
windowSize
(
cvRound
(
origWinSize
.
width
*
factor
),
cvRound
(
origWinSize
.
height
*
factor
)
);
Size
scaledImageSize
(
cvRound
(
grayImage
.
cols
/
factor
),
cvRound
(
grayImage
.
rows
/
factor
)
);
Size
processingAreaSize
(
scaledImageSize
.
width
-
origWinSize
.
width
,
scaledImageSize
.
height
-
origWinSize
.
height
);
if
(
sz1
.
width
<=
0
||
sz1
.
height
<=
0
)
if
(
processingAreaSize
.
width
<=
0
||
processingAreaSize
.
height
<=
0
)
break
;
if
(
win
Size
.
width
>
maxSize
.
width
||
winSize
.
height
>
max
Size
.
height
)
if
(
win
dowSize
.
width
>
maxObjectSize
.
width
||
windowSize
.
height
>
maxObject
Size
.
height
)
break
;
if
(
win
Size
.
width
<
minSize
.
width
||
winSize
.
height
<
min
Size
.
height
)
if
(
win
dowSize
.
width
<
minObjectSize
.
width
||
windowSize
.
height
<
minObject
Size
.
height
)
continue
;
int
yStep
=
factor
>
2.
?
1
:
2
;
#ifdef HAVE_TBB
const
int
PTS_PER_THREAD
=
1000
;
stripCount
=
((
sz1
.
width
/
yStep
)
*
(
sz1
.
height
+
yStep
-
1
)
/
yStep
+
PTS_PER_THREAD
/
2
)
/
PTS_PER_THREAD
;
stripCount
=
((
processingAreaSize
.
width
/
yStep
)
*
(
processingAreaSize
.
height
+
yStep
-
1
)
/
yStep
+
PTS_PER_THREAD
/
2
)
/
PTS_PER_THREAD
;
stripCount
=
std
::
min
(
std
::
max
(
stripCount
,
1
),
100
);
stripSize
=
(((
sz1
.
height
+
stripCount
-
1
)
/
stripCount
+
yStep
-
1
)
/
yStep
)
*
yStep
;
stripSize
=
(((
processingAreaSize
.
height
+
stripCount
-
1
)
/
stripCount
+
yStep
-
1
)
/
yStep
)
*
yStep
;
#else
stripCount
=
1
;
stripSize
=
sz1
.
height
;
stripSize
=
processingAreaSize
.
height
;
#endif
Mat
img1
(
sz
,
CV_8U
,
imgbuf
.
data
);
resize
(
img
,
img1
,
sz
,
0
,
0
,
CV_INTER_LINEAR
);
if
(
!
feval
->
setImage
(
img1
,
origWinSize
)
)
Mat
scaledImage
(
scaledImageSize
,
CV_8U
,
imageBuffer
.
data
);
resize
(
grayImage
,
scaledImage
,
scaledImageSize
,
0
,
0
,
CV_INTER_LINEAR
);
if
(
!
feval
->
setImage
(
scaledImage
,
origWinSize
)
)
break
;
parallel_for
(
BlockedRange
(
0
,
stripCount
),
CascadeClassifierInvoker
(
*
this
,
sz1
,
stripSize
,
yStep
,
factor
,
allC
andidates
));
parallel_for
(
BlockedRange
(
0
,
stripCount
),
CascadeClassifierInvoker
(
*
this
,
processingAreaSize
,
stripSize
,
yStep
,
factor
,
c
andidates
));
}
objects
.
resize
(
allCandidates
.
size
());
std
::
copy
(
allCandidates
.
begin
(),
allCandidates
.
end
(),
objects
.
begin
());
objects
.
resize
(
candidates
.
size
());
std
::
copy
(
candidates
.
begin
(),
candidates
.
end
(),
objects
.
begin
());
groupRectangles
(
objects
,
minNeighbors
,
GROUP_EPS
);
}
...
...
@@ -947,7 +957,7 @@ bool CascadeClassifier::read(const FileNode& root)
origWinSize
.
height
=
(
int
)
root
[
CC_HEIGHT
];
CV_Assert
(
origWinSize
.
height
>
0
&&
origWinSize
.
width
>
0
);
is
_stump_b
ased
=
(
int
)(
root
[
CC_STAGE_PARAMS
][
CC_MAX_DEPTH
])
==
1
?
true
:
false
;
is
StumpB
ased
=
(
int
)(
root
[
CC_STAGE_PARAMS
][
CC_MAX_DEPTH
])
==
1
?
true
:
false
;
// load feature params
FileNode
fn
=
root
[
CC_FEATURE_PARAMS
];
...
...
modules/objdetect/src/haar.cpp
View file @
d8415ed4
...
...
@@ -112,7 +112,7 @@ CvHidHaarStageClassifier;
struct
CvHidHaarClassifierCascade
{
int
count
;
int
is
_stump_b
ased
;
int
is
StumpB
ased
;
int
has_tilted_features
;
int
is_tree
;
double
inv_window_area
;
...
...
@@ -272,7 +272,7 @@ icvCreateHidHaarClassifierCascade( CvHaarClassifierCascade* cascade )
haar_classifier_ptr
=
(
CvHidHaarClassifier
*
)(
out
->
stage_classifier
+
cascade
->
count
);
haar_node_ptr
=
(
CvHidHaarTreeNode
*
)(
haar_classifier_ptr
+
total_classifiers
);
out
->
is
_stump_b
ased
=
1
;
out
->
is
StumpB
ased
=
1
;
out
->
has_tilted_features
=
has_tilted_features
;
out
->
is_tree
=
0
;
...
...
@@ -329,12 +329,12 @@ icvCreateHidHaarClassifierCascade( CvHaarClassifierCascade* cascade )
haar_node_ptr
=
(
CvHidHaarTreeNode
*
)
cvAlignPtr
(
alpha_ptr
+
node_count
+
1
,
sizeof
(
void
*
));
out
->
is
_stump_b
ased
&=
node_count
==
1
;
out
->
is
StumpB
ased
&=
node_count
==
1
;
}
}
#ifdef HAVE_IPP
int
can_use_ipp
=
!
out
->
has_tilted_features
&&
!
out
->
is_tree
&&
out
->
is
_stump_b
ased
;
int
can_use_ipp
=
!
out
->
has_tilted_features
&&
!
out
->
is_tree
&&
out
->
is
StumpB
ased
;
if
(
can_use_ipp
)
{
...
...
@@ -719,7 +719,7 @@ cvRunHaarClassifierCascade( const CvHaarClassifierCascade* _cascade,
}
}
}
else
if
(
cascade
->
is
_stump_b
ased
)
else
if
(
cascade
->
is
StumpB
ased
)
{
for
(
i
=
start_stage
;
i
<
cascade
->
count
;
i
++
)
{
...
...
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