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
f196e9fd
Commit
f196e9fd
authored
Oct 11, 2012
by
marina.kolpakova
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add factory method for Fields structure
parent
0898c3c6
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
272 additions
and
287 deletions
+272
-287
softcascade.cpp
modules/gpu/src/softcascade.cpp
+272
-287
No files found.
modules/gpu/src/softcascade.cpp
View file @
f196e9fd
...
@@ -78,77 +78,255 @@ namespace imgproc
...
@@ -78,77 +78,255 @@ namespace imgproc
struct
cv
::
gpu
::
SoftCascade
::
Filds
struct
cv
::
gpu
::
SoftCascade
::
Filds
{
{
struct
CascadeIntrinsics
{
static
const
float
lambda
=
1.099
f
,
a
=
0.89
f
;
static
float
getFor
(
int
channel
,
float
scaling
)
{
CV_Assert
(
channel
<
10
);
if
(
fabs
(
scaling
-
1.
f
)
<
FLT_EPSILON
)
return
1.
f
;
// according to R. Benenson, M. Mathias, R. Timofte and L. Van Gool's and Dallal's papers
static
const
float
A
[
2
][
2
]
=
{
//channel <= 6, otherwise
{
0.89
f
,
1.
f
},
// down
{
1.00
f
,
1.
f
}
// up
};
static
const
float
B
[
2
][
2
]
=
{
//channel <= 6, otherwise
{
1.099
f
/
::
log
(
2
),
2.
f
},
// down
{
0.
f
,
2.
f
}
// up
};
Filds
()
float
a
=
A
[(
int
)(
scaling
>=
1
)][(
int
)(
channel
>
6
)];
float
b
=
B
[(
int
)(
scaling
>=
1
)][(
int
)(
channel
>
6
)];
// printf("!!! scaling: %f %f %f -> %f\n", scaling, a, b, a * pow(scaling, b));
return
a
*
::
pow
(
scaling
,
b
);
}
};
static
Filds
*
parseCascade
(
const
FileNode
&
root
,
const
float
mins
,
const
float
maxs
)
{
{
plane
.
create
(
FRAME_HEIGHT
*
(
HOG_LUV_BINS
+
1
),
FRAME_WIDTH
,
CV_8UC1
);
static
const
char
*
const
SC_STAGE_TYPE
=
"stageType"
;
fplane
.
create
(
FRAME_HEIGHT
*
6
,
FRAME_WIDTH
,
CV_32FC1
);
static
const
char
*
const
SC_BOOST
=
"BOOST"
;
luv
.
create
(
FRAME_HEIGHT
,
FRAME_WIDTH
,
CV_8UC3
);
shrunk
.
create
(
FRAME_HEIGHT
/
4
*
HOG_LUV_BINS
,
FRAME_WIDTH
/
4
,
CV_8UC1
);
integralBuffer
.
create
(
1
,
(
shrunk
.
rows
+
1
)
*
HOG_LUV_BINS
*
(
shrunk
.
cols
+
1
),
CV_32SC1
);
hogluv
.
create
((
FRAME_HEIGHT
/
4
+
1
)
*
HOG_LUV_BINS
,
FRAME_WIDTH
/
4
+
64
,
CV_32SC1
);
detCounter
.
create
(
1
,
1
,
CV_32SC1
);
}
// scales range
static
const
char
*
const
SC_FEATURE_TYPE
=
"featureType"
;
float
minScale
;
static
const
char
*
const
SC_ICF
=
"ICF"
;
float
maxScale
;
int
origObjWidth
;
// only Ada Boost supported
int
origObjHeight
;
std
::
string
stageTypeStr
=
(
string
)
root
[
SC_STAGE_TYPE
];
CV_Assert
(
stageTypeStr
==
SC_BOOST
);
int
downscales
;
// only HOG-like integral channel features cupported
string
featureTypeStr
=
(
string
)
root
[
SC_FEATURE_TYPE
];
CV_Assert
(
featureTypeStr
==
SC_ICF
);
GpuMat
octaves
;
static
const
char
*
const
SC_ORIG_W
=
"width"
;
GpuMat
stages
;
static
const
char
*
const
SC_ORIG_H
=
"height"
;
GpuMat
nodes
;
GpuMat
leaves
;
GpuMat
levels
;
GpuMat
detCounter
;
int
origWidth
=
(
int
)
root
[
SC_ORIG_W
];
CV_Assert
(
origWidth
==
ORIG_OBJECT_WIDTH
);
// preallocated buffer 640x480x10 for hogluv + 640x480 got gray
int
origHeight
=
(
int
)
root
[
SC_ORIG_H
];
GpuMat
plane
;
CV_Assert
(
origHeight
==
ORIG_OBJECT_HEIGHT
)
;
// preallocated buffer for floating point operations
static
const
char
*
const
SC_OCTAVES
=
"octaves"
;
GpuMat
fplane
;
static
const
char
*
const
SC_STAGES
=
"stages"
;
static
const
char
*
const
SC_FEATURES
=
"features"
;
// temporial mat for cvtColor
static
const
char
*
const
SC_WEEK
=
"weakClassifiers"
;
GpuMat
luv
;
static
const
char
*
const
SC_INTERNAL
=
"internalNodes"
;
static
const
char
*
const
SC_LEAF
=
"leafValues"
;
// 160x120x10
static
const
char
*
const
SC_OCT_SCALE
=
"scale"
;
GpuMat
shrunk
;
static
const
char
*
const
SC_OCT_STAGES
=
"stageNum"
;
static
const
char
*
const
SC_OCT_SHRINKAGE
=
"shrinkingFactor"
;
// temporial mat for integrall
static
const
char
*
const
SC_STAGE_THRESHOLD
=
"stageThreshold"
;
GpuMat
integralBuffer
;
// 161x121x10
static
const
char
*
const
SC_F_CHANNEL
=
"channel"
;
GpuMat
hogluv
;
static
const
char
*
const
SC_F_RECT
=
"rect"
;
std
::
vector
<
float
>
scales
;
device
::
icf
::
CascadeInvoker
<
device
::
icf
::
CascadePolicy
>
invoker
;
FileNode
fn
=
root
[
SC_OCTAVES
];
if
(
fn
.
empty
())
return
false
;
static
const
int
shrinkage
=
4
;
using
namespace
device
::
icf
;
enum
{
BOOST
=
0
};
std
::
vector
<
Octave
>
voctaves
;
enum
std
::
vector
<
float
>
vstages
;
std
::
vector
<
Node
>
vnodes
;
std
::
vector
<
float
>
vleaves
;
FileNodeIterator
it
=
fn
.
begin
(),
it_end
=
fn
.
end
();
int
feature_offset
=
0
;
ushort
octIndex
=
0
;
ushort
shrinkage
=
1
;
for
(;
it
!=
it_end
;
++
it
)
{
FileNode
fns
=
*
it
;
float
scale
=
(
float
)
fns
[
SC_OCT_SCALE
];
bool
isUPOctave
=
scale
>=
1
;
ushort
nstages
=
saturate_cast
<
ushort
>
((
int
)
fns
[
SC_OCT_STAGES
]);
ushort2
size
;
size
.
x
=
cvRound
(
ORIG_OBJECT_WIDTH
*
scale
);
size
.
y
=
cvRound
(
ORIG_OBJECT_HEIGHT
*
scale
);
shrinkage
=
saturate_cast
<
ushort
>
((
int
)
fns
[
SC_OCT_SHRINKAGE
]);
Octave
octave
(
octIndex
,
nstages
,
shrinkage
,
size
,
scale
);
CV_Assert
(
octave
.
stages
>
0
);
voctaves
.
push_back
(
octave
);
FileNode
ffs
=
fns
[
SC_FEATURES
];
if
(
ffs
.
empty
())
return
false
;
FileNodeIterator
ftrs
=
ffs
.
begin
();
fns
=
fns
[
SC_STAGES
];
if
(
fn
.
empty
())
return
false
;
// for each stage (~ decision tree with H = 2)
FileNodeIterator
st
=
fns
.
begin
(),
st_end
=
fns
.
end
();
for
(;
st
!=
st_end
;
++
st
)
{
fns
=
*
st
;
vstages
.
push_back
((
float
)
fns
[
SC_STAGE_THRESHOLD
]);
fns
=
fns
[
SC_WEEK
];
FileNodeIterator
ftr
=
fns
.
begin
(),
ft_end
=
fns
.
end
();
for
(;
ftr
!=
ft_end
;
++
ftr
)
{
fns
=
(
*
ftr
)[
SC_INTERNAL
];
FileNodeIterator
inIt
=
fns
.
begin
(),
inIt_end
=
fns
.
end
();
for
(;
inIt
!=
inIt_end
;)
{
// int feature = (int)(*(inIt +=2)) + feature_offset;
inIt
+=
3
;
// extract feature, Todo:check it
uint
th
=
saturate_cast
<
uint
>
((
float
)(
*
(
inIt
++
)));
cv
::
FileNode
ftn
=
(
*
ftrs
)[
SC_F_RECT
];
cv
::
FileNodeIterator
r_it
=
ftn
.
begin
();
uchar4
rect
;
rect
.
x
=
saturate_cast
<
uchar
>
((
int
)
*
(
r_it
++
));
rect
.
y
=
saturate_cast
<
uchar
>
((
int
)
*
(
r_it
++
));
rect
.
z
=
saturate_cast
<
uchar
>
((
int
)
*
(
r_it
++
));
rect
.
w
=
saturate_cast
<
uchar
>
((
int
)
*
(
r_it
++
));
if
(
isUPOctave
)
{
rect
.
z
-=
rect
.
x
;
rect
.
w
-=
rect
.
y
;
}
uint
channel
=
saturate_cast
<
uint
>
((
int
)(
*
ftrs
)[
SC_F_CHANNEL
]);
vnodes
.
push_back
(
Node
(
rect
,
channel
,
th
));
++
ftrs
;
}
fns
=
(
*
ftr
)[
SC_LEAF
];
inIt
=
fns
.
begin
(),
inIt_end
=
fns
.
end
();
for
(;
inIt
!=
inIt_end
;
++
inIt
)
vleaves
.
push_back
((
float
)(
*
inIt
));
}
}
feature_offset
+=
octave
.
stages
*
3
;
++
octIndex
;
}
cv
::
Mat
hoctaves
(
1
,
voctaves
.
size
()
*
sizeof
(
Octave
),
CV_8UC1
,
(
uchar
*
)
&
(
voctaves
[
0
]));
CV_Assert
(
!
hoctaves
.
empty
());
cv
::
Mat
hstages
(
cv
::
Mat
(
vstages
).
reshape
(
1
,
1
));
CV_Assert
(
!
hstages
.
empty
());
cv
::
Mat
hnodes
(
1
,
vnodes
.
size
()
*
sizeof
(
Node
),
CV_8UC1
,
(
uchar
*
)
&
(
vnodes
[
0
])
);
CV_Assert
(
!
hnodes
.
empty
());
cv
::
Mat
hleaves
(
cv
::
Mat
(
vleaves
).
reshape
(
1
,
1
));
CV_Assert
(
!
hleaves
.
empty
());
std
::
vector
<
Level
>
vlevels
;
float
logFactor
=
(
::
log
(
maxs
)
-
::
log
(
mins
))
/
(
TOTAL_SCALES
-
1
);
float
scale
=
mins
;
int
downscales
=
0
;
for
(
int
sc
=
0
;
sc
<
TOTAL_SCALES
;
++
sc
)
{
int
width
=
::
std
::
max
(
0.0
f
,
FRAME_WIDTH
-
(
origWidth
*
scale
));
int
height
=
::
std
::
max
(
0.0
f
,
FRAME_HEIGHT
-
(
origHeight
*
scale
));
float
logScale
=
::
log
(
scale
);
int
fit
=
fitOctave
(
voctaves
,
logScale
);
Level
level
(
fit
,
voctaves
[
fit
],
scale
,
width
,
height
);
level
.
scaling
[
0
]
=
CascadeIntrinsics
::
getFor
(
0
,
level
.
relScale
);
level
.
scaling
[
1
]
=
CascadeIntrinsics
::
getFor
(
9
,
level
.
relScale
);
if
(
!
width
||
!
height
)
break
;
else
{
vlevels
.
push_back
(
level
);
if
(
voctaves
[
fit
].
scale
<
1
)
++
downscales
;
}
if
(
::
fabs
(
scale
-
maxs
)
<
FLT_EPSILON
)
break
;
scale
=
::
std
::
min
(
maxs
,
::
expf
(
::
log
(
scale
)
+
logFactor
));
// std::cout << "level " << sc
// << " octeve "
// << vlevels[sc].octave
// << " relScale "
// << vlevels[sc].relScale
// << " " << vlevels[sc].shrScale
// << " [" << (int)vlevels[sc].objSize.x
// << " " << (int)vlevels[sc].objSize.y << "] ["
// << (int)vlevels[sc].workRect.x << " " << (int)vlevels[sc].workRect.y << "]" << std::endl;
}
cv
::
Mat
hlevels
(
1
,
vlevels
.
size
()
*
sizeof
(
Level
),
CV_8UC1
,
(
uchar
*
)
&
(
vlevels
[
0
])
);
CV_Assert
(
!
hlevels
.
empty
());
Filds
*
filds
=
new
Filds
(
mins
,
maxs
,
origWidth
,
origHeight
,
shrinkage
,
downscales
,
hoctaves
,
hstages
,
hnodes
,
hleaves
,
hlevels
);
return
filds
;
}
Filds
(
const
float
mins
,
const
float
maxs
,
const
int
ow
,
const
int
oh
,
const
int
shr
,
const
int
ds
,
cv
::
Mat
hoctaves
,
cv
::
Mat
hstages
,
cv
::
Mat
hnodes
,
cv
::
Mat
hleaves
,
cv
::
Mat
hlevels
)
:
minScale
(
mins
),
maxScale
(
maxs
),
origObjWidth
(
ow
),
origObjHeight
(
oh
),
shrinkage
(
shr
),
downscales
(
ds
)
{
{
FRAME_WIDTH
=
640
,
plane
.
create
(
FRAME_HEIGHT
*
(
HOG_LUV_BINS
+
1
),
FRAME_WIDTH
,
CV_8UC1
);
FRAME_HEIGHT
=
480
,
fplane
.
create
(
FRAME_HEIGHT
*
6
,
FRAME_WIDTH
,
CV_32FC1
);
TOTAL_SCALES
=
55
,
luv
.
create
(
FRAME_HEIGHT
,
FRAME_WIDTH
,
CV_8UC3
);
ORIG_OBJECT_WIDTH
=
64
,
shrunk
.
create
(
FRAME_HEIGHT
/
shr
*
HOG_LUV_BINS
,
FRAME_WIDTH
/
shr
,
CV_8UC1
);
ORIG_OBJECT_HEIGHT
=
128
,
integralBuffer
.
create
(
1
,
(
shrunk
.
rows
+
1
)
*
HOG_LUV_BINS
*
(
shrunk
.
cols
+
1
),
CV_32SC1
);
HOG_BINS
=
6
,
hogluv
.
create
((
FRAME_HEIGHT
/
shr
+
1
)
*
HOG_LUV_BINS
,
FRAME_WIDTH
/
shr
+
64
,
CV_32SC1
);
LUV_BINS
=
3
,
detCounter
.
create
(
1
,
1
,
CV_32SC1
);
HOG_LUV_BINS
=
10
};
octaves
.
upload
(
hoctaves
);
stages
.
upload
(
hstages
);
nodes
.
upload
(
hnodes
);
leaves
.
upload
(
hleaves
);
levels
.
upload
(
hlevels
);
invoker
=
device
::
icf
::
CascadeInvoker
<
device
::
icf
::
CascadePolicy
>
(
levels
,
octaves
,
stages
,
nodes
,
leaves
);
}
bool
fill
(
const
FileNode
&
root
,
const
float
mins
,
const
float
maxs
);
void
detect
(
int
scale
,
const
cv
::
gpu
::
GpuMat
&
roi
,
cv
::
gpu
::
GpuMat
&
objects
,
cudaStream_t
stream
)
const
void
detect
(
int
scale
,
const
cv
::
gpu
::
GpuMat
&
roi
,
cv
::
gpu
::
GpuMat
&
objects
,
cudaStream_t
stream
)
const
{
{
cudaMemset
(
detCounter
.
data
,
0
,
detCounter
.
step
*
detCounter
.
rows
*
sizeof
(
int
));
cudaMemset
(
detCounter
.
data
,
0
,
detCounter
.
step
*
detCounter
.
rows
*
sizeof
(
int
));
// device::icf::CascadeInvoker<device::icf::CascadePolicy> invoker(levels, octaves, stages, nodes, leaves);
invoker
(
roi
,
hogluv
,
objects
,
detCounter
,
downscales
,
scale
);
invoker
(
roi
,
hogluv
,
objects
,
detCounter
,
downscales
,
scale
);
}
}
...
@@ -169,11 +347,9 @@ struct cv::gpu::SoftCascade::Filds
...
@@ -169,11 +347,9 @@ struct cv::gpu::SoftCascade::Filds
}
}
private
:
private
:
void
calcLevels
(
const
std
::
vector
<
device
::
icf
::
Octave
>&
octs
,
int
frameW
,
int
frameH
,
int
nscales
);
typedef
std
::
vector
<
device
::
icf
::
Octave
>::
const_iterator
octIt_t
;
typedef
std
::
vector
<
device
::
icf
::
Octave
>::
const_iterator
octIt_t
;
int
fitOctave
(
const
std
::
vector
<
device
::
icf
::
Octave
>&
octs
,
const
float
&
logFactor
)
const
static
int
fitOctave
(
const
std
::
vector
<
device
::
icf
::
Octave
>&
octs
,
const
float
&
logFactor
)
{
{
float
minAbsLog
=
FLT_MAX
;
float
minAbsLog
=
FLT_MAX
;
int
res
=
0
;
int
res
=
0
;
...
@@ -257,247 +433,61 @@ private:
...
@@ -257,247 +433,61 @@ private:
cv
::
gpu
::
integralBuffered
(
channel
,
sum
,
integralBuffer
);
cv
::
gpu
::
integralBuffered
(
channel
,
sum
,
integralBuffer
);
}
}
}
}
};
bool
cv
::
gpu
::
SoftCascade
::
Filds
::
fill
(
const
FileNode
&
root
,
const
float
mins
,
const
float
maxs
)
{
using
namespace
device
::
icf
;
minScale
=
mins
;
maxScale
=
maxs
;
// cascade properties
static
const
char
*
const
SC_STAGE_TYPE
=
"stageType"
;
static
const
char
*
const
SC_BOOST
=
"BOOST"
;
static
const
char
*
const
SC_FEATURE_TYPE
=
"featureType"
;
static
const
char
*
const
SC_ICF
=
"ICF"
;
static
const
char
*
const
SC_ORIG_W
=
"width"
;
static
const
char
*
const
SC_ORIG_H
=
"height"
;
static
const
char
*
const
SC_OCTAVES
=
"octaves"
;
static
const
char
*
const
SC_STAGES
=
"stages"
;
static
const
char
*
const
SC_FEATURES
=
"features"
;
static
const
char
*
const
SC_WEEK
=
"weakClassifiers"
;
static
const
char
*
const
SC_INTERNAL
=
"internalNodes"
;
static
const
char
*
const
SC_LEAF
=
"leafValues"
;
static
const
char
*
const
SC_OCT_SCALE
=
"scale"
;
static
const
char
*
const
SC_OCT_STAGES
=
"stageNum"
;
static
const
char
*
const
SC_OCT_SHRINKAGE
=
"shrinkingFactor"
;
static
const
char
*
const
SC_STAGE_THRESHOLD
=
"stageThreshold"
;
static
const
char
*
const
SC_F_CHANNEL
=
"channel"
;
static
const
char
*
const
SC_F_RECT
=
"rect"
;
// only Ada Boost supported
std
::
string
stageTypeStr
=
(
string
)
root
[
SC_STAGE_TYPE
];
CV_Assert
(
stageTypeStr
==
SC_BOOST
);
// only HOG-like integral channel features cupported
string
featureTypeStr
=
(
string
)
root
[
SC_FEATURE_TYPE
];
CV_Assert
(
featureTypeStr
==
SC_ICF
);
origObjWidth
=
(
int
)
root
[
SC_ORIG_W
];
public
:
CV_Assert
(
origObjWidth
==
ORIG_OBJECT_WIDTH
);
origObjHeight
=
(
int
)
root
[
SC_ORIG_H
];
// scales range
CV_Assert
(
origObjHeight
==
ORIG_OBJECT_HEIGHT
);
float
minScale
;
float
maxScale
;
FileNode
fn
=
root
[
SC_OCTAVES
];
if
(
fn
.
empty
())
return
false
;
std
::
vector
<
Octave
>
voctaves
;
std
::
vector
<
float
>
vstages
;
std
::
vector
<
Node
>
vnodes
;
std
::
vector
<
float
>
vleaves
;
scales
.
clear
();
FileNodeIterator
it
=
fn
.
begin
(),
it_end
=
fn
.
end
();
int
feature_offset
=
0
;
ushort
octIndex
=
0
;
ushort
shrinkage
=
1
;
for
(;
it
!=
it_end
;
++
it
)
{
FileNode
fns
=
*
it
;
float
scale
=
(
float
)
fns
[
SC_OCT_SCALE
];
bool
isUPOctave
=
scale
>=
1
;
scales
.
push_back
(
scale
);
ushort
nstages
=
saturate_cast
<
ushort
>
((
int
)
fns
[
SC_OCT_STAGES
]);
ushort2
size
;
size
.
x
=
cvRound
(
ORIG_OBJECT_WIDTH
*
scale
);
size
.
y
=
cvRound
(
ORIG_OBJECT_HEIGHT
*
scale
);
shrinkage
=
saturate_cast
<
ushort
>
((
int
)
fns
[
SC_OCT_SHRINKAGE
]);
Octave
octave
(
octIndex
,
nstages
,
shrinkage
,
size
,
scale
);
CV_Assert
(
octave
.
stages
>
0
);
voctaves
.
push_back
(
octave
);
FileNode
ffs
=
fns
[
SC_FEATURES
];
if
(
ffs
.
empty
())
return
false
;
FileNodeIterator
ftrs
=
ffs
.
begin
();
fns
=
fns
[
SC_STAGES
];
if
(
fn
.
empty
())
return
false
;
// for each stage (~ decision tree with H = 2)
FileNodeIterator
st
=
fns
.
begin
(),
st_end
=
fns
.
end
();
for
(;
st
!=
st_end
;
++
st
)
{
fns
=
*
st
;
vstages
.
push_back
((
float
)
fns
[
SC_STAGE_THRESHOLD
]);
fns
=
fns
[
SC_WEEK
];
int
origObjWidth
;
FileNodeIterator
ftr
=
fns
.
begin
(),
ft_end
=
fns
.
end
();
int
origObjHeight
;
for
(;
ftr
!=
ft_end
;
++
ftr
)
{
fns
=
(
*
ftr
)[
SC_INTERNAL
];
FileNodeIterator
inIt
=
fns
.
begin
(),
inIt_end
=
fns
.
end
();
for
(;
inIt
!=
inIt_end
;)
{
// int feature = (int)(*(inIt +=2)) + feature_offset;
inIt
+=
3
;
// extract feature, Todo:check it
uint
th
=
saturate_cast
<
uint
>
((
float
)(
*
(
inIt
++
)));
cv
::
FileNode
ftn
=
(
*
ftrs
)[
SC_F_RECT
];
cv
::
FileNodeIterator
r_it
=
ftn
.
begin
();
uchar4
rect
;
rect
.
x
=
saturate_cast
<
uchar
>
((
int
)
*
(
r_it
++
));
rect
.
y
=
saturate_cast
<
uchar
>
((
int
)
*
(
r_it
++
));
rect
.
z
=
saturate_cast
<
uchar
>
((
int
)
*
(
r_it
++
));
rect
.
w
=
saturate_cast
<
uchar
>
((
int
)
*
(
r_it
++
));
if
(
isUPOctave
)
{
rect
.
z
-=
rect
.
x
;
rect
.
w
-=
rect
.
y
;
}
uint
channel
=
saturate_cast
<
uint
>
((
int
)(
*
ftrs
)[
SC_F_CHANNEL
]);
const
int
shrinkage
;
vnodes
.
push_back
(
Node
(
rect
,
channel
,
th
));
int
downscales
;
++
ftrs
;
}
fns
=
(
*
ftr
)[
SC_LEAF
];
// preallocated buffer 640x480x10 for hogluv + 640x480 got gray
inIt
=
fns
.
begin
(),
inIt_end
=
fns
.
end
();
GpuMat
plane
;
for
(;
inIt
!=
inIt_end
;
++
inIt
)
vleaves
.
push_back
((
float
)(
*
inIt
));
}
}
feature_offset
+=
octave
.
stages
*
3
;
// preallocated buffer for floating point operations
++
octIndex
;
GpuMat
fplane
;
}
// upload in gpu memory
// temporial mat for cvtColor
octaves
.
upload
(
cv
::
Mat
(
1
,
voctaves
.
size
()
*
sizeof
(
Octave
),
CV_8UC1
,
(
uchar
*
)
&
(
voctaves
[
0
])
));
GpuMat
luv
;
CV_Assert
(
!
octaves
.
empty
());
stages
.
upload
(
cv
::
Mat
(
vstages
).
reshape
(
1
,
1
));
// 160x120x10
CV_Assert
(
!
stages
.
empty
())
;
GpuMat
shrunk
;
nodes
.
upload
(
cv
::
Mat
(
1
,
vnodes
.
size
()
*
sizeof
(
Node
),
CV_8UC1
,
(
uchar
*
)
&
(
vnodes
[
0
])
));
// temporial mat for integrall
CV_Assert
(
!
nodes
.
empty
())
;
GpuMat
integralBuffer
;
leaves
.
upload
(
cv
::
Mat
(
vleaves
).
reshape
(
1
,
1
));
// 161x121x10
CV_Assert
(
!
leaves
.
empty
())
;
GpuMat
hogluv
;
// compute levels
GpuMat
detCounter
;
calcLevels
(
voctaves
,
FRAME_WIDTH
,
FRAME_HEIGHT
,
TOTAL_SCALES
);
CV_Assert
(
!
levels
.
empty
());
invoker
=
device
::
icf
::
CascadeInvoker
<
device
::
icf
::
CascadePolicy
>
(
levels
,
octaves
,
stages
,
nodes
,
leaves
);
// Cascade from xml
GpuMat
octaves
;
GpuMat
stages
;
GpuMat
nodes
;
GpuMat
leaves
;
GpuMat
levels
;
return
true
;
device
::
icf
::
CascadeInvoker
<
device
::
icf
::
CascadePolicy
>
invoker
;
}
namespace
{
enum
{
BOOST
=
0
};
struct
CascadeIntrinsics
enum
{
{
static
const
float
lambda
=
1.099
f
,
a
=
0.89
f
;
FRAME_WIDTH
=
640
,
FRAME_HEIGHT
=
480
,
static
float
getFor
(
int
channel
,
float
scaling
)
TOTAL_SCALES
=
55
,
{
ORIG_OBJECT_WIDTH
=
64
,
CV_Assert
(
channel
<
10
);
ORIG_OBJECT_HEIGHT
=
128
,
HOG_BINS
=
6
,
if
(
fabs
(
scaling
-
1.
f
)
<
FLT_EPSILON
)
LUV_BINS
=
3
,
return
1.
f
;
HOG_LUV_BINS
=
10
// according to R. Benenson, M. Mathias, R. Timofte and L. Van Gool's and Dallal's papers
static
const
float
A
[
2
][
2
]
=
{
//channel <= 6, otherwise
{
0.89
f
,
1.
f
},
// down
{
1.00
f
,
1.
f
}
// up
};
static
const
float
B
[
2
][
2
]
=
{
//channel <= 6, otherwise
{
1.099
f
/
log
(
2
),
2.
f
},
// down
{
0.
f
,
2.
f
}
// up
};
float
a
=
A
[(
int
)(
scaling
>=
1
)][(
int
)(
channel
>
6
)];
float
b
=
B
[(
int
)(
scaling
>=
1
)][(
int
)(
channel
>
6
)];
// printf("!!! scaling: %f %f %f -> %f\n", scaling, a, b, a * pow(scaling, b));
return
a
*
pow
(
scaling
,
b
);
}
};
};
}
};
inline
void
cv
::
gpu
::
SoftCascade
::
Filds
::
calcLevels
(
const
std
::
vector
<
device
::
icf
::
Octave
>&
octs
,
int
frameW
,
int
frameH
,
int
nscales
)
{
CV_Assert
(
nscales
>
1
);
using
device
::
icf
::
Level
;
std
::
vector
<
Level
>
vlevels
;
float
logFactor
=
(
::
log
(
maxScale
)
-
::
log
(
minScale
))
/
(
nscales
-
1
);
float
scale
=
minScale
;
downscales
=
0
;
for
(
int
sc
=
0
;
sc
<
nscales
;
++
sc
)
{
int
width
=
::
std
::
max
(
0.0
f
,
frameW
-
(
origObjWidth
*
scale
));
int
height
=
::
std
::
max
(
0.0
f
,
frameH
-
(
origObjHeight
*
scale
));
float
logScale
=
::
log
(
scale
);
int
fit
=
fitOctave
(
octs
,
logScale
);
Level
level
(
fit
,
octs
[
fit
],
scale
,
width
,
height
);
level
.
scaling
[
0
]
=
CascadeIntrinsics
::
getFor
(
0
,
level
.
relScale
);
level
.
scaling
[
1
]
=
CascadeIntrinsics
::
getFor
(
9
,
level
.
relScale
);
if
(
!
width
||
!
height
)
break
;
else
{
vlevels
.
push_back
(
level
);
if
(
octs
[
fit
].
scale
<
1
)
++
downscales
;
}
if
(
::
fabs
(
scale
-
maxScale
)
<
FLT_EPSILON
)
break
;
scale
=
::
std
::
min
(
maxScale
,
::
expf
(
::
log
(
scale
)
+
logFactor
));
// std::cout << "level " << sc
// << " octeve "
// << vlevels[sc].octave
// << " relScale "
// << vlevels[sc].relScale
// << " " << vlevels[sc].shrScale
// << " [" << (int)vlevels[sc].objSize.x
// << " " << (int)vlevels[sc].objSize.y << "] ["
// << (int)vlevels[sc].workRect.x << " " << (int)vlevels[sc].workRect.y << "]" << std::endl;
}
levels
.
upload
(
cv
::
Mat
(
1
,
vlevels
.
size
()
*
sizeof
(
Level
),
CV_8UC1
,
(
uchar
*
)
&
(
vlevels
[
0
])
));
}
cv
::
gpu
::
SoftCascade
::
SoftCascade
()
:
filds
(
0
)
{}
cv
::
gpu
::
SoftCascade
::
SoftCascade
()
:
filds
(
0
)
{}
...
@@ -513,21 +503,15 @@ cv::gpu::SoftCascade::~SoftCascade()
...
@@ -513,21 +503,15 @@ cv::gpu::SoftCascade::~SoftCascade()
bool
cv
::
gpu
::
SoftCascade
::
load
(
const
string
&
filename
,
const
float
minScale
,
const
float
maxScale
)
bool
cv
::
gpu
::
SoftCascade
::
load
(
const
string
&
filename
,
const
float
minScale
,
const
float
maxScale
)
{
{
if
(
filds
)
if
(
filds
)
delete
filds
;
delete
filds
;
filds
=
0
;
cv
::
FileStorage
fs
(
filename
,
FileStorage
::
READ
);
cv
::
FileStorage
fs
(
filename
,
FileStorage
::
READ
);
if
(
!
fs
.
isOpened
())
return
false
;
if
(
!
fs
.
isOpened
())
return
false
;
filds
=
new
Filds
;
filds
=
Filds
::
parseCascade
(
fs
.
getFirstTopLevelNode
(),
minScale
,
maxScale
);
Filds
&
flds
=
*
filds
;
return
filds
!=
0
;
if
(
!
flds
.
fill
(
fs
.
getFirstTopLevelNode
(),
minScale
,
maxScale
))
return
false
;
return
true
;
}
}
//================================== synchronous version ============================================================//
void
cv
::
gpu
::
SoftCascade
::
detectMultiScale
(
const
GpuMat
&
colored
,
const
GpuMat
&
rois
,
void
cv
::
gpu
::
SoftCascade
::
detectMultiScale
(
const
GpuMat
&
colored
,
const
GpuMat
&
rois
,
GpuMat
&
objects
,
const
int
/*rejectfactor*/
,
int
specificScale
)
const
GpuMat
&
objects
,
const
int
/*rejectfactor*/
,
int
specificScale
)
const
{
{
...
@@ -562,7 +546,7 @@ void cv::gpu::SoftCascade::detectMultiScale(const GpuMat&, const GpuMat&, GpuMat
...
@@ -562,7 +546,7 @@ void cv::gpu::SoftCascade::detectMultiScale(const GpuMat&, const GpuMat&, GpuMat
cv
::
Size
cv
::
gpu
::
SoftCascade
::
getRoiSize
()
const
cv
::
Size
cv
::
gpu
::
SoftCascade
::
getRoiSize
()
const
{
{
return
cv
::
Size
(
Filds
::
FRAME_WIDTH
/
4
,
Filds
::
FRAME_HEIGHT
/
4
);
return
cv
::
Size
(
Filds
::
FRAME_WIDTH
/
(
*
filds
).
shrinkage
,
Filds
::
FRAME_HEIGHT
/
(
*
filds
).
shrinkage
);
}
}
#endif
#endif
\ No newline at end of file
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