Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
O
opencv_contrib
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_contrib
Commits
319b25ee
Commit
319b25ee
authored
Jul 24, 2014
by
Vlad Shakhuro
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Bomb commit
parent
9e5b6684
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
730 additions
and
317 deletions
+730
-317
CMakeLists.txt
modules/adas/tools/CMakeLists.txt
+2
-33
CMakeLists.txt
modules/adas/tools/fcw_detect/CMakeLists.txt
+34
-0
fcw_detect.cpp
modules/adas/tools/fcw_detect/fcw_detect.cpp
+92
-0
fcw_train.cpp
modules/adas/tools/fcw_train.cpp
+0
-195
CMakeLists.txt
modules/adas/tools/fcw_train/CMakeLists.txt
+34
-0
fcw_train.cpp
modules/adas/tools/fcw_train/fcw_train.cpp
+100
-0
xobjdetect.hpp
modules/xobjdetect/include/opencv2/xobjdetect.hpp
+57
-13
private.hpp
modules/xobjdetect/include/opencv2/xobjdetect/private.hpp
+24
-0
acffeature.cpp
modules/xobjdetect/src/acffeature.cpp
+68
-13
icfdetector.cpp
modules/xobjdetect/src/icfdetector.cpp
+149
-47
precomp.hpp
modules/xobjdetect/src/precomp.hpp
+2
-0
stump.cpp
modules/xobjdetect/src/stump.cpp
+15
-0
waldboost.cpp
modules/xobjdetect/src/waldboost.cpp
+153
-16
No files found.
modules/adas/tools/CMakeLists.txt
View file @
319b25ee
set
(
name fcw_train
)
set
(
the_target opencv_
${
name
}
)
set
(
the_module opencv_adas
)
ocv_check_dependencies
(
${
OPENCV_MODULE_
${
the_module
}
_DEPS
}
)
if
(
NOT OCV_DEPENDENCIES_FOUND
)
return
()
endif
()
project
(
${
the_target
}
)
ocv_include_directories
(
"
${
OpenCV_SOURCE_DIR
}
/include/opencv"
)
ocv_include_modules
(
${
OPENCV_MODULE_
${
the_module
}
_DEPS
}
)
file
(
GLOB
${
the_target
}
_SOURCES
${
CMAKE_CURRENT_LIST_DIR
}
/*.cpp
)
add_executable
(
${
the_target
}
${${
the_target
}
_SOURCES
}
)
ocv_target_link_libraries
(
${
the_target
}
${
OPENCV_MODULE_
${
the_module
}
_DEPS
}
)
set_target_properties
(
${
the_target
}
PROPERTIES
DEBUG_POSTFIX
"
${
OPENCV_DEBUG_POSTFIX
}
"
ARCHIVE_OUTPUT_DIRECTORY
${
LIBRARY_OUTPUT_PATH
}
RUNTIME_OUTPUT_DIRECTORY
${
EXECUTABLE_OUTPUT_PATH
}
INSTALL_NAME_DIR lib
OUTPUT_NAME
${
the_target
}
)
if
(
ENABLE_SOLUTION_FOLDERS
)
set_target_properties
(
${
the_target
}
PROPERTIES FOLDER
"applications"
)
endif
()
install
(
TARGETS
${
the_target
}
RUNTIME DESTINATION bin COMPONENT main
)
add_subdirectory
(
fcw_train
)
add_subdirectory
(
fcw_detect
)
modules/adas/tools/fcw_detect/CMakeLists.txt
0 → 100644
View file @
319b25ee
set
(
name fcw_detect
)
set
(
the_target opencv_
${
name
}
)
set
(
OPENCV_
${
the_target
}
_DEPS opencv_xobjdetect
)
ocv_check_dependencies
(
${
OPENCV_
${
the_target
}
_DEPS
}
)
if
(
NOT OCV_DEPENDENCIES_FOUND
)
return
()
endif
()
project
(
${
the_target
}
)
ocv_include_directories
(
"
${
OpenCV_SOURCE_DIR
}
/include/opencv"
)
ocv_include_modules
(
${
OPENCV_
${
the_target
}
_DEPS
}
)
file
(
GLOB
${
the_target
}
_SOURCES
${
CMAKE_CURRENT_SOURCE_DIR
}
/*.cpp
)
add_executable
(
${
the_target
}
${${
the_target
}
_SOURCES
}
)
target_link_libraries
(
${
the_target
}
${
OPENCV_
${
the_target
}
_DEPS
}
)
set_target_properties
(
${
the_target
}
PROPERTIES
DEBUG_POSTFIX
"
${
OPENCV_DEBUG_POSTFIX
}
"
ARCHIVE_OUTPUT_DIRECTORY
${
LIBRARY_OUTPUT_PATH
}
RUNTIME_OUTPUT_DIRECTORY
${
EXECUTABLE_OUTPUT_PATH
}
INSTALL_NAME_DIR lib
OUTPUT_NAME
${
the_target
}
)
if
(
ENABLE_SOLUTION_FOLDERS
)
set_target_properties
(
${
the_target
}
PROPERTIES FOLDER
"applications"
)
endif
()
install
(
TARGETS
${
the_target
}
RUNTIME DESTINATION bin COMPONENT main
)
modules/adas/tools/fcw_detect/fcw_detect.cpp
0 → 100644
View file @
319b25ee
#include <string>
using
std
::
string
;
#include <vector>
using
std
::
vector
;
#include <iostream>
using
std
::
cerr
;
using
std
::
endl
;
#include <opencv2/core.hpp>
using
cv
::
Rect
;
using
cv
::
Size
;
using
cv
::
Mat
;
using
cv
::
Mat_
;
using
cv
::
Vec3b
;
#include <opencv2/highgui.hpp>
using
cv
::
imread
;
using
cv
::
imwrite
;
#include <opencv2/core/utility.hpp>
using
cv
::
CommandLineParser
;
using
cv
::
FileStorage
;
#include <opencv2/xobjdetect.hpp>
using
cv
::
xobjdetect
::
ICFDetector
;
static
Mat
visualize
(
const
Mat
&
image
,
const
vector
<
Rect
>
&
objects
)
{
CV_Assert
(
image
.
type
()
==
CV_8UC3
);
Mat_
<
Vec3b
>
img
=
image
.
clone
();
for
(
size_t
j
=
0
;
j
<
objects
.
size
();
++
j
)
{
Rect
obj
=
objects
[
j
];
int
x
=
obj
.
x
;
int
y
=
obj
.
y
;
int
width
=
obj
.
width
;
int
height
=
obj
.
height
;
for
(
int
i
=
y
;
i
<=
y
+
height
;
++
i
)
{
img
(
i
,
x
)
=
Vec3b
(
255
,
0
,
0
);
img
(
i
,
x
+
width
)
=
Vec3b
(
255
,
0
,
0
);
}
for
(
int
i
=
x
;
i
<=
x
+
width
;
++
i
)
{
img
(
y
,
i
)
=
Vec3b
(
255
,
0
,
0
);
img
(
y
+
height
,
i
)
=
Vec3b
(
255
,
0
,
0
);
}
}
return
img
;
}
int
main
(
int
argc
,
char
*
argv
[])
{
const
string
keys
=
"{help | | print this message}"
"{model_filename | model.xml | filename for reading model}"
"{image_path | test.png | path to image for detection}"
"{out_image_path | out.png | path to image for output}"
"{threshold | 0.0 | threshold for cascade}"
;
CommandLineParser
parser
(
argc
,
argv
,
keys
);
parser
.
about
(
"FCW detection"
);
if
(
parser
.
has
(
"help"
)
||
argc
==
1
)
{
parser
.
printMessage
();
return
0
;
}
string
model_filename
=
parser
.
get
<
string
>
(
"model_filename"
);
string
image_path
=
parser
.
get
<
string
>
(
"image_path"
);
string
out_image_path
=
parser
.
get
<
string
>
(
"out_image_path"
);
float
threshold
=
parser
.
get
<
float
>
(
"threshold"
);
if
(
!
parser
.
check
()
)
{
parser
.
printErrors
();
return
1
;
}
ICFDetector
detector
;
FileStorage
fs
(
model_filename
,
FileStorage
::
READ
);
fs
[
"icfdetector"
]
>>
detector
;
fs
.
release
();
vector
<
Rect
>
objects
;
Mat
img
=
imread
(
image_path
);
detector
.
detect
(
img
,
objects
,
1.1
,
Size
(
40
,
40
),
Size
(
300
,
300
),
threshold
);
imwrite
(
out_image_path
,
visualize
(
img
,
objects
));
}
modules/adas/tools/fcw_train.cpp
deleted
100644 → 0
View file @
9e5b6684
#include <cstdio>
#include <cstring>
#include <string>
using
std
::
string
;
#include <vector>
using
std
::
vector
;
#include <fstream>
using
std
::
ifstream
;
using
std
::
getline
;
#include <sstream>
using
std
::
stringstream
;
#include <iostream>
using
std
::
cerr
;
using
std
::
endl
;
#include <opencv2/core.hpp>
using
cv
::
Rect
;
#include <opencv2/xobjdetect.hpp>
using
cv
::
xobjdetect
::
ICFDetectorParams
;
using
cv
::
xobjdetect
::
ICFDetector
;
using
cv
::
xobjdetect
::
WaldBoost
;
using
cv
::
xobjdetect
::
WaldBoostParams
;
using
cv
::
Mat
;
static
bool
read_pos_int
(
const
char
*
str
,
int
*
n
)
{
int
pos
=
0
;
if
(
sscanf
(
str
,
"%d%n"
,
n
,
&
pos
)
!=
1
||
str
[
pos
]
!=
'\0'
||
*
n
<=
0
)
{
return
false
;
}
return
true
;
}
static
bool
read_model_size
(
char
*
str
,
int
*
rows
,
int
*
cols
)
{
int
pos
=
0
;
if
(
sscanf
(
str
,
"%dx%d%n"
,
rows
,
cols
,
&
pos
)
!=
2
||
str
[
pos
]
!=
'\0'
||
*
rows
<=
0
||
*
cols
<=
0
)
{
return
false
;
}
return
true
;
}
static
bool
read_overlap
(
const
char
*
str
,
double
*
overlap
)
{
int
pos
=
0
;
if
(
sscanf
(
str
,
"%lf%n"
,
overlap
,
&
pos
)
!=
1
||
str
[
pos
]
!=
'\0'
||
*
overlap
<
0
||
*
overlap
>
1
)
{
return
false
;
}
return
true
;
}
static
bool
read_labels
(
const
string
&
path
,
vector
<
string
>&
filenames
,
vector
<
vector
<
Rect
>
>&
labels
)
{
string
labels_path
=
path
+
"/gt.txt"
;
string
filename
,
line
;
int
x1
,
y1
,
x2
,
y2
;
char
delim
;
ifstream
ifs
(
labels_path
.
c_str
());
if
(
!
ifs
.
good
()
)
return
false
;
while
(
getline
(
ifs
,
line
)
)
{
stringstream
stream
(
line
);
stream
>>
filename
;
filenames
.
push_back
(
path
+
"/"
+
filename
);
vector
<
Rect
>
filename_labels
;
while
(
stream
>>
x1
>>
y1
>>
x2
>>
y2
>>
delim
)
{
filename_labels
.
push_back
(
Rect
(
x1
,
y1
,
x2
,
y2
));
}
labels
.
push_back
(
filename_labels
);
filename_labels
.
clear
();
}
return
true
;
}
int
main
(
int
argc
,
char
*
argv
[])
{
if
(
argc
==
1
)
{
printf
(
"Usage: %s OPTIONS, where OPTIONS are:
\n
"
"
\n
"
"--path <path> - path to dir with data and labels
\n
"
" (labels should have name gt.txt)
\n
"
"
\n
"
"--feature_count <count> - number of features to generate
\n
"
"
\n
"
"--weak_count <count> - number of weak classifiers in cascade
\n
"
"
\n
"
"--model_size <rowsxcols> - model size in pixels
\n
"
"
\n
"
"--overlap <measure> - number from [0, 1], means maximum
\n
"
" overlap with objects while sampling background
\n
"
"
\n
"
"--model_filename <path> - filename for saving model
\n
"
,
argv
[
0
]);
return
0
;
}
string
path
,
model_path
;
ICFDetectorParams
params
;
for
(
int
i
=
1
;
i
<
argc
;
++
i
)
{
if
(
!
strcmp
(
"--path"
,
argv
[
i
])
)
{
i
+=
1
;
path
=
argv
[
i
];
}
else
if
(
!
strcmp
(
"--feature_count"
,
argv
[
i
])
)
{
i
+=
1
;
if
(
!
read_pos_int
(
argv
[
i
],
&
params
.
feature_count
)
)
{
fprintf
(
stderr
,
"Error reading feature count from `%s`
\n
"
,
argv
[
i
]);
return
1
;
}
}
else
if
(
!
strcmp
(
"--weak_count"
,
argv
[
i
])
)
{
i
+=
1
;
if
(
!
read_pos_int
(
argv
[
i
],
&
params
.
weak_count
)
)
{
fprintf
(
stderr
,
"Error reading weak count from `%s`
\n
"
,
argv
[
i
]);
return
1
;
}
}
else
if
(
!
strcmp
(
"--model_size"
,
argv
[
i
])
)
{
i
+=
1
;
if
(
!
read_model_size
(
argv
[
i
],
&
params
.
model_n_rows
,
&
params
.
model_n_cols
)
)
{
fprintf
(
stderr
,
"Error reading model size from `%s`
\n
"
,
argv
[
i
]);
return
1
;
}
}
else
if
(
!
strcmp
(
"--overlap"
,
argv
[
i
])
)
{
i
+=
1
;
if
(
!
read_overlap
(
argv
[
i
],
&
params
.
overlap
)
)
{
fprintf
(
stderr
,
"Error reading overlap from `%s`
\n
"
,
argv
[
i
]);
return
1
;
}
}
else
if
(
!
strcmp
(
"--model_filename"
,
argv
[
i
])
)
{
i
+=
1
;
model_path
=
argv
[
i
];
}
else
{
fprintf
(
stderr
,
"Error: unknown argument `%s`
\n
"
,
argv
[
i
]);
return
1
;
}
}
try
{
ICFDetector
detector
;
vector
<
string
>
filenames
;
vector
<
vector
<
Rect
>
>
labels
;
read_labels
(
path
,
filenames
,
labels
);
detector
.
train
(
filenames
,
labels
,
params
);
}
catch
(
const
char
*
err
)
{
cerr
<<
err
<<
endl
;
}
catch
(
...
)
{
cerr
<<
"Unknown error
\n
"
<<
endl
;
}
}
modules/adas/tools/fcw_train/CMakeLists.txt
0 → 100644
View file @
319b25ee
set
(
name fcw_train
)
set
(
the_target opencv_
${
name
}
)
set
(
OPENCV_
${
the_target
}
_DEPS opencv_xobjdetect
)
ocv_check_dependencies
(
${
OPENCV_
${
the_target
}
_DEPS
}
)
if
(
NOT OCV_DEPENDENCIES_FOUND
)
return
()
endif
()
project
(
${
the_target
}
)
ocv_include_directories
(
"
${
OpenCV_SOURCE_DIR
}
/include/opencv"
)
ocv_include_modules
(
${
OPENCV_
${
the_target
}
_DEPS
}
)
file
(
GLOB
${
the_target
}
_SOURCES
${
CMAKE_CURRENT_SOURCE_DIR
}
/*.cpp
)
add_executable
(
${
the_target
}
${${
the_target
}
_SOURCES
}
)
target_link_libraries
(
${
the_target
}
${
OPENCV_
${
the_target
}
_DEPS
}
)
set_target_properties
(
${
the_target
}
PROPERTIES
DEBUG_POSTFIX
"
${
OPENCV_DEBUG_POSTFIX
}
"
ARCHIVE_OUTPUT_DIRECTORY
${
LIBRARY_OUTPUT_PATH
}
RUNTIME_OUTPUT_DIRECTORY
${
EXECUTABLE_OUTPUT_PATH
}
INSTALL_NAME_DIR lib
OUTPUT_NAME
${
the_target
}
)
if
(
ENABLE_SOLUTION_FOLDERS
)
set_target_properties
(
${
the_target
}
PROPERTIES FOLDER
"applications"
)
endif
()
install
(
TARGETS
${
the_target
}
RUNTIME DESTINATION bin COMPONENT main
)
modules/adas/tools/fcw_train/fcw_train.cpp
0 → 100644
View file @
319b25ee
#include <cstdio>
#include <cstring>
#include <string>
using
std
::
string
;
#include <vector>
using
std
::
vector
;
#include <fstream>
using
std
::
ifstream
;
using
std
::
getline
;
#include <sstream>
using
std
::
stringstream
;
#include <iostream>
using
std
::
cerr
;
using
std
::
endl
;
#include <opencv2/core.hpp>
using
cv
::
Rect
;
using
cv
::
Size
;
#include <opencv2/highgui.hpp>
using
cv
::
imread
;
#include <opencv2/core/utility.hpp>
using
cv
::
CommandLineParser
;
using
cv
::
FileStorage
;
#include <opencv2/xobjdetect.hpp>
using
cv
::
xobjdetect
::
ICFDetectorParams
;
using
cv
::
xobjdetect
::
ICFDetector
;
using
cv
::
xobjdetect
::
WaldBoost
;
using
cv
::
xobjdetect
::
WaldBoostParams
;
using
cv
::
Mat
;
static
bool
read_model_size
(
const
char
*
str
,
int
*
rows
,
int
*
cols
)
{
int
pos
=
0
;
if
(
sscanf
(
str
,
"%dx%d%n"
,
rows
,
cols
,
&
pos
)
!=
2
||
str
[
pos
]
!=
'\0'
||
*
rows
<=
0
||
*
cols
<=
0
)
{
return
false
;
}
return
true
;
}
int
main
(
int
argc
,
char
*
argv
[])
{
const
string
keys
=
"{help | | print this message}"
"{pos_path | pos | path to training object samples}"
"{bg_path | bg | path to background images}"
"{feature_count | 10000 | number of features to generate}"
"{weak_count | 100 | number of weak classifiers in cascade}"
"{model_size | 40x40 | model size in pixels}"
"{model_filename | model.xml | filename for saving model}"
;
CommandLineParser
parser
(
argc
,
argv
,
keys
);
parser
.
about
(
"FCW trainer"
);
if
(
parser
.
has
(
"help"
)
||
argc
==
1
)
{
parser
.
printMessage
();
return
0
;
}
string
pos_path
=
parser
.
get
<
string
>
(
"pos_path"
);
string
bg_path
=
parser
.
get
<
string
>
(
"bg_path"
);
string
model_filename
=
parser
.
get
<
string
>
(
"model_filename"
);
cerr
<<
pos_path
<<
endl
;
cerr
<<
bg_path
<<
endl
;
ICFDetectorParams
params
;
params
.
feature_count
=
parser
.
get
<
size_t
>
(
"feature_count"
);
params
.
weak_count
=
parser
.
get
<
size_t
>
(
"weak_count"
);
string
model_size
=
parser
.
get
<
string
>
(
"model_size"
);
if
(
!
read_model_size
(
model_size
.
c_str
(),
&
params
.
model_n_rows
,
&
params
.
model_n_cols
)
)
{
cerr
<<
"Error reading model size from `"
<<
model_size
<<
"`"
<<
endl
;
return
1
;
}
if
(
!
parser
.
check
()
)
{
parser
.
printErrors
();
return
1
;
}
ICFDetector
detector
;
detector
.
train
(
pos_path
,
bg_path
,
params
);
FileStorage
fs
(
model_filename
,
FileStorage
::
WRITE
);
fs
<<
"icfdetector"
<<
detector
;
fs
.
release
();
}
modules/xobjdetect/include/opencv2/xobjdetect.hpp
View file @
319b25ee
...
...
@@ -58,7 +58,7 @@ namespace xobjdetect
channels — output array for computed channels
*/
void
computeChannels
(
InputArray
image
,
OutputArrayOfArrays
channels
);
void
computeChannels
(
InputArray
image
,
std
::
vector
<
Mat
>&
channels
);
class
CV_EXPORTS
ACFFeatureEvaluator
:
public
Algorithm
{
...
...
@@ -69,6 +69,8 @@ public:
/* Set window position */
virtual
void
setPosition
(
Size
position
)
=
0
;
virtual
void
assertChannels
()
=
0
;
/* Evaluate feature with given index for current channels
and window position */
virtual
int
evaluate
(
size_t
feature_ind
)
const
=
0
;
...
...
@@ -103,7 +105,7 @@ struct CV_EXPORTS WaldBoostParams
int
weak_count
;
float
alpha
;
WaldBoostParams
()
:
weak_count
(
100
),
alpha
(
0.0
1
f
)
WaldBoostParams
()
:
weak_count
(
100
),
alpha
(
0.0
2
f
)
{}
};
...
...
@@ -122,8 +124,8 @@ public:
Returns feature indices chosen for cascade.
Feature enumeration starts from 0
*/
virtual
std
::
vector
<
int
>
train
(
const
Mat
&
data
,
const
Mat
&
labels
)
=
0
;
virtual
std
::
vector
<
int
>
train
(
const
Mat
&
/*data*/
,
const
Mat
&
/*labels*/
)
{
return
std
::
vector
<
int
>
();}
/* Predict object class given object that can compute object features
...
...
@@ -133,10 +135,21 @@ public:
is from class +1
*/
virtual
float
predict
(
const
Ptr
<
ACFFeatureEvaluator
>&
feature_evaluator
)
const
=
0
;
const
Ptr
<
ACFFeatureEvaluator
>&
/*feature_evaluator*/
)
const
{
return
0.0
f
;}
/* Write WaldBoost to FileStorage */
virtual
void
write
(
FileStorage
&
/*fs*/
)
const
{}
/* Read WaldBoost */
virtual
void
read
(
const
FileNode
&
/*node*/
)
{}
};
void
write
(
FileStorage
&
fs
,
String
&
,
const
WaldBoost
&
waldboost
);
void
read
(
const
FileNode
&
node
,
WaldBoost
&
w
,
const
WaldBoost
&
default_value
=
WaldBoost
());
CV_EXPORTS
Ptr
<
WaldBoost
>
createWaldBoost
(
const
WaldBoostParams
&
params
=
WaldBoostParams
());
...
...
@@ -146,32 +159,63 @@ struct CV_EXPORTS ICFDetectorParams
int
weak_count
;
int
model_n_rows
;
int
model_n_cols
;
double
overlap
;
ICFDetectorParams
()
:
feature_count
(
UINT_MAX
),
weak_count
(
100
),
model_n_rows
(
40
),
model_n_cols
(
40
)
,
overlap
(
0.0
)
model_n_rows
(
40
),
model_n_cols
(
40
)
{}
};
class
CV_EXPORTS
ICFDetector
{
public
:
ICFDetector
()
:
waldboost_
(),
features_
()
{}
/* Train detector
image_filenames — filenames of images for training
pos_path — path to folder with images of objects
labelling — vector of object bounding boxes per every image
bg_path — path to folder with background images
params — parameters for detector training
*/
void
train
(
const
std
::
vector
<
std
::
string
>&
image_filenames
,
const
std
::
vector
<
std
::
vector
<
cv
::
Rect
>
>&
labelling
,
void
train
(
const
String
&
pos_path
,
const
String
&
bg_path
,
ICFDetectorParams
params
=
ICFDetectorParams
());
/* Save detector in file, return true on success, false otherwise */
bool
save
(
const
std
::
string
&
filename
);
/* Detect object on image
image — image for detection
object — output array of bounding boxes
scaleFactor — scale between layers in detection pyramid
minSize — min size of objects in pixels
maxSize — max size of objects in pixels
*/
void
detect
(
const
Mat
&
image
,
std
::
vector
<
Rect
>&
objects
,
double
scaleFactor
,
Size
minSize
,
Size
maxSize
,
float
threshold
);
/* Write detector to FileStorage */
void
write
(
FileStorage
&
fs
)
const
;
/* Read detector */
void
read
(
const
FileNode
&
node
);
private
:
Ptr
<
WaldBoost
>
waldboost_
;
std
::
vector
<
Point3i
>
features_
;
int
model_n_rows_
;
int
model_n_cols_
;
};
CV_EXPORTS
void
write
(
FileStorage
&
fs
,
String
&
,
const
ICFDetector
&
detector
);
CV_EXPORTS
void
read
(
const
FileNode
&
node
,
ICFDetector
&
d
,
const
ICFDetector
&
default_value
=
ICFDetector
());
}
/* namespace xobjdetect */
}
/* namespace cv */
...
...
modules/xobjdetect/include/opencv2/xobjdetect/private.hpp
View file @
319b25ee
...
...
@@ -47,6 +47,26 @@ public:
*/
float
predict
(
int
value
)
const
;
/* Write stump in FileStorage */
void
write
(
FileStorage
&
fs
)
const
{
fs
<<
"{"
<<
"threshold"
<<
threshold_
<<
"polarity"
<<
polarity_
<<
"pos_value"
<<
pos_value_
<<
"neg_value"
<<
neg_value_
<<
"}"
;
}
/* Read stump */
void
read
(
const
FileNode
&
node
)
{
threshold_
=
(
int
)
node
[
"threshold"
];
polarity_
=
(
int
)
node
[
"polarity"
];
pos_value_
=
(
float
)
node
[
"pos_value"
];
neg_value_
=
(
float
)
node
[
"neg_value"
];
}
private
:
/* Stump decision threshold */
int
threshold_
;
...
...
@@ -56,6 +76,10 @@ private:
float
pos_value_
,
neg_value_
;
};
void
read
(
const
FileNode
&
node
,
Stump
&
s
,
const
Stump
&
default_value
=
Stump
());
void
write
(
FileStorage
&
fs
,
String
&
,
const
Stump
&
s
);
}
/* namespace xobjdetect */
}
/* namespace cv */
...
...
modules/xobjdetect/src/acffeature.cpp
View file @
319b25ee
...
...
@@ -64,6 +64,7 @@ public:
}
virtual
void
setChannels
(
InputArrayOfArrays
channels
);
virtual
void
assertChannels
();
virtual
void
setPosition
(
Size
position
);
virtual
int
evaluate
(
size_t
feature_ind
)
const
;
virtual
void
evaluateAll
(
OutputArray
feature_values
)
const
;
...
...
@@ -77,16 +78,56 @@ private:
Size
position_
;
};
static
bool
isNull
(
const
Mat_
<
int
>
&
m
)
{
bool
null_data
=
true
;
for
(
int
row
=
0
;
row
<
m
.
rows
;
++
row
)
{
for
(
int
col
=
0
;
col
<
m
.
cols
;
++
col
)
if
(
m
.
at
<
int
>
(
row
,
col
)
)
null_data
=
false
;
}
return
null_data
;
}
void
ACFFeatureEvaluatorImpl
::
assertChannels
()
{
bool
null_data
=
true
;
for
(
size_t
i
=
0
;
i
<
channels_
.
size
();
++
i
)
null_data
&=
isNull
(
channels_
[
i
]);
CV_Assert
(
!
null_data
);
}
void
ACFFeatureEvaluatorImpl
::
setChannels
(
cv
::
InputArrayOfArrays
channels
)
{
channels_
.
clear
();
vector
<
Mat
>
ch
;
channels
.
getMatVector
(
ch
);
CV_Assert
(
ch
.
size
()
==
10
);
/*int min_val = 100500, max_val = -1;
for( size_t i = 0; i < ch.size(); ++i )
{
const Mat &channel = ch[i];
for( int row = 0; row < channel.rows; ++row )
for( int col = 0; col < channel.cols; ++col )
{
int val = (int)channel.at<float>(row, col);
if( val < min_val )
min_val = val;
else if( val > max_val )
max_val = val;
}
}
cout << "SET " << min_val << " " << max_val << endl;
*/
for
(
size_t
i
=
0
;
i
<
ch
.
size
();
++
i
)
{
const
Mat
&
channel
=
ch
[
i
];
Mat_
<
int
>
acf_channel
(
channel
.
rows
/
4
,
channel
.
cols
/
4
);
Mat_
<
int
>
acf_channel
=
Mat_
<
int
>::
zeros
(
channel
.
rows
/
4
,
channel
.
cols
/
4
);
for
(
int
row
=
0
;
row
<
channel
.
rows
;
row
+=
4
)
{
for
(
int
col
=
0
;
col
<
channel
.
cols
;
col
+=
4
)
...
...
@@ -94,18 +135,23 @@ void ACFFeatureEvaluatorImpl::setChannels(cv::InputArrayOfArrays channels)
int
sum
=
0
;
for
(
int
cell_row
=
row
;
cell_row
<
row
+
4
;
++
cell_row
)
for
(
int
cell_col
=
col
;
cell_col
<
col
+
4
;
++
cell_col
)
{
//cout << channel.rows << " " << channel.cols << endl;
//cout << cell_row << " " << cell_col << endl;
sum
+=
(
int
)
channel
.
at
<
float
>
(
cell_row
,
cell_col
);
}
acf_channel
(
row
/
4
,
col
/
4
)
=
sum
;
}
}
channels_
.
push_back
(
acf_channel
);
channels_
.
push_back
(
acf_channel
.
clone
());
}
}
void
ACFFeatureEvaluatorImpl
::
setPosition
(
Size
position
)
{
position_
=
position
;
position_
=
Size
(
position
.
width
/
4
,
position
.
height
/
4
)
;
}
int
ACFFeatureEvaluatorImpl
::
evaluate
(
size_t
feature_ind
)
const
...
...
@@ -117,7 +163,7 @@ int ACFFeatureEvaluatorImpl::evaluate(size_t feature_ind) const
int
x
=
feature
.
x
;
int
y
=
feature
.
y
;
int
n
=
feature
.
z
;
return
channels_
[
n
].
at
<
int
>
(
y
,
x
);
return
channels_
[
n
].
at
<
int
>
(
y
+
position_
.
width
,
x
+
position_
.
height
);
}
void
ACFFeatureEvaluatorImpl
::
evaluateAll
(
OutputArray
feature_values
)
const
...
...
@@ -127,7 +173,7 @@ void ACFFeatureEvaluatorImpl::evaluateAll(OutputArray feature_values) const
{
feature_vals
(
0
,
i
)
=
evaluate
(
i
);
}
feature_values
.
setTo
(
feature_vals
);
feature_values
.
assign
(
feature_vals
);
}
Ptr
<
ACFFeatureEvaluator
>
...
...
@@ -159,14 +205,15 @@ vector<Point3i> generateFeatures(Size window_size, int count)
return
features
;
}
void
computeChannels
(
cv
::
InputArray
image
,
cv
::
OutputArrayOfArrays
channels_
)
void
computeChannels
(
InputArray
image
,
vector
<
Mat
>&
channels
)
{
Mat
src
(
image
.
getMat
().
rows
,
image
.
getMat
().
cols
,
CV_32FC3
);
image
.
getMat
().
convertTo
(
src
,
CV_32FC3
,
1.
/
255
);
Mat_
<
float
>
grad
;
Mat
gray
;
Mat
luv
,
gray
;
cvtColor
(
src
,
gray
,
CV_RGB2GRAY
);
cvtColor
(
src
,
luv
,
CV_RGB2Luv
);
Mat_
<
float
>
row_der
,
col_der
;
Sobel
(
gray
,
row_der
,
CV_32F
,
0
,
1
);
...
...
@@ -174,7 +221,7 @@ void computeChannels(cv::InputArray image, cv::OutputArrayOfArrays channels_)
magnitude
(
row_der
,
col_der
,
grad
);
Mat_
<
Vec6f
>
hist
(
grad
.
rows
,
grad
.
cols
);
Mat_
<
Vec6f
>
hist
=
Mat_
<
Vec6f
>::
zeros
(
grad
.
rows
,
grad
.
cols
);
const
float
to_deg
=
180
/
3.1415926
f
;
for
(
int
row
=
0
;
row
<
grad
.
rows
;
++
row
)
{
for
(
int
col
=
0
;
col
<
grad
.
cols
;
++
col
)
{
...
...
@@ -182,12 +229,22 @@ void computeChannels(cv::InputArray image, cv::OutputArrayOfArrays channels_)
if
(
angle
<
0
)
angle
+=
180
;
int
ind
=
(
int
)(
angle
/
30
);
hist
(
row
,
col
)[
ind
]
=
grad
(
row
,
col
);
// If angle == 180, prevent index overflow
if
(
ind
==
6
)
ind
=
5
;
hist
(
row
,
col
)[
ind
]
=
grad
(
row
,
col
)
*
255
;
}
}
vector
<
Mat
>
channels
;
channels
.
push_back
(
gray
);
channels
.
clear
();
Mat
luv_channels
[
3
];
split
(
luv
,
luv_channels
);
for
(
int
i
=
0
;
i
<
3
;
++
i
)
channels
.
push_back
(
luv_channels
[
i
]);
channels
.
push_back
(
grad
);
vector
<
Mat
>
hist_channels
;
...
...
@@ -195,8 +252,6 @@ void computeChannels(cv::InputArray image, cv::OutputArrayOfArrays channels_)
for
(
size_t
i
=
0
;
i
<
hist_channels
.
size
();
++
i
)
channels
.
push_back
(
hist_channels
[
i
]);
channels_
.
setTo
(
channels
);
}
}
/* namespace xobjdetect */
...
...
modules/xobjdetect/src/icfdetector.cpp
View file @
319b25ee
...
...
@@ -39,6 +39,17 @@ the use of this software, even if advised of the possibility of such damage.
*/
#include <sstream>
using
std
::
ostringstream
;
#include <iomanip>
using
std
::
setfill
;
using
std
::
setw
;
#include <iostream>
using
std
::
cout
;
using
std
::
endl
;
#include "precomp.hpp"
using
std
::
vector
;
...
...
@@ -52,64 +63,54 @@ namespace cv
namespace
xobjdetect
{
static
bool
overlap
(
const
Rect
&
r
,
const
vector
<
Rect
>&
gt
)
{
for
(
size_t
i
=
0
;
i
<
gt
.
size
();
++
i
)
if
(
(
r
&
gt
[
i
]).
area
()
)
return
true
;
return
false
;
}
void
ICFDetector
::
train
(
const
vector
<
string
>&
image_filenames
,
const
vector
<
vector
<
Rect
>
>&
labelling
,
void
ICFDetector
::
train
(
const
String
&
pos_path
,
const
String
&
bg_path
,
ICFDetectorParams
params
)
{
vector
<
String
>
pos_filenames
;
glob
(
pos_path
+
"/*.png"
,
pos_filenames
);
vector
<
String
>
bg_filenames
;
glob
(
bg_path
+
"/*.png"
,
bg_filenames
);
model_n_rows_
=
params
.
model_n_rows
;
model_n_cols_
=
params
.
model_n_cols
;
Size
model_size
(
params
.
model_n_cols
,
params
.
model_n_rows
);
vector
<
Mat
>
samples
;
/* positive samples + negative samples */
Mat
sample
,
resized_sample
;
int
pos_count
=
0
;
for
(
size_t
i
=
0
;
i
<
image_filenames
.
size
();
++
i
,
++
pos_count
)
{
Mat
img
=
imread
(
String
(
image_filenames
[
i
].
c_str
()));
for
(
size_t
j
=
0
;
j
<
labelling
[
i
].
size
();
++
j
)
{
Rect
r
=
labelling
[
i
][
j
];
if
(
r
.
x
>
img
.
cols
||
r
.
y
>
img
.
rows
)
continue
;
sample
=
img
.
colRange
(
max
(
r
.
x
,
0
),
min
(
r
.
width
,
img
.
cols
))
.
rowRange
(
max
(
r
.
y
,
0
),
min
(
r
.
height
,
img
.
rows
));
resize
(
sample
,
resized_sample
,
model_size
);
samples
.
push_back
(
resized_sample
);
}
for
(
size_t
i
=
0
;
i
<
pos_filenames
.
size
();
++
i
,
++
pos_count
)
{
cout
<<
setw
(
6
)
<<
(
i
+
1
)
<<
"/"
<<
pos_filenames
.
size
()
<<
"
\r
"
;
Mat
img
=
imread
(
pos_filenames
[
i
]);
resize
(
img
,
resized_sample
,
model_size
);
samples
.
push_back
(
resized_sample
.
clone
());
}
cout
<<
"
\n
"
;
int
neg_count
=
0
;
RNG
rng
;
for
(
size_t
i
=
0
;
i
<
image
_filenames
.
size
();
++
i
)
for
(
size_t
i
=
0
;
i
<
bg
_filenames
.
size
();
++
i
)
{
Mat
img
=
imread
(
String
(
image_filenames
[
i
].
c_str
()));
for
(
int
j
=
0
;
j
<
(
int
)(
pos_count
/
image_filenames
.
size
()
+
1
);
)
cout
<<
setw
(
6
)
<<
(
i
+
1
)
<<
"/"
<<
bg_filenames
.
size
()
<<
"
\r
"
;
Mat
img
=
imread
(
bg_filenames
[
i
]);
for
(
int
j
=
0
;
j
<
50
;
++
j
,
++
neg_count
)
{
Rect
r
;
r
.
x
=
rng
.
uniform
(
0
,
img
.
cols
);
r
.
width
=
rng
.
uniform
(
r
.
x
+
1
,
img
.
cols
);
r
.
x
=
rng
.
uniform
(
0
,
img
.
cols
);
r
.
width
=
rng
.
uniform
(
r
.
x
+
1
,
img
.
cols
);
r
.
y
=
rng
.
uniform
(
0
,
img
.
rows
);
r
.
height
=
rng
.
uniform
(
r
.
y
+
1
,
img
.
rows
);
if
(
!
overlap
(
r
,
labelling
[
i
])
)
{
sample
=
img
.
colRange
(
r
.
x
,
r
.
width
).
rowRange
(
r
.
y
,
r
.
height
);
//resize(sample, resized_sample);
samples
.
push_back
(
resized_sample
);
++
neg_count
;
++
j
;
}
sample
=
img
.
colRange
(
r
.
x
,
r
.
width
).
rowRange
(
r
.
y
,
r
.
height
);
resize
(
sample
,
resized_sample
,
model_size
);
samples
.
push_back
(
resized_sample
.
clone
());
}
}
cout
<<
"
\n
"
;
Mat_
<
int
>
labels
(
1
,
pos_count
+
neg_count
);
for
(
int
i
=
0
;
i
<
pos_count
;
++
i
)
...
...
@@ -120,30 +121,131 @@ void ICFDetector::train(const vector<string>& image_filenames,
vector
<
Point3i
>
features
=
generateFeatures
(
model_size
);
Ptr
<
ACFFeatureEvaluator
>
feature_evaluator
=
createACFFeatureEvaluator
(
features
);
Mat_
<
int
>
data
((
int
)
features
.
size
(),
(
int
)
samples
.
size
());
Mat_
<
int
>
feature_col
;
Mat_
<
int
>
data
=
Mat_
<
int
>::
zeros
((
int
)
features
.
size
(),
(
int
)
samples
.
size
());
Mat_
<
int
>
feature_col
(
1
,
(
int
)
samples
.
size
())
;
vector
<
Mat
>
channels
;
for
(
int
i
=
0
;
i
<
(
int
)
samples
.
size
();
++
i
)
{
cout
<<
setw
(
6
)
<<
i
<<
"/"
<<
samples
.
size
()
<<
"
\r
"
;
computeChannels
(
samples
[
i
],
channels
);
feature_evaluator
->
setChannels
(
channels
);
//feature_evaluator->assertChannels();
feature_evaluator
->
evaluateAll
(
feature_col
);
for
(
int
j
=
0
;
j
<
feature_col
.
rows
;
++
j
)
data
(
i
,
j
)
=
feature_col
(
0
,
j
);
CV_Assert
(
feature_col
.
cols
==
(
int
)
features
.
size
());
for
(
int
j
=
0
;
j
<
feature_col
.
cols
;
++
j
)
data
(
j
,
i
)
=
feature_col
(
0
,
j
);
}
cout
<<
"
\n
"
;
samples
.
clear
();
WaldBoostParams
wparams
;
wparams
.
weak_count
=
params
.
weak_count
;
wparams
.
alpha
=
0.001
f
;
wparams
.
alpha
=
0.02
f
;
waldboost_
=
createWaldBoost
(
wparams
);
vector
<
int
>
indices
=
waldboost_
->
train
(
data
,
labels
);
cout
<<
"indices: "
;
for
(
size_t
i
=
0
;
i
<
indices
.
size
();
++
i
)
cout
<<
indices
[
i
]
<<
" "
;
cout
<<
endl
;
features_
.
clear
();
for
(
size_t
i
=
0
;
i
<
indices
.
size
();
++
i
)
features_
.
push_back
(
features
[
indices
[
i
]]);
}
Ptr
<
WaldBoost
>
waldboost
=
createWaldBoost
(
wparams
);
waldboost
->
train
(
data
,
labels
);
void
ICFDetector
::
write
(
FileStorage
&
fs
)
const
{
fs
<<
"{"
;
fs
<<
"model_n_rows"
<<
model_n_rows_
;
fs
<<
"model_n_cols"
<<
model_n_cols_
;
fs
<<
"waldboost"
<<
*
waldboost_
;
fs
<<
"features"
<<
"["
;
for
(
size_t
i
=
0
;
i
<
features_
.
size
();
++
i
)
{
fs
<<
features_
[
i
];
}
fs
<<
"]"
;
fs
<<
"}"
;
}
void
ICFDetector
::
read
(
const
FileNode
&
node
)
{
waldboost_
=
Ptr
<
WaldBoost
>
(
createWaldBoost
(
WaldBoostParams
()));
node
[
"model_n_rows"
]
>>
model_n_rows_
;
node
[
"model_n_cols"
]
>>
model_n_cols_
;
node
[
"waldboost"
]
>>
*
waldboost_
;
FileNode
features
=
node
[
"features"
];
features_
.
clear
();
Point3i
p
;
for
(
FileNodeIterator
n
=
features
.
begin
();
n
!=
features
.
end
();
++
n
)
{
(
*
n
)
>>
p
;
features_
.
push_back
(
p
);
}
}
void
ICFDetector
::
detect
(
const
Mat
&
img
,
vector
<
Rect
>&
objects
,
double
scaleFactor
,
Size
minSize
,
Size
maxSize
,
float
threshold
)
{
float
scale_from
=
min
(
model_n_cols_
/
(
float
)
maxSize
.
width
,
model_n_rows_
/
(
float
)
maxSize
.
height
);
float
scale_to
=
max
(
model_n_cols_
/
(
float
)
minSize
.
width
,
model_n_rows_
/
(
float
)
minSize
.
height
);
objects
.
clear
();
Ptr
<
ACFFeatureEvaluator
>
evaluator
=
createACFFeatureEvaluator
(
features_
);
Mat
rescaled_image
;
int
step
=
8
;
vector
<
Mat
>
channels
;
for
(
float
scale
=
scale_from
;
scale
<
scale_to
+
0.001
;
scale
*=
scaleFactor
)
{
cout
<<
"scale "
<<
scale
<<
endl
;
int
new_width
=
img
.
cols
*
scale
;
new_width
-=
new_width
%
4
;
int
new_height
=
img
.
rows
*
scale
;
new_height
-=
new_height
%
4
;
resize
(
img
,
rescaled_image
,
Size
(
new_width
,
new_height
));
computeChannels
(
rescaled_image
,
channels
);
evaluator
->
setChannels
(
channels
);
for
(
int
row
=
0
;
row
<=
rescaled_image
.
rows
-
model_n_rows_
;
row
+=
step
)
{
for
(
int
col
=
0
;
col
<=
rescaled_image
.
cols
-
model_n_cols_
;
col
+=
step
)
{
evaluator
->
setPosition
(
Size
(
row
,
col
));
float
value
=
waldboost_
->
predict
(
evaluator
);
if
(
value
>
threshold
)
{
int
x
=
(
int
)(
col
/
scale
);
int
y
=
(
int
)(
row
/
scale
);
int
width
=
(
int
)(
model_n_cols_
/
scale
);
int
height
=
(
int
)(
model_n_rows_
/
scale
);
cout
<<
value
<<
" "
<<
x
<<
" "
<<
y
<<
" "
<<
width
<<
" "
<<
height
<<
endl
;
objects
.
push_back
(
Rect
(
x
,
y
,
width
,
height
));
}
}
}
}
}
void
write
(
FileStorage
&
fs
,
String
&
,
const
ICFDetector
&
detector
)
{
detector
.
write
(
fs
);
}
bool
ICFDetector
::
save
(
const
string
&
)
void
read
(
const
FileNode
&
node
,
ICFDetector
&
d
,
const
ICFDetector
&
default_value
)
{
return
true
;
if
(
node
.
empty
()
)
d
=
default_value
;
else
d
.
read
(
node
);
}
}
/* namespace xobjdetect */
...
...
modules/xobjdetect/src/precomp.hpp
View file @
319b25ee
...
...
@@ -45,6 +45,8 @@ the use of this software, even if advised of the possibility of such damage.
#include <opencv2/xobjdetect.hpp>
#include <opencv2/xobjdetect/private.hpp>
#include <opencv2/core/utility.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/imgproc/types_c.h>
...
...
modules/xobjdetect/src/stump.cpp
View file @
319b25ee
...
...
@@ -65,6 +65,7 @@ int Stump::train(const Mat& data, const Mat& labels, const Mat& weights)
{
CV_Assert
(
labels
.
rows
==
1
&&
labels
.
cols
==
data
.
cols
);
CV_Assert
(
weights
.
rows
==
1
&&
weights
.
cols
==
data
.
cols
);
CV_Assert
(
data
.
cols
>
1
);
/* Assert that data and labels have int type */
/* Assert that weights have float type */
...
...
@@ -199,5 +200,19 @@ float Stump::predict(int value) const
return
polarity_
*
(
value
-
threshold_
)
>
0
?
pos_value_
:
neg_value_
;
}
void
read
(
const
FileNode
&
node
,
Stump
&
s
,
const
Stump
&
default_value
)
{
if
(
node
.
empty
()
)
s
=
default_value
;
else
s
.
read
(
node
);
}
void
write
(
FileStorage
&
fs
,
String
&
,
const
Stump
&
s
)
{
s
.
write
(
fs
);
}
}
/* namespace xobjdetect */
}
/* namespace cv */
modules/xobjdetect/src/waldboost.cpp
View file @
319b25ee
...
...
@@ -45,6 +45,11 @@ using std::swap;
using
std
::
vector
;
#include <iostream>
using
std
::
cout
;
using
std
::
endl
;
namespace
cv
{
namespace
xobjdetect
...
...
@@ -64,6 +69,10 @@ public:
virtual
float
predict
(
const
Ptr
<
ACFFeatureEvaluator
>&
feature_evaluator
)
const
;
virtual
void
write
(
FileStorage
&
fs
)
const
;
virtual
void
read
(
const
FileNode
&
node
);
private
:
/* Parameters for cascade training */
WaldBoostParams
params_
;
...
...
@@ -73,19 +82,97 @@ private:
std
::
vector
<
float
>
thresholds_
;
};
vector
<
int
>
WaldBoostImpl
::
train
(
const
Mat
&
data
,
const
Mat
&
labels
)
static
int
count
(
const
Mat_
<
int
>
&
m
,
int
elem
)
{
int
res
=
0
;
for
(
int
row
=
0
;
row
<
m
.
rows
;
++
row
)
for
(
int
col
=
0
;
col
<
m
.
cols
;
++
col
)
if
(
m
(
row
,
col
)
==
elem
)
res
+=
1
;
return
res
;
}
void
write
(
FileStorage
&
fs
,
String
&
,
const
WaldBoost
&
waldboost
)
{
waldboost
.
write
(
fs
);
}
void
read
(
const
FileNode
&
node
,
WaldBoost
&
w
,
const
WaldBoost
&
default_value
)
{
if
(
node
.
empty
()
)
w
=
default_value
;
else
w
.
read
(
node
);
}
void
WaldBoostImpl
::
read
(
const
FileNode
&
node
)
{
CV_Assert
(
labels
.
rows
==
1
&&
labels
.
cols
==
data
.
cols
);
FileNode
params
=
node
[
"waldboost_params"
];
params_
.
weak_count
=
(
int
)(
params
[
"weak_count"
]);
params_
.
alpha
=
(
float
)(
params
[
"alpha"
]);
int
pos_count
=
0
,
neg_count
=
0
;
for
(
int
col
=
0
;
col
<
labels
.
cols
;
++
col
)
FileNode
stumps
=
node
[
"waldboost_stumps"
];
stumps_
.
clear
();
for
(
FileNodeIterator
n
=
stumps
.
begin
();
n
!=
stumps
.
end
();
++
n
)
{
if
(
labels
.
at
<
int
>
(
0
,
col
)
==
+
1
)
pos_count
+=
1
;
else
neg_count
+=
1
;
Stump
s
;
*
n
>>
s
;
stumps_
.
push_back
(
s
);
}
FileNode
thresholds
=
node
[
"waldboost_thresholds"
];
thresholds_
.
clear
();
for
(
FileNodeIterator
n
=
thresholds
.
begin
();
n
!=
thresholds
.
end
();
++
n
)
{
float
t
;
*
n
>>
t
;
thresholds_
.
push_back
(
t
);
}
}
void
WaldBoostImpl
::
write
(
FileStorage
&
fs
)
const
{
fs
<<
"{"
;
fs
<<
"waldboost_params"
<<
"{"
<<
"weak_count"
<<
params_
.
weak_count
<<
"alpha"
<<
params_
.
alpha
<<
"}"
;
fs
<<
"waldboost_stumps"
<<
"["
;
for
(
size_t
i
=
0
;
i
<
stumps_
.
size
();
++
i
)
fs
<<
stumps_
[
i
];
fs
<<
"]"
;
fs
<<
"waldboost_thresholds"
<<
"["
;
for
(
size_t
i
=
0
;
i
<
thresholds_
.
size
();
++
i
)
fs
<<
thresholds_
[
i
];
fs
<<
"]"
;
fs
<<
"}"
;
}
vector
<
int
>
WaldBoostImpl
::
train
(
const
Mat
&
data_
,
const
Mat
&
labels_
)
{
CV_Assert
(
labels_
.
rows
==
1
&&
labels_
.
cols
==
data_
.
cols
);
CV_Assert
(
data_
.
rows
>=
params_
.
weak_count
);
Mat
labels
,
data
;
data_
.
copyTo
(
data
);
labels_
.
copyTo
(
labels
);
bool
null_data
=
true
;
for
(
int
row
=
0
;
row
<
data
.
rows
;
++
row
)
{
for
(
int
col
=
0
;
col
<
data
.
cols
;
++
col
)
if
(
data
.
at
<
int
>
(
row
,
col
)
)
null_data
=
false
;
}
CV_Assert
(
!
null_data
);
int
pos_count
=
count
(
labels
,
+
1
);
int
neg_count
=
count
(
labels
,
-
1
);
Mat_
<
float
>
weights
(
labels
.
rows
,
labels
.
cols
);
float
pos_weight
=
1.0
f
/
(
2
*
pos_count
);
float
neg_weight
=
1.0
f
/
(
2
*
neg_count
);
...
...
@@ -97,6 +184,9 @@ vector<int> WaldBoostImpl::train(const Mat& data, const Mat& labels)
weights
.
at
<
float
>
(
0
,
col
)
=
neg_weight
;
}
vector
<
int
>
feature_indices_pool
;
for
(
int
ind
=
0
;
ind
<
data
.
rows
;
++
ind
)
feature_indices_pool
.
push_back
(
ind
);
vector
<
int
>
feature_indices
;
Mat_
<
float
>
trace
=
Mat_
<
float
>::
zeros
(
labels
.
rows
,
labels
.
cols
);
...
...
@@ -104,10 +194,14 @@ vector<int> WaldBoostImpl::train(const Mat& data, const Mat& labels)
thresholds_
.
clear
();
for
(
int
i
=
0
;
i
<
params_
.
weak_count
;
++
i
)
{
cout
<<
"stage "
<<
i
<<
endl
;
Stump
s
;
int
feature_ind
=
s
.
train
(
data
,
labels
,
weights
);
cout
<<
"feature_ind "
<<
feature_ind
<<
endl
;
stumps_
.
push_back
(
s
);
feature_indices
.
push_back
(
feature_ind
);
int
ind
=
feature_indices_pool
[
feature_ind
];
feature_indices_pool
.
erase
(
feature_indices_pool
.
begin
()
+
feature_ind
);
feature_indices
.
push_back
(
ind
);
// Recompute weights
for
(
int
col
=
0
;
col
<
weights
.
cols
;
++
col
)
...
...
@@ -118,6 +212,14 @@ vector<int> WaldBoostImpl::train(const Mat& data, const Mat& labels)
weights
.
at
<
float
>
(
0
,
col
)
*=
exp
(
-
label
*
h
);
}
// Erase row for feature in data
Mat
fixed_data
;
fixed_data
.
push_back
(
data
.
rowRange
(
0
,
feature_ind
));
fixed_data
.
push_back
(
data
.
rowRange
(
feature_ind
+
1
,
data
.
rows
));
data
=
fixed_data
;
// Normalize weights
float
z
=
(
float
)
sum
(
weights
)[
0
];
for
(
int
col
=
0
;
col
<
weights
.
cols
;
++
col
)
...
...
@@ -125,12 +227,12 @@ vector<int> WaldBoostImpl::train(const Mat& data, const Mat& labels)
weights
.
at
<
float
>
(
0
,
col
)
/=
z
;
}
// Sort trace
Mat
indices
;
sortIdx
(
trace
,
indices
,
cv
::
SORT_EVERY_ROW
|
cv
::
SORT_ASCENDING
);
Mat
new_weights
=
Mat_
<
float
>::
zeros
(
weights
.
rows
,
weights
.
cols
);
Mat
new_labels
=
Mat_
<
int
>::
zeros
(
labels
.
rows
,
labels
.
cols
);
Mat
new_data
=
Mat_
<
int
>::
zeros
(
data
.
rows
,
data
.
cols
);
Mat
new_trace
;
for
(
int
col
=
0
;
col
<
new_weights
.
cols
;
++
col
)
{
...
...
@@ -138,26 +240,60 @@ vector<int> WaldBoostImpl::train(const Mat& data, const Mat& labels)
weights
.
at
<
float
>
(
0
,
indices
.
at
<
int
>
(
0
,
col
));
new_labels
.
at
<
int
>
(
0
,
col
)
=
labels
.
at
<
int
>
(
0
,
indices
.
at
<
int
>
(
0
,
col
));
for
(
int
row
=
0
;
row
<
new_data
.
rows
;
++
row
)
{
new_data
.
at
<
int
>
(
row
,
col
)
=
data
.
at
<
int
>
(
row
,
indices
.
at
<
int
>
(
0
,
col
));
}
}
sort
(
trace
,
new_trace
,
cv
::
SORT_EVERY_ROW
|
cv
::
SORT_ASCENDING
);
// Compute threshold for trace
/*
int col = 0;
for( int pos_i = 0;
pos_i
<
pos_count
*
params_
.
alpha
&&
col
<
weight
s
.
cols
;
pos_i < pos_count * params_.alpha && col <
new_label
s.cols;
++col )
{
if
(
labels
.
at
<
int
>
(
0
,
col
)
==
+
1
)
if(
new_
labels.at<int>(0, col) == +1 )
++pos_i;
}
*/
int
cur_pos
=
0
,
cur_neg
=
0
;
int
max_col
=
0
;
for
(
int
col
=
0
;
col
<
new_labels
.
cols
-
1
;
++
col
)
{
if
(
new_labels
.
at
<
int
>
(
0
,
col
)
==
+
1
)
++
cur_pos
;
else
++
cur_neg
;
float
p_neg
=
cur_neg
/
(
float
)
neg_count
;
float
p_pos
=
cur_pos
/
(
float
)
pos_count
;
if
(
params_
.
alpha
*
p_neg
>
p_pos
)
max_col
=
col
;
}
thresholds_
.
push_back
(
new_trace
.
at
<
float
>
(
0
,
col
));
thresholds_
.
push_back
(
new_trace
.
at
<
float
>
(
0
,
max_col
));
cout
<<
"threshold "
<<
*
(
thresholds_
.
end
()
-
1
)
<<
endl
;
cout
<<
"col "
<<
max_col
<<
" size "
<<
data
.
cols
<<
endl
;
// Drop samples below threshold
new_trace
.
colRange
(
col
,
new_trace
.
cols
).
copyTo
(
trace
);
new_weights
.
colRange
(
col
,
new_weights
.
cols
).
copyTo
(
weights
);
new_labels
.
colRange
(
col
,
new_labels
.
cols
).
copyTo
(
labels
);
new_data
.
colRange
(
max_col
,
new_data
.
cols
).
copyTo
(
data
);
new_trace
.
colRange
(
max_col
,
new_trace
.
cols
).
copyTo
(
trace
);
new_weights
.
colRange
(
max_col
,
new_weights
.
cols
).
copyTo
(
weights
);
new_labels
.
colRange
(
max_col
,
new_labels
.
cols
).
copyTo
(
labels
);
pos_count
=
count
(
labels
,
+
1
);
neg_count
=
count
(
labels
,
-
1
);
cout
<<
"pos_count "
<<
pos_count
<<
"; neg_count "
<<
neg_count
<<
endl
;
if
(
data
.
cols
<
2
||
neg_count
==
0
)
{
break
;
}
}
return
feature_indices
;
}
...
...
@@ -166,6 +302,7 @@ float WaldBoostImpl::predict(
const
Ptr
<
ACFFeatureEvaluator
>&
feature_evaluator
)
const
{
float
trace
=
0
;
CV_Assert
(
stumps_
.
size
()
==
thresholds_
.
size
());
for
(
size_t
i
=
0
;
i
<
stumps_
.
size
();
++
i
)
{
int
value
=
feature_evaluator
->
evaluate
(
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