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
9ec4c202
Commit
9ec4c202
authored
Dec 25, 2013
by
Andrey Pavlenko
Committed by
OpenCV Buildbot
Dec 25, 2013
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #2042 from vpisarev:ocl_facedetect8
parents
faddd5b9
bc730292
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
221 additions
and
137 deletions
+221
-137
perf_cascadeclassifier.cpp
modules/objdetect/perf/perf_cascadeclassifier.cpp
+6
-0
cascadedetect.cpp
modules/objdetect/src/cascadedetect.cpp
+125
-50
cascadedetect.hpp
modules/objdetect/src/cascadedetect.hpp
+44
-35
cascadedetect.cl
modules/objdetect/src/opencl/cascadedetect.cl
+46
-52
No files found.
modules/objdetect/perf/perf_cascadeclassifier.cpp
View file @
9ec4c202
...
...
@@ -44,6 +44,12 @@ PERF_TEST_P(ImageName_MinSize, CascadeClassifierLBPFrontalFace,
cc
.
detectMultiScale
(
img
,
faces
,
1.1
,
3
,
0
,
minSize
);
stopTimer
();
}
// for some reason OpenCL version detects the face, which CPU version does not detect, we just remove it
// TODO better solution: implement smart way of comparing two set of rectangles
if
(
filename
==
"cv/shared/1_itseez-0000492.png"
&&
faces
.
size
()
==
(
size_t
)
3
)
{
faces
.
erase
(
faces
.
begin
());
}
std
::
sort
(
faces
.
begin
(),
faces
.
end
(),
comparators
::
RectLess
());
SANITY_CHECK
(
faces
,
3.001
*
faces
.
size
());
...
...
modules/objdetect/src/cascadedetect.cpp
View file @
9ec4c202
...
...
@@ -654,6 +654,7 @@ bool LBPEvaluator::Feature :: read(const FileNode& node )
LBPEvaluator
::
LBPEvaluator
()
{
features
=
makePtr
<
std
::
vector
<
Feature
>
>
();
optfeatures
=
makePtr
<
std
::
vector
<
OptFeature
>
>
();
}
LBPEvaluator
::~
LBPEvaluator
()
{
...
...
@@ -662,11 +663,12 @@ LBPEvaluator::~LBPEvaluator()
bool
LBPEvaluator
::
read
(
const
FileNode
&
node
)
{
features
->
resize
(
node
.
size
());
featuresPtr
=
&
(
*
features
)[
0
];
optfeaturesPtr
=
&
(
*
opt
features
)[
0
];
FileNodeIterator
it
=
node
.
begin
(),
it_end
=
node
.
end
();
std
::
vector
<
Feature
>&
ff
=
*
features
;
for
(
int
i
=
0
;
it
!=
it_end
;
++
it
,
i
++
)
{
if
(
!
f
eaturesPtr
[
i
].
read
(
*
it
))
if
(
!
f
f
[
i
].
read
(
*
it
))
return
false
;
}
return
true
;
...
...
@@ -677,31 +679,58 @@ Ptr<FeatureEvaluator> LBPEvaluator::clone() const
Ptr
<
LBPEvaluator
>
ret
=
makePtr
<
LBPEvaluator
>
();
ret
->
origWinSize
=
origWinSize
;
ret
->
features
=
features
;
ret
->
featuresPtr
=
&
(
*
ret
->
features
)[
0
];
ret
->
optfeatures
=
optfeatures
;
ret
->
optfeaturesPtr
=
ret
->
optfeatures
.
empty
()
?
0
:
&
(
*
ret
->
optfeatures
)[
0
];
ret
->
sum0
=
sum0
,
ret
->
sum
=
sum
;
ret
->
normrect
=
normrect
;
ret
->
offset
=
offset
;
ret
->
pwin
=
pwin
;
return
ret
;
}
bool
LBPEvaluator
::
setImage
(
InputArray
_image
,
Size
_origWinSize
,
Size
)
bool
LBPEvaluator
::
setImage
(
InputArray
_image
,
Size
_origWinSize
,
Size
_sumSize
)
{
Mat
image
=
_image
.
getMat
();
int
rn
=
image
.
rows
+
1
,
cn
=
image
.
cols
+
1
;
origWinSize
=
_origWinSize
;
Size
imgsz
=
_image
.
size
();
int
cols
=
imgsz
.
width
,
rows
=
imgsz
.
height
;
if
(
image
.
cols
<
origWinSize
.
width
||
image
.
rows
<
origWinSize
.
height
)
if
(
imgsz
.
width
<
origWinSize
.
width
||
imgsz
.
height
<
origWinSize
.
height
)
return
false
;
if
(
sum0
.
rows
<
rn
||
sum0
.
cols
<
cn
)
origWinSize
=
_origWinSize
;
int
rn
=
_sumSize
.
height
,
cn
=
_sumSize
.
width
;
int
sumStep
;
CV_Assert
(
rn
>=
rows
+
1
&&
cn
>=
cols
+
1
);
if
(
_image
.
isUMat
()
)
{
usum0
.
create
(
rn
,
cn
,
CV_32S
);
usum
=
UMat
(
usum0
,
Rect
(
0
,
0
,
cols
+
1
,
rows
+
1
));
integral
(
_image
,
usum
,
noArray
(),
noArray
(),
CV_32S
);
sumStep
=
(
int
)(
usum
.
step
/
usum
.
elemSize
());
}
else
{
sum0
.
create
(
rn
,
cn
,
CV_32S
);
sum
=
Mat
(
rn
,
cn
,
CV_32S
,
sum0
.
data
);
integral
(
image
,
sum
);
sum
=
sum0
(
Rect
(
0
,
0
,
cols
+
1
,
rows
+
1
));
integral
(
_image
,
sum
,
noArray
(),
noArray
(),
CV_32S
);
sumStep
=
(
int
)(
sum
.
step
/
sum
.
elemSize
());
}
size_t
fi
,
nfeatures
=
features
->
size
();
const
std
::
vector
<
Feature
>&
ff
=
*
features
;
if
(
sumSize0
!=
_sumSize
)
{
optfeatures
->
resize
(
nfeatures
);
optfeaturesPtr
=
&
(
*
optfeatures
)[
0
];
for
(
fi
=
0
;
fi
<
nfeatures
;
fi
++
)
optfeaturesPtr
[
fi
].
setOffsets
(
ff
[
fi
],
sumStep
);
}
if
(
_image
.
isUMat
()
&&
(
sumSize0
!=
_sumSize
||
ufbuf
.
empty
())
)
copyVectorToUMat
(
*
optfeatures
,
ufbuf
);
sumSize0
=
_sumSize
;
for
(
fi
=
0
;
fi
<
nfeatures
;
fi
++
)
featuresPtr
[
fi
].
updatePtrs
(
sum
);
return
true
;
}
...
...
@@ -711,10 +740,18 @@ bool LBPEvaluator::setWindow( Point pt )
pt
.
x
+
origWinSize
.
width
>=
sum
.
cols
||
pt
.
y
+
origWinSize
.
height
>=
sum
.
rows
)
return
false
;
offset
=
pt
.
y
*
((
int
)
sum
.
step
/
sizeof
(
int
))
+
pt
.
x
;
pwin
=
&
sum
.
at
<
int
>
(
pt
)
;
return
true
;
}
void
LBPEvaluator
::
getUMats
(
std
::
vector
<
UMat
>&
bufs
)
{
bufs
.
clear
();
bufs
.
push_back
(
usum
);
bufs
.
push_back
(
ufbuf
);
}
//---------------------------------------------- HOGEvaluator ---------------------------------------
bool
HOGEvaluator
::
Feature
::
read
(
const
FileNode
&
node
)
{
...
...
@@ -1133,50 +1170,84 @@ bool CascadeClassifierImpl::detectSingleScale( InputArray _image, Size processin
bool
CascadeClassifierImpl
::
ocl_detectSingleScale
(
InputArray
_image
,
Size
processingRectSize
,
int
yStep
,
double
factor
,
Size
sumSize0
)
{
const
int
VECTOR_SIZE
=
1
;
Ptr
<
HaarEvaluator
>
haar
=
featureEvaluator
.
dynamicCast
<
HaarEvaluator
>
();
if
(
haar
.
empty
()
)
return
false
;
haar
->
setImage
(
_image
,
data
.
origWinSize
,
sumSize0
);
if
(
cascadeKernel
.
empty
()
)
{
cascadeKernel
.
create
(
"runHaarClassifierStump"
,
ocl
::
objdetect
::
cascadedetect_oclsrc
,
format
(
"-D VECTOR_SIZE=%d"
,
VECTOR_SIZE
));
if
(
cascadeKernel
.
empty
()
)
return
false
;
}
int
featureType
=
getFeatureType
();
std
::
vector
<
UMat
>
bufs
;
size_t
globalsize
[]
=
{
processingRectSize
.
width
/
yStep
,
processingRectSize
.
height
/
yStep
};
bool
ok
=
false
;
if
(
ustages
.
empty
()
)
{
copyVectorToUMat
(
data
.
stages
,
ustages
);
copyVectorToUMat
(
data
.
stumps
,
ustumps
);
if
(
!
data
.
subsets
.
empty
()
)
copyVectorToUMat
(
data
.
subsets
,
usubsets
);
}
std
::
vector
<
UMat
>
bufs
;
haar
->
getUMats
(
bufs
);
CV_Assert
(
bufs
.
size
()
==
3
);
if
(
featureType
==
FeatureEvaluator
::
HAAR
)
{
Ptr
<
HaarEvaluator
>
haar
=
featureEvaluator
.
dynamicCast
<
HaarEvaluator
>
();
if
(
haar
.
empty
()
)
return
false
;
haar
->
setImage
(
_image
,
data
.
origWinSize
,
sumSize0
);
if
(
haarKernel
.
empty
()
)
{
haarKernel
.
create
(
"runHaarClassifierStump"
,
ocl
::
objdetect
::
cascadedetect_oclsrc
,
""
);
if
(
haarKernel
.
empty
()
)
return
false
;
}
haar
->
getUMats
(
bufs
);
Rect
normrect
=
haar
->
getNormRect
();
haarKernel
.
args
(
ocl
::
KernelArg
::
ReadOnlyNoSize
(
bufs
[
0
]),
// sum
ocl
::
KernelArg
::
ReadOnlyNoSize
(
bufs
[
1
]),
// sqsum
ocl
::
KernelArg
::
PtrReadOnly
(
bufs
[
2
]),
// optfeatures
Rect
normrect
=
haar
->
getNormRect
();
// cascade classifier
(
int
)
data
.
stages
.
size
(),
ocl
::
KernelArg
::
PtrReadOnly
(
ustages
),
ocl
::
KernelArg
::
PtrReadOnly
(
ustumps
),
//processingRectSize = Size(yStep, yStep);
size_t
globalsize
[]
=
{
(
processingRectSize
.
width
/
yStep
+
VECTOR_SIZE
-
1
)
/
VECTOR_SIZE
,
processingRectSize
.
height
/
yStep
};
ocl
::
KernelArg
::
PtrWriteOnly
(
ufacepos
),
// positions
processingRectSize
,
yStep
,
(
float
)
factor
,
normrect
,
data
.
origWinSize
,
MAX_FACES
);
ok
=
haarKernel
.
run
(
2
,
globalsize
,
0
,
true
);
}
else
if
(
featureType
==
FeatureEvaluator
::
LBP
)
{
Ptr
<
LBPEvaluator
>
lbp
=
featureEvaluator
.
dynamicCast
<
LBPEvaluator
>
();
if
(
lbp
.
empty
()
)
return
false
;
cascadeKernel
.
args
(
ocl
::
KernelArg
::
ReadOnlyNoSize
(
bufs
[
0
]),
// sum
ocl
::
KernelArg
::
ReadOnlyNoSize
(
bufs
[
1
]),
// sqsum
ocl
::
KernelArg
::
PtrReadOnly
(
bufs
[
2
]),
// optfeatures
lbp
->
setImage
(
_image
,
data
.
origWinSize
,
sumSize0
);
if
(
lbpKernel
.
empty
()
)
{
lbpKernel
.
create
(
"runLBPClassifierStump"
,
ocl
::
objdetect
::
cascadedetect_oclsrc
,
""
);
if
(
lbpKernel
.
empty
()
)
return
false
;
}
lbp
->
getUMats
(
bufs
);
// cascade classifier
(
int
)
data
.
stages
.
size
(),
ocl
::
KernelArg
::
PtrReadOnly
(
ustages
),
ocl
::
KernelArg
::
PtrReadOnly
(
ustumps
),
int
subsetSize
=
(
data
.
ncategories
+
31
)
/
32
;
lbpKernel
.
args
(
ocl
::
KernelArg
::
ReadOnlyNoSize
(
bufs
[
0
]),
// sum
ocl
::
KernelArg
::
PtrReadOnly
(
bufs
[
1
]),
// optfeatures
ocl
::
KernelArg
::
PtrWriteOnly
(
ufacepos
),
// positions
processingRectSize
,
yStep
,
(
float
)
factor
,
normrect
,
data
.
origWinSize
,
MAX_FACES
);
bool
ok
=
cascadeKernel
.
run
(
2
,
globalsize
,
0
,
true
);
// cascade classifier
(
int
)
data
.
stages
.
size
(),
ocl
::
KernelArg
::
PtrReadOnly
(
ustages
),
ocl
::
KernelArg
::
PtrReadOnly
(
ustumps
),
ocl
::
KernelArg
::
PtrReadOnly
(
usubsets
),
subsetSize
,
ocl
::
KernelArg
::
PtrWriteOnly
(
ufacepos
),
// positions
processingRectSize
,
yStep
,
(
float
)
factor
,
data
.
origWinSize
,
MAX_FACES
);
ok
=
lbpKernel
.
run
(
2
,
globalsize
,
0
,
true
);
}
//CV_Assert(ok);
return
ok
;
}
...
...
@@ -1225,6 +1296,7 @@ void CascadeClassifierImpl::detectMultiScaleNoGrouping( InputArray _image, std::
double
scaleFactor
,
Size
minObjectSize
,
Size
maxObjectSize
,
bool
outputRejectLevels
)
{
int
featureType
=
getFeatureType
();
Size
imgsz
=
_image
.
size
();
int
imgtype
=
_image
.
type
();
...
...
@@ -1238,7 +1310,9 @@ void CascadeClassifierImpl::detectMultiScaleNoGrouping( InputArray _image, std::
maxObjectSize
=
imgsz
;
bool
use_ocl
=
ocl
::
useOpenCL
()
&&
getFeatureType
()
==
FeatureEvaluator
::
HAAR
&&
(
featureType
==
FeatureEvaluator
::
HAAR
||
featureType
==
FeatureEvaluator
::
LBP
)
&&
ocl
::
Device
::
getDefault
().
type
()
!=
ocl
::
Device
::
TYPE_CPU
&&
!
isOldFormatCascade
()
&&
data
.
isStumpBased
()
&&
maskGenerator
.
empty
()
&&
...
...
@@ -1564,7 +1638,8 @@ bool CascadeClassifierImpl::Data::read(const FileNode &root)
bool
CascadeClassifierImpl
::
read_
(
const
FileNode
&
root
)
{
tryOpenCL
=
true
;
cascadeKernel
=
ocl
::
Kernel
();
haarKernel
=
ocl
::
Kernel
();
lbpKernel
=
ocl
::
Kernel
();
ustages
.
release
();
ustumps
.
release
();
if
(
!
data
.
read
(
root
)
)
...
...
modules/objdetect/src/cascadedetect.hpp
View file @
9ec4c202
...
...
@@ -149,7 +149,7 @@ protected:
Ptr
<
MaskGenerator
>
maskGenerator
;
UMat
ugrayImage
,
uimageBuffer
;
UMat
ufacepos
,
ustages
,
ustumps
,
usubsets
;
ocl
::
Kernel
cascade
Kernel
;
ocl
::
Kernel
haarKernel
,
lbp
Kernel
;
bool
tryOpenCL
;
Mutex
mtx
;
...
...
@@ -250,13 +250,11 @@ public:
struct
Feature
{
Feature
();
bool
read
(
const
FileNode
&
node
);
bool
tilted
;
enum
{
RECT_NUM
=
3
};
struct
{
Rect
r
;
...
...
@@ -369,14 +367,20 @@ public:
{
Feature
();
Feature
(
int
x
,
int
y
,
int
_block_w
,
int
_block_h
)
:
rect
(
x
,
y
,
_block_w
,
_block_h
)
{}
rect
(
x
,
y
,
_block_w
,
_block_h
)
{}
int
calc
(
int
offset
)
const
;
void
updatePtrs
(
const
Mat
&
sum
);
bool
read
(
const
FileNode
&
node
);
Rect
rect
;
// weight and height for block
const
int
*
p
[
16
];
// fast
};
struct
OptFeature
{
OptFeature
();
int
calc
(
const
int
*
pwin
)
const
;
void
setOffsets
(
const
Feature
&
_f
,
int
step
);
int
ofs
[
16
];
};
LBPEvaluator
();
...
...
@@ -388,55 +392,60 @@ public:
virtual
bool
setImage
(
InputArray
image
,
Size
_origWinSize
,
Size
);
virtual
bool
setWindow
(
Point
pt
);
virtual
void
getUMats
(
std
::
vector
<
UMat
>&
bufs
);
int
operator
()(
int
featureIdx
)
const
{
return
featuresPtr
[
featureIdx
].
calc
(
offset
);
}
{
return
optfeaturesPtr
[
featureIdx
].
calc
(
pwin
);
}
virtual
int
calcCat
(
int
featureIdx
)
const
{
return
(
*
this
)(
featureIdx
);
}
protected
:
Size
origWinSize
;
Size
origWinSize
,
sumSize0
;
Ptr
<
std
::
vector
<
Feature
>
>
features
;
Feature
*
featuresPtr
;
// optimization
Ptr
<
std
::
vector
<
OptFeature
>
>
optfeatures
;
OptFeature
*
optfeaturesPtr
;
// optimization
Mat
sum0
,
sum
;
Rect
normrect
;
UMat
usum0
,
usum
,
ufbuf
;
int
offset
;
const
int
*
pwin
;
};
inline
LBPEvaluator
::
Feature
::
Feature
()
{
rect
=
Rect
();
}
inline
LBPEvaluator
::
OptFeature
::
OptFeature
()
{
for
(
int
i
=
0
;
i
<
16
;
i
++
)
p
[
i
]
=
0
;
ofs
[
i
]
=
0
;
}
inline
int
LBPEvaluator
::
Feature
::
calc
(
int
_offset
)
const
inline
int
LBPEvaluator
::
OptFeature
::
calc
(
const
int
*
p
)
const
{
int
cval
=
CALC_SUM_
(
p
[
5
],
p
[
6
],
p
[
9
],
p
[
10
],
_offset
);
return
(
CALC_SUM_
(
p
[
0
],
p
[
1
],
p
[
4
],
p
[
5
],
_offset
)
>=
cval
?
128
:
0
)
|
// 0
(
CALC_SUM_
(
p
[
1
],
p
[
2
],
p
[
5
],
p
[
6
],
_offset
)
>=
cval
?
64
:
0
)
|
// 1
(
CALC_SUM_
(
p
[
2
],
p
[
3
],
p
[
6
],
p
[
7
],
_offset
)
>=
cval
?
32
:
0
)
|
// 2
(
CALC_SUM_
(
p
[
6
],
p
[
7
],
p
[
10
],
p
[
11
],
_offset
)
>=
cval
?
16
:
0
)
|
// 5
(
CALC_SUM_
(
p
[
10
],
p
[
11
],
p
[
14
],
p
[
15
],
_offset
)
>=
cval
?
8
:
0
)
|
// 8
(
CALC_SUM_
(
p
[
9
],
p
[
10
],
p
[
13
],
p
[
14
],
_offset
)
>=
cval
?
4
:
0
)
|
// 7
(
CALC_SUM_
(
p
[
8
],
p
[
9
],
p
[
12
],
p
[
13
],
_offset
)
>=
cval
?
2
:
0
)
|
// 6
(
CALC_SUM_
(
p
[
4
],
p
[
5
],
p
[
8
],
p
[
9
],
_offset
)
>=
cval
?
1
:
0
);
int
cval
=
CALC_SUM_
OFS_
(
ofs
[
5
],
ofs
[
6
],
ofs
[
9
],
ofs
[
10
],
p
);
return
(
CALC_SUM_
OFS_
(
ofs
[
0
],
ofs
[
1
],
ofs
[
4
],
ofs
[
5
],
p
)
>=
cval
?
128
:
0
)
|
// 0
(
CALC_SUM_
OFS_
(
ofs
[
1
],
ofs
[
2
],
ofs
[
5
],
ofs
[
6
],
p
)
>=
cval
?
64
:
0
)
|
// 1
(
CALC_SUM_
OFS_
(
ofs
[
2
],
ofs
[
3
],
ofs
[
6
],
ofs
[
7
],
p
)
>=
cval
?
32
:
0
)
|
// 2
(
CALC_SUM_
OFS_
(
ofs
[
6
],
ofs
[
7
],
ofs
[
10
],
ofs
[
11
],
p
)
>=
cval
?
16
:
0
)
|
// 5
(
CALC_SUM_
OFS_
(
ofs
[
10
],
ofs
[
11
],
ofs
[
14
],
ofs
[
15
],
p
)
>=
cval
?
8
:
0
)
|
// 8
(
CALC_SUM_
OFS_
(
ofs
[
9
],
ofs
[
10
],
ofs
[
13
],
ofs
[
14
],
p
)
>=
cval
?
4
:
0
)
|
// 7
(
CALC_SUM_
OFS_
(
ofs
[
8
],
ofs
[
9
],
ofs
[
12
],
ofs
[
13
],
p
)
>=
cval
?
2
:
0
)
|
// 6
(
CALC_SUM_
OFS_
(
ofs
[
4
],
ofs
[
5
],
ofs
[
8
],
ofs
[
9
],
p
)
>=
cval
?
1
:
0
);
}
inline
void
LBPEvaluator
::
Feature
::
updatePtrs
(
const
Mat
&
_sum
)
inline
void
LBPEvaluator
::
OptFeature
::
setOffsets
(
const
Feature
&
_f
,
int
step
)
{
const
int
*
ptr
=
(
const
int
*
)
_sum
.
data
;
size_t
step
=
_sum
.
step
/
sizeof
(
ptr
[
0
]);
Rect
tr
=
rect
;
CV_SUM_PTRS
(
p
[
0
],
p
[
1
],
p
[
4
],
p
[
5
],
ptr
,
tr
,
step
);
tr
.
x
+=
2
*
rect
.
width
;
CV_SUM_PTRS
(
p
[
2
],
p
[
3
],
p
[
6
],
p
[
7
],
ptr
,
tr
,
step
);
tr
.
y
+=
2
*
rect
.
height
;
CV_SUM_PTRS
(
p
[
10
],
p
[
11
],
p
[
14
],
p
[
15
],
ptr
,
tr
,
step
);
tr
.
x
-=
2
*
rect
.
width
;
CV_SUM_PTRS
(
p
[
8
],
p
[
9
],
p
[
12
],
p
[
13
],
ptr
,
tr
,
step
);
Rect
tr
=
_f
.
rect
;
CV_SUM_OFS
(
ofs
[
0
],
ofs
[
1
],
ofs
[
4
],
ofs
[
5
],
0
,
tr
,
step
);
tr
.
x
+=
2
*
_f
.
rect
.
width
;
CV_SUM_OFS
(
ofs
[
2
],
ofs
[
3
],
ofs
[
6
],
ofs
[
7
],
0
,
tr
,
step
);
tr
.
y
+=
2
*
_f
.
rect
.
height
;
CV_SUM_OFS
(
ofs
[
10
],
ofs
[
11
],
ofs
[
14
],
ofs
[
15
],
0
,
tr
,
step
);
tr
.
x
-=
2
*
_f
.
rect
.
width
;
CV_SUM_OFS
(
ofs
[
8
],
ofs
[
9
],
ofs
[
12
],
ofs
[
13
],
0
,
tr
,
step
);
}
//---------------------------------------------- HOGEvaluator -------------------------------------------
...
...
modules/objdetect/src/opencl/cascadedetect.cl
View file @
9ec4c202
/////////////////////////////
OpenCL
kernels
for
face
detection
//////////////////////////////
//////////////////////////////
see
the
opencv/doc/license.txt
///////////////////////////////
typedef
struct
__attribute__
((
aligned
(
4
)))
OptFeature
typedef
struct
__attribute__
((
aligned
(
4
)))
Opt
Haar
Feature
{
int4
ofs[3]
__attribute__
((
aligned
(
4
)))
;
float4
weight
__attribute__
((
aligned
(
4
)))
;
}
OptFeature
;
OptHaarFeature
;
typedef
struct
__attribute__
((
aligned
(
4
)))
OptLBPFeature
{
int16
ofs
__attribute__
((
aligned
(
4
)))
;
}
OptLBPFeature
;
typedef
struct
__attribute__
((
aligned
(
4
)))
Stump
{
int
featureIdx
__attribute__
((
aligned
(
4
)))
;
float
threshold
__attribute__
((
aligned
(
4
)))
; // for ordered features only
float
left
__attribute__
((
aligned
(
4
)))
;
float
right
__attribute__
((
aligned
(
4
)))
;
float4
st
__attribute__
((
aligned
(
4
)))
;
}
Stump
;
...
...
@@ -30,7 +33,7 @@ __kernel void runHaarClassifierStump(
int
sumstep,
int
sumoffset,
__global
const
int*
sqsum,
int
sqsumstep,
int
sqsumoffset,
__global
const
OptFeature*
optfeatures,
__global
const
Opt
Haar
Feature*
optfeatures,
int
nstages,
__global
const
Stage*
stages,
...
...
@@ -47,11 +50,8 @@ __kernel void runHaarClassifierStump(
if
(
ix
<
imgsize.x
&&
iy
<
imgsize.y
)
{
int
ntrees
;
int
stageIdx,
i
;
float
s
=
0.f
;
int
stageIdx
;
__global
const
Stump*
stump
=
stumps
;
__global
const
OptFeature*
f
;
__global
const
int*
psum
=
sum
+
mad24
(
iy,
sumstep,
ix
)
;
__global
const
int*
pnsum
=
psum
+
mad24
(
normrect.y,
sumstep,
normrect.x
)
;
...
...
@@ -61,20 +61,19 @@ __kernel void runHaarClassifierStump(
pnsum[mad24
(
normrect.w,
sumstep,
normrect.z
)
]
)
*invarea
;
float
sqval
=
(
sqsum[mad24
(
iy
+
normrect.y,
sqsumstep,
ix
+
normrect.x
)
]
)
*invarea
;
float
nf
=
(
float
)
normarea
*
sqrt
(
max
(
sqval
-
sval
*
sval,
0.f
))
;
float4
weight,
vsval
;
int4
ofs,
ofs0,
ofs1,
ofs2
;
nf
=
nf
>
0
?
nf
:
1.f
;
for
(
stageIdx
=
0
; stageIdx < nstages; stageIdx++ )
{
ntrees
=
stages[stageIdx].ntrees
;
s
=
0.f
;
int
i,
ntrees
=
stages[stageIdx].ntrees
;
float
s
=
0.f
;
for
(
i
=
0
; i < ntrees; i++, stump++ )
{
f
=
optfeatures
+
stump->featureIdx
;
weight
=
f->weight
;
float4
st
=
stump->st
;
__global
const
OptHaarFeature*
f
=
optfeatures
+
as_int
(
st.x
)
;
float4
weight
=
f->weight
;
ofs
=
f->ofs[0]
;
int4
ofs
=
f->ofs[0]
;
sval
=
(
psum[ofs.x]
-
psum[ofs.y]
-
psum[ofs.z]
+
psum[ofs.w]
)
*weight.x
;
ofs
=
f->ofs[1]
;
sval
+=
(
psum[ofs.x]
-
psum[ofs.y]
-
psum[ofs.z]
+
psum[ofs.w]
)
*weight.y
;
...
...
@@ -84,7 +83,7 @@ __kernel void runHaarClassifierStump(
sval
+=
(
psum[ofs.x]
-
psum[ofs.y]
-
psum[ofs.z]
+
psum[ofs.w]
)
*weight.z
;
}
s
+=
(
sval
<
st
ump->threshold*nf
)
?
stump->left
:
stump->right
;
s
+=
(
sval
<
st
.y*nf
)
?
st.z
:
st.w
;
}
if
(
s
<
stages[stageIdx].threshold
)
...
...
@@ -106,13 +105,11 @@ __kernel void runHaarClassifierStump(
}
}
#
if
0
__kernel
void
runLBPClassifierStump
(
__global
const
int*
sum,
int
sumstep,
int
sumoffset,
__global
const
int*
sqsum,
int
sqsumstep,
int
sqsumoffset,
__global
const
OptFeature*
optfeatures,
__global
const
OptLBPFeature*
optfeatures,
int
nstages,
__global
const
Stage*
stages,
...
...
@@ -122,50 +119,48 @@ __kernel void runLBPClassifierStump(
volatile
__global
int*
facepos,
int2
imgsize,
int
xyscale,
float
factor,
int
4
normrect,
int
2
windowsize,
int
maxFaces
)
int2
windowsize,
int
maxFaces
)
{
int
ix
=
get_global_id
(
0
)
*xyscale
*
VECTOR_SIZE
;
int
ix
=
get_global_id
(
0
)
*xyscale
;
int
iy
=
get_global_id
(
1
)
*xyscale
;
sumstep
/=
sizeof
(
int
)
;
sqsumstep
/=
sizeof
(
int
)
;
if
(
ix
<
imgsize.x
&&
iy
<
imgsize.y
)
{
int
ntrees
;
int
stageIdx,
i
;
float
s
=
0.f
;
int
stageIdx
;
__global
const
Stump*
stump
=
stumps
;
__global
const
int*
bitset
=
bitsets
;
__global
const
OptFeature*
f
;
__global
const
int*
psum
=
sum
+
mad24
(
iy,
sumstep,
ix
)
;
__global
const
int*
pnsum
=
psum
+
mad24
(
normrect.y,
sumstep,
normrect.x
)
;
int
normarea
=
normrect.z
*
normrect.w
;
float
invarea
=
1.f/normarea
;
float
sval
=
(
pnsum[0]
-
pnsum[normrect.z]
-
pnsum[mul24
(
normrect.w,
sumstep
)
]
+
pnsum[mad24
(
normrect.w,
sumstep,
normrect.z
)
]
)
*invarea
;
float
sqval
=
(
sqsum[mad24
(
iy
+
normrect.y,
sqsumstep,
ix
+
normrect.x
)
]
)
*invarea
;
float
nf
=
(
float
)
normarea
*
sqrt
(
max
(
sqval
-
sval
*
sval,
0.f
))
;
float4
weight
;
int4
ofs
;
nf
=
nf
>
0
?
nf
:
1.f
;
__global
const
int*
p
=
sum
+
mad24
(
iy,
sumstep,
ix
)
;
for
(
stageIdx
=
0
; stageIdx < nstages; stageIdx++ )
{
ntrees
=
stages[stageIdx].ntrees
;
s
=
0.f
;
for
(
i
=
0
; i < ntrees; i++, stump++, bitset += bitsetSize )
int
i,
ntrees
=
stages[stageIdx].ntrees
;
float
s
=
0.f
;
for
(
i
=
0
; i < ntrees; i++, stump++, bitset
s
+= bitsetSize )
{
f
=
optfeatures
+
stump->featureIdx
;
float4
st
=
stump->st
;
__global
const
OptLBPFeature*
f
=
optfeatures
+
as_int
(
st.x
)
;
int16
ofs
=
f->ofs
;
#
define
CALC_SUM_OFS_
(
p0,
p1,
p2,
p3,
ptr
)
\
((
ptr
)
[p0]
-
(
ptr
)
[p1]
-
(
ptr
)
[p2]
+
(
ptr
)
[p3]
)
int
cval
=
CALC_SUM_OFS_
(
ofs.s5,
ofs.s6,
ofs.s9,
ofs.sa,
p
)
;
weight
=
f->weight
;
int
mask,
idx
=
(
CALC_SUM_OFS_
(
ofs.s0,
ofs.s1,
ofs.s4,
ofs.s5,
p
)
>=
cval
?
4
:
0
)
; // 0
idx
|= (CALC_SUM_OFS_( ofs.s1, ofs.s2, ofs.s5, ofs.s6, p ) >= cval ? 2 : 0); // 1
idx |
=
(
CALC_SUM_OFS_
(
ofs.s2,
ofs.s3,
ofs.s6,
ofs.s7,
p
)
>=
cval
?
1
:
0
)
; // 2
//
compute
LBP
feature
to
val
s
+=
(
bitset[val
>>
5]
&
(
1
<<
(
val
&
31
)))
?
stump->left
:
stump->right
;
mask
=
(
CALC_SUM_OFS_
(
ofs.s6,
ofs.s7,
ofs.sa,
ofs.sb,
p
)
>=
cval
?
16
:
0
)
; // 5
mask
|= (CALC_SUM_OFS_( ofs.sa, ofs.sb, ofs.se, ofs.sf, p ) >= cval ? 8 : 0); // 8
mask |
=
(
CALC_SUM_OFS_
(
ofs.s9,
ofs.sa,
ofs.sd,
ofs.se,
p
)
>=
cval
?
4
:
0
)
; // 7
mask
|= (CALC_SUM_OFS_( ofs.s8, ofs.s9, ofs.sc, ofs.sd, p ) >= cval ? 2 : 0); // 6
mask |
=
(
CALC_SUM_OFS_
(
ofs.s4,
ofs.s5,
ofs.s8,
ofs.s9,
p
)
>=
cval
?
1
:
0
)
; // 7
s
+=
(
bitsets[idx]
&
(
1
<<
mask
))
?
st.z
:
st.w
;
}
if
(
s
<
stages[stageIdx].threshold
)
break
;
break
;
}
if
(
stageIdx
==
nstages
)
...
...
@@ -182,4 +177,3 @@ __kernel void runLBPClassifierStump(
}
}
}
#
endif
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