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
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
258 additions
and
273 deletions
+258
-273
softcascade.cpp
modules/gpu/src/softcascade.cpp
+258
-273
No files found.
modules/gpu/src/softcascade.cpp
View file @
f196e9fd
...
...
@@ -78,203 +78,63 @@ namespace imgproc
struct
cv
::
gpu
::
SoftCascade
::
Filds
{
Filds
()
{
plane
.
create
(
FRAME_HEIGHT
*
(
HOG_LUV_BINS
+
1
),
FRAME_WIDTH
,
CV_8UC1
);
fplane
.
create
(
FRAME_HEIGHT
*
6
,
FRAME_WIDTH
,
CV_32FC1
);
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
float
minScale
;
float
maxScale
;
int
origObjWidth
;
int
origObjHeight
;
int
downscales
;
GpuMat
octaves
;
GpuMat
stages
;
GpuMat
nodes
;
GpuMat
leaves
;
GpuMat
levels
;
GpuMat
detCounter
;
// preallocated buffer 640x480x10 for hogluv + 640x480 got gray
GpuMat
plane
;
// preallocated buffer for floating point operations
GpuMat
fplane
;
// temporial mat for cvtColor
GpuMat
luv
;
// 160x120x10
GpuMat
shrunk
;
// temporial mat for integrall
GpuMat
integralBuffer
;
// 161x121x10
GpuMat
hogluv
;
std
::
vector
<
float
>
scales
;
device
::
icf
::
CascadeInvoker
<
device
::
icf
::
CascadePolicy
>
invoker
;
static
const
int
shrinkage
=
4
;
enum
{
BOOST
=
0
};
enum
{
FRAME_WIDTH
=
640
,
FRAME_HEIGHT
=
480
,
TOTAL_SCALES
=
55
,
ORIG_OBJECT_WIDTH
=
64
,
ORIG_OBJECT_HEIGHT
=
128
,
HOG_BINS
=
6
,
LUV_BINS
=
3
,
HOG_LUV_BINS
=
10
};
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
{
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
);
}
void
preprocess
(
const
cv
::
gpu
::
GpuMat
&
colored
)
{
cudaMemset
(
plane
.
data
,
0
,
plane
.
step
*
plane
.
rows
);
static
const
int
fw
=
Filds
::
FRAME_WIDTH
;
static
const
int
fh
=
Filds
::
FRAME_HEIGHT
;
GpuMat
gray
(
plane
,
cv
::
Rect
(
0
,
fh
*
Filds
::
HOG_LUV_BINS
,
fw
,
fh
));
cv
::
gpu
::
cvtColor
(
colored
,
gray
,
CV_BGR2GRAY
);
createHogBins
(
gray
);
createLuvBins
(
colored
);
integrate
();
}
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
;
int
fitOctave
(
const
std
::
vector
<
device
::
icf
::
Octave
>&
octs
,
const
float
&
logFactor
)
const
{
float
minAbsLog
=
FLT_MAX
;
int
res
=
0
;
for
(
int
oct
=
0
;
oct
<
(
int
)
octs
.
size
();
++
oct
)
{
const
device
::
icf
::
Octave
&
octave
=
octs
[
oct
];
float
logOctave
=
::
log
(
octave
.
scale
);
float
logAbsScale
=
::
fabs
(
logFactor
-
logOctave
);
if
(
logAbsScale
<
minAbsLog
)
struct
CascadeIntrinsics
{
res
=
oct
;
minAbsLog
=
logAbsScale
;
}
}
return
res
;
}
static
const
float
lambda
=
1.099
f
,
a
=
0.89
f
;
void
createHogBins
(
const
cv
::
gpu
::
GpuMat
&
gray
)
static
float
getFor
(
int
channel
,
float
scaling
)
{
static
const
int
fw
=
Filds
::
FRAME_WIDTH
;
static
const
int
fh
=
Filds
::
FRAME_HEIGHT
;
GpuMat
dfdx
(
fplane
,
cv
::
Rect
(
0
,
0
,
fw
,
fh
));
GpuMat
dfdy
(
fplane
,
cv
::
Rect
(
0
,
fh
,
fw
,
fh
));
cv
::
gpu
::
Sobel
(
gray
,
dfdx
,
CV_32F
,
1
,
0
,
3
,
0.125
f
);
cv
::
gpu
::
Sobel
(
gray
,
dfdy
,
CV_32F
,
0
,
1
,
3
,
0.125
f
);
GpuMat
mag
(
fplane
,
cv
::
Rect
(
0
,
2
*
fh
,
fw
,
fh
));
GpuMat
ang
(
fplane
,
cv
::
Rect
(
0
,
3
*
fh
,
fw
,
fh
));
cv
::
gpu
::
cartToPolar
(
dfdx
,
dfdy
,
mag
,
ang
,
true
);
// normolize magnitude to uchar interval and angles to 6 bins
GpuMat
nmag
(
fplane
,
cv
::
Rect
(
0
,
4
*
fh
,
fw
,
fh
));
GpuMat
nang
(
fplane
,
cv
::
Rect
(
0
,
5
*
fh
,
fw
,
fh
));
cv
::
gpu
::
multiply
(
mag
,
cv
::
Scalar
::
all
(
1.
f
/
::
log
(
2
)),
nmag
);
cv
::
gpu
::
multiply
(
ang
,
cv
::
Scalar
::
all
(
1.
f
/
60.
f
),
nang
);
//create uchar magnitude
GpuMat
cmag
(
plane
,
cv
::
Rect
(
0
,
fh
*
Filds
::
HOG_BINS
,
fw
,
fh
));
nmag
.
convertTo
(
cmag
,
CV_8UC1
);
CV_Assert
(
channel
<
10
);
device
::
icf
::
fillBins
(
plane
,
nang
,
fw
,
fh
,
Filds
::
HOG_BINS
);
}
if
(
fabs
(
scaling
-
1.
f
)
<
FLT_EPSILON
)
return
1.
f
;
void
createLuvBins
(
const
cv
::
gpu
::
GpuMat
&
colored
)
{
static
const
int
fw
=
Filds
::
FRAME_WIDTH
;
static
const
int
fh
=
Filds
::
FRAME_HEIGHT
;
// 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
};
cv
::
gpu
::
cvtColor
(
colored
,
luv
,
CV_BGR2Luv
);
static
const
float
B
[
2
][
2
]
=
{
//channel <= 6, otherwise
{
1.099
f
/
::
log
(
2
),
2.
f
},
// down
{
0.
f
,
2.
f
}
// up
};
std
::
vector
<
GpuMat
>
splited
;
for
(
int
i
=
0
;
i
<
Filds
::
LUV_BINS
;
++
i
)
{
splited
.
push_back
(
GpuMat
(
plane
,
cv
::
Rect
(
0
,
fh
*
(
7
+
i
),
fw
,
fh
)));
}
float
a
=
A
[(
int
)(
scaling
>=
1
)][(
int
)(
channel
>
6
)];
float
b
=
B
[(
int
)(
scaling
>=
1
)][(
int
)(
channel
>
6
)];
cv
::
gpu
::
split
(
luv
,
splited
);
// printf("!!! scaling: %f %f %f -> %f\n", scaling, a, b, a * pow(scaling, b));
return
a
*
::
pow
(
scaling
,
b
);
}
};
void
integrate
()
{
int
fw
=
Filds
::
FRAME_WIDTH
;
int
fh
=
Filds
::
FRAME_HEIGHT
;
GpuMat
channels
(
plane
,
cv
::
Rect
(
0
,
0
,
fw
,
fh
*
Filds
::
HOG_LUV_BINS
));
cv
::
gpu
::
resize
(
channels
,
shrunk
,
cv
::
Size
(),
0.25
,
0.25
,
CV_INTER_AREA
);
fw
/=
shrinkage
;
fh
/=
shrinkage
;
for
(
int
i
=
0
;
i
<
Filds
::
HOG_LUV_BINS
;
++
i
)
static
Filds
*
parseCascade
(
const
FileNode
&
root
,
const
float
mins
,
const
float
maxs
)
{
GpuMat
channel
(
shrunk
,
cv
::
Rect
(
0
,
fh
*
i
,
fw
,
fh
));
GpuMat
sum
(
hogluv
,
cv
::
Rect
(
0
,
(
fh
+
1
)
*
i
,
fw
+
1
,
fh
+
1
));
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"
;
// 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
);
static
const
char
*
const
SC_ORIG_W
=
"width"
;
static
const
char
*
const
SC_ORIG_H
=
"height"
;
int
origWidth
=
(
int
)
root
[
SC_ORIG_W
];
CV_Assert
(
origWidth
==
ORIG_OBJECT_WIDTH
);
int
origHeight
=
(
int
)
root
[
SC_ORIG_H
];
CV_Assert
(
origHeight
==
ORIG_OBJECT_HEIGHT
);
static
const
char
*
const
SC_OCTAVES
=
"octaves"
;
static
const
char
*
const
SC_STAGES
=
"stages"
;
static
const
char
*
const
SC_FEATURES
=
"features"
;
...
...
@@ -292,28 +152,16 @@ bool cv::gpu::SoftCascade::Filds::fill(const FileNode &root, const float mins, c
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
];
CV_Assert
(
origObjWidth
==
ORIG_OBJECT_WIDTH
);
origObjHeight
=
(
int
)
root
[
SC_ORIG_H
];
CV_Assert
(
origObjHeight
==
ORIG_OBJECT_HEIGHT
);
FileNode
fn
=
root
[
SC_OCTAVES
];
if
(
fn
.
empty
())
return
false
;
using
namespace
device
::
icf
;
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
;
...
...
@@ -327,7 +175,6 @@ bool cv::gpu::SoftCascade::Filds::fill(const FileNode &root, const float mins, c
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
);
...
...
@@ -395,82 +242,32 @@ bool cv::gpu::SoftCascade::Filds::fill(const FileNode &root, const float mins, c
++
octIndex
;
}
// upload in gpu memory
octaves
.
upload
(
cv
::
Mat
(
1
,
voctaves
.
size
()
*
sizeof
(
Octave
),
CV_8UC1
,
(
uchar
*
)
&
(
voctaves
[
0
])
));
CV_Assert
(
!
octaves
.
empty
());
stages
.
upload
(
cv
::
Mat
(
vstages
).
reshape
(
1
,
1
));
CV_Assert
(
!
stages
.
empty
());
nodes
.
upload
(
cv
::
Mat
(
1
,
vnodes
.
size
()
*
sizeof
(
Node
),
CV_8UC1
,
(
uchar
*
)
&
(
vnodes
[
0
])
));
CV_Assert
(
!
nodes
.
empty
());
leaves
.
upload
(
cv
::
Mat
(
vleaves
).
reshape
(
1
,
1
));
CV_Assert
(
!
leaves
.
empty
());
// compute levels
calcLevels
(
voctaves
,
FRAME_WIDTH
,
FRAME_HEIGHT
,
TOTAL_SCALES
);
CV_Assert
(
!
levels
.
empty
());
invoker
=
device
::
icf
::
CascadeInvoker
<
device
::
icf
::
CascadePolicy
>
(
levels
,
octaves
,
stages
,
nodes
,
leaves
);
return
true
;
}
cv
::
Mat
hoctaves
(
1
,
voctaves
.
size
()
*
sizeof
(
Octave
),
CV_8UC1
,
(
uchar
*
)
&
(
voctaves
[
0
]));
CV_Assert
(
!
hoctaves
.
empty
());
namespace
{
struct
CascadeIntrinsics
{
static
const
float
lambda
=
1.099
f
,
a
=
0.89
f
;
cv
::
Mat
hstages
(
cv
::
Mat
(
vstages
).
reshape
(
1
,
1
));
CV_Assert
(
!
hstages
.
empty
());
static
float
getFor
(
int
channel
,
float
scaling
)
{
CV_Assert
(
channel
<
10
);
cv
::
Mat
hnodes
(
1
,
vnodes
.
size
()
*
sizeof
(
Node
),
CV_8UC1
,
(
uchar
*
)
&
(
vnodes
[
0
])
);
CV_Assert
(
!
hnodes
.
empty
());
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
};
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
;
cv
::
Mat
hleaves
(
cv
::
Mat
(
vleaves
).
reshape
(
1
,
1
));
CV_Assert
(
!
hleaves
.
empty
());
std
::
vector
<
Level
>
vlevels
;
float
logFactor
=
(
::
log
(
maxScale
)
-
::
log
(
minScale
))
/
(
nscales
-
1
);
float
logFactor
=
(
::
log
(
maxs
)
-
::
log
(
mins
))
/
(
TOTAL_SCALES
-
1
);
float
scale
=
minScale
;
downscales
=
0
;
for
(
int
sc
=
0
;
sc
<
nscales
;
++
sc
)
float
scale
=
mins
;
int
downscales
=
0
;
for
(
int
sc
=
0
;
sc
<
TOTAL_SCALES
;
++
sc
)
{
int
width
=
::
std
::
max
(
0.0
f
,
frameW
-
(
origObj
Width
*
scale
));
int
height
=
::
std
::
max
(
0.0
f
,
frameH
-
(
origObj
Height
*
scale
));
int
width
=
::
std
::
max
(
0.0
f
,
FRAME_WIDTH
-
(
orig
Width
*
scale
));
int
height
=
::
std
::
max
(
0.0
f
,
FRAME_HEIGHT
-
(
orig
Height
*
scale
));
float
logScale
=
::
log
(
scale
);
int
fit
=
fitOctave
(
oct
s
,
logScale
);
int
fit
=
fitOctave
(
voctave
s
,
logScale
);
Level
level
(
fit
,
oct
s
[
fit
],
scale
,
width
,
height
);
Level
level
(
fit
,
voctave
s
[
fit
],
scale
,
width
,
height
);
level
.
scaling
[
0
]
=
CascadeIntrinsics
::
getFor
(
0
,
level
.
relScale
);
level
.
scaling
[
1
]
=
CascadeIntrinsics
::
getFor
(
9
,
level
.
relScale
);
...
...
@@ -479,11 +276,11 @@ inline void cv::gpu::SoftCascade::Filds::calcLevels(const std::vector<device::ic
else
{
vlevels
.
push_back
(
level
);
if
(
oct
s
[
fit
].
scale
<
1
)
++
downscales
;
if
(
voctave
s
[
fit
].
scale
<
1
)
++
downscales
;
}
if
(
::
fabs
(
scale
-
maxScale
)
<
FLT_EPSILON
)
break
;
scale
=
::
std
::
min
(
maxScale
,
::
expf
(
::
log
(
scale
)
+
logFactor
));
if
(
::
fabs
(
scale
-
maxs
)
<
FLT_EPSILON
)
break
;
scale
=
::
std
::
min
(
maxs
,
::
expf
(
::
log
(
scale
)
+
logFactor
));
// std::cout << "level " << sc
// << " octeve "
...
...
@@ -496,8 +293,201 @@ inline void cv::gpu::SoftCascade::Filds::calcLevels(const std::vector<device::ic
// << (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
::
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
)
{
plane
.
create
(
FRAME_HEIGHT
*
(
HOG_LUV_BINS
+
1
),
FRAME_WIDTH
,
CV_8UC1
);
fplane
.
create
(
FRAME_HEIGHT
*
6
,
FRAME_WIDTH
,
CV_32FC1
);
luv
.
create
(
FRAME_HEIGHT
,
FRAME_WIDTH
,
CV_8UC3
);
shrunk
.
create
(
FRAME_HEIGHT
/
shr
*
HOG_LUV_BINS
,
FRAME_WIDTH
/
shr
,
CV_8UC1
);
integralBuffer
.
create
(
1
,
(
shrunk
.
rows
+
1
)
*
HOG_LUV_BINS
*
(
shrunk
.
cols
+
1
),
CV_32SC1
);
hogluv
.
create
((
FRAME_HEIGHT
/
shr
+
1
)
*
HOG_LUV_BINS
,
FRAME_WIDTH
/
shr
+
64
,
CV_32SC1
);
detCounter
.
create
(
1
,
1
,
CV_32SC1
);
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
);
}
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
));
invoker
(
roi
,
hogluv
,
objects
,
detCounter
,
downscales
,
scale
);
}
void
preprocess
(
const
cv
::
gpu
::
GpuMat
&
colored
)
{
cudaMemset
(
plane
.
data
,
0
,
plane
.
step
*
plane
.
rows
);
static
const
int
fw
=
Filds
::
FRAME_WIDTH
;
static
const
int
fh
=
Filds
::
FRAME_HEIGHT
;
GpuMat
gray
(
plane
,
cv
::
Rect
(
0
,
fh
*
Filds
::
HOG_LUV_BINS
,
fw
,
fh
));
cv
::
gpu
::
cvtColor
(
colored
,
gray
,
CV_BGR2GRAY
);
createHogBins
(
gray
);
createLuvBins
(
colored
);
integrate
();
}
private
:
typedef
std
::
vector
<
device
::
icf
::
Octave
>::
const_iterator
octIt_t
;
static
int
fitOctave
(
const
std
::
vector
<
device
::
icf
::
Octave
>&
octs
,
const
float
&
logFactor
)
{
float
minAbsLog
=
FLT_MAX
;
int
res
=
0
;
for
(
int
oct
=
0
;
oct
<
(
int
)
octs
.
size
();
++
oct
)
{
const
device
::
icf
::
Octave
&
octave
=
octs
[
oct
];
float
logOctave
=
::
log
(
octave
.
scale
);
float
logAbsScale
=
::
fabs
(
logFactor
-
logOctave
);
if
(
logAbsScale
<
minAbsLog
)
{
res
=
oct
;
minAbsLog
=
logAbsScale
;
}
}
return
res
;
}
void
createHogBins
(
const
cv
::
gpu
::
GpuMat
&
gray
)
{
static
const
int
fw
=
Filds
::
FRAME_WIDTH
;
static
const
int
fh
=
Filds
::
FRAME_HEIGHT
;
GpuMat
dfdx
(
fplane
,
cv
::
Rect
(
0
,
0
,
fw
,
fh
));
GpuMat
dfdy
(
fplane
,
cv
::
Rect
(
0
,
fh
,
fw
,
fh
));
cv
::
gpu
::
Sobel
(
gray
,
dfdx
,
CV_32F
,
1
,
0
,
3
,
0.125
f
);
cv
::
gpu
::
Sobel
(
gray
,
dfdy
,
CV_32F
,
0
,
1
,
3
,
0.125
f
);
GpuMat
mag
(
fplane
,
cv
::
Rect
(
0
,
2
*
fh
,
fw
,
fh
));
GpuMat
ang
(
fplane
,
cv
::
Rect
(
0
,
3
*
fh
,
fw
,
fh
));
cv
::
gpu
::
cartToPolar
(
dfdx
,
dfdy
,
mag
,
ang
,
true
);
// normolize magnitude to uchar interval and angles to 6 bins
GpuMat
nmag
(
fplane
,
cv
::
Rect
(
0
,
4
*
fh
,
fw
,
fh
));
GpuMat
nang
(
fplane
,
cv
::
Rect
(
0
,
5
*
fh
,
fw
,
fh
));
cv
::
gpu
::
multiply
(
mag
,
cv
::
Scalar
::
all
(
1.
f
/
::
log
(
2
)),
nmag
);
cv
::
gpu
::
multiply
(
ang
,
cv
::
Scalar
::
all
(
1.
f
/
60.
f
),
nang
);
//create uchar magnitude
GpuMat
cmag
(
plane
,
cv
::
Rect
(
0
,
fh
*
Filds
::
HOG_BINS
,
fw
,
fh
));
nmag
.
convertTo
(
cmag
,
CV_8UC1
);
device
::
icf
::
fillBins
(
plane
,
nang
,
fw
,
fh
,
Filds
::
HOG_BINS
);
}
void
createLuvBins
(
const
cv
::
gpu
::
GpuMat
&
colored
)
{
static
const
int
fw
=
Filds
::
FRAME_WIDTH
;
static
const
int
fh
=
Filds
::
FRAME_HEIGHT
;
cv
::
gpu
::
cvtColor
(
colored
,
luv
,
CV_BGR2Luv
);
std
::
vector
<
GpuMat
>
splited
;
for
(
int
i
=
0
;
i
<
Filds
::
LUV_BINS
;
++
i
)
{
splited
.
push_back
(
GpuMat
(
plane
,
cv
::
Rect
(
0
,
fh
*
(
7
+
i
),
fw
,
fh
)));
}
cv
::
gpu
::
split
(
luv
,
splited
);
}
void
integrate
()
{
int
fw
=
Filds
::
FRAME_WIDTH
;
int
fh
=
Filds
::
FRAME_HEIGHT
;
GpuMat
channels
(
plane
,
cv
::
Rect
(
0
,
0
,
fw
,
fh
*
Filds
::
HOG_LUV_BINS
));
cv
::
gpu
::
resize
(
channels
,
shrunk
,
cv
::
Size
(),
0.25
,
0.25
,
CV_INTER_AREA
);
fw
/=
shrinkage
;
fh
/=
shrinkage
;
for
(
int
i
=
0
;
i
<
Filds
::
HOG_LUV_BINS
;
++
i
)
{
GpuMat
channel
(
shrunk
,
cv
::
Rect
(
0
,
fh
*
i
,
fw
,
fh
));
GpuMat
sum
(
hogluv
,
cv
::
Rect
(
0
,
(
fh
+
1
)
*
i
,
fw
+
1
,
fh
+
1
));
cv
::
gpu
::
integralBuffered
(
channel
,
sum
,
integralBuffer
);
}
}
public
:
// scales range
float
minScale
;
float
maxScale
;
int
origObjWidth
;
int
origObjHeight
;
const
int
shrinkage
;
int
downscales
;
// preallocated buffer 640x480x10 for hogluv + 640x480 got gray
GpuMat
plane
;
// preallocated buffer for floating point operations
GpuMat
fplane
;
// temporial mat for cvtColor
GpuMat
luv
;
// 160x120x10
GpuMat
shrunk
;
// temporial mat for integrall
GpuMat
integralBuffer
;
// 161x121x10
GpuMat
hogluv
;
GpuMat
detCounter
;
// Cascade from xml
GpuMat
octaves
;
GpuMat
stages
;
GpuMat
nodes
;
GpuMat
leaves
;
GpuMat
levels
;
device
::
icf
::
CascadeInvoker
<
device
::
icf
::
CascadePolicy
>
invoker
;
enum
{
BOOST
=
0
};
enum
{
FRAME_WIDTH
=
640
,
FRAME_HEIGHT
=
480
,
TOTAL_SCALES
=
55
,
ORIG_OBJECT_WIDTH
=
64
,
ORIG_OBJECT_HEIGHT
=
128
,
HOG_BINS
=
6
,
LUV_BINS
=
3
,
HOG_LUV_BINS
=
10
};
};
cv
::
gpu
::
SoftCascade
::
SoftCascade
()
:
filds
(
0
)
{}
...
...
@@ -513,21 +503,15 @@ cv::gpu::SoftCascade::~SoftCascade()
bool
cv
::
gpu
::
SoftCascade
::
load
(
const
string
&
filename
,
const
float
minScale
,
const
float
maxScale
)
{
if
(
filds
)
delete
filds
;
filds
=
0
;
if
(
filds
)
delete
filds
;
cv
::
FileStorage
fs
(
filename
,
FileStorage
::
READ
);
if
(
!
fs
.
isOpened
())
return
false
;
filds
=
new
Filds
;
Filds
&
flds
=
*
filds
;
if
(
!
flds
.
fill
(
fs
.
getFirstTopLevelNode
(),
minScale
,
maxScale
))
return
false
;
return
true
;
filds
=
Filds
::
parseCascade
(
fs
.
getFirstTopLevelNode
(),
minScale
,
maxScale
);
return
filds
!=
0
;
}
//================================== synchronous version ============================================================//
void
cv
::
gpu
::
SoftCascade
::
detectMultiScale
(
const
GpuMat
&
colored
,
const
GpuMat
&
rois
,
GpuMat
&
objects
,
const
int
/*rejectfactor*/
,
int
specificScale
)
const
{
...
...
@@ -562,7 +546,7 @@ void cv::gpu::SoftCascade::detectMultiScale(const GpuMat&, const GpuMat&, GpuMat
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
\ 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