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
da257f33
Commit
da257f33
authored
Sep 13, 2017
by
Vadim Pisarevsky
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #9541 from sturkmen72:patch-15
parents
622318ae
f6daaccc
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
238 additions
and
307 deletions
+238
-307
train_HOG.cpp
samples/cpp/train_HOG.cpp
+238
-307
No files found.
samples/cpp/train_HOG.cpp
View file @
da257f33
#include <opencv2/opencv.hpp>
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/ml.hpp"
#include "opencv2/objdetect.hpp"
#include <string>
#include <iostream>
#include <iostream>
#include <fstream>
#include <vector>
#include <time.h>
#include <time.h>
using
namespace
cv
;
using
namespace
cv
;
using
namespace
cv
::
ml
;
using
namespace
cv
::
ml
;
using
namespace
std
;
using
namespace
std
;
void
get_svm_detector
(
const
Ptr
<
SVM
>
&
svm
,
vector
<
float
>
&
hog_detector
);
void
get_svm_detector
(
const
Ptr
<
SVM
>
&
svm
,
vector
<
float
>
&
hog_detector
);
void
convert_to_ml
(
const
std
::
vector
<
cv
::
Mat
>
&
train_samples
,
cv
::
Mat
&
trainData
);
void
convert_to_ml
(
const
std
::
vector
<
Mat
>
&
train_samples
,
Mat
&
trainData
);
void
load_images
(
const
string
&
prefix
,
const
string
&
filename
,
vector
<
Mat
>
&
img_lst
);
void
load_images
(
const
String
&
dirname
,
vector
<
Mat
>
&
img_lst
,
bool
showImages
);
void
sample_neg
(
const
vector
<
Mat
>
&
full_neg_lst
,
vector
<
Mat
>
&
neg_lst
,
const
Size
&
size
);
void
sample_neg
(
const
vector
<
Mat
>
&
full_neg_lst
,
vector
<
Mat
>
&
neg_lst
,
const
Size
&
size
);
Mat
get_hogdescriptor_visu
(
const
Mat
&
color_origImg
,
vector
<
float
>&
descriptorValues
,
const
Size
&
size
);
void
computeHOGs
(
const
Size
wsize
,
const
vector
<
Mat
>
&
img_lst
,
vector
<
Mat
>
&
gradient_lst
);
void
compute_hog
(
const
vector
<
Mat
>
&
img_lst
,
vector
<
Mat
>
&
gradient_lst
,
const
Size
&
size
);
int
test_trained_detector
(
String
obj_det_filename
,
String
test_dir
,
String
videofilename
);
void
train_svm
(
const
vector
<
Mat
>
&
gradient_lst
,
const
vector
<
int
>
&
labels
);
void
draw_locations
(
Mat
&
img
,
const
vector
<
Rect
>
&
locations
,
const
Scalar
&
color
);
void
test_it
(
const
Size
&
size
);
void
get_svm_detector
(
const
Ptr
<
SVM
>&
svm
,
vector
<
float
>
&
hog_detector
)
void
get_svm_detector
(
const
Ptr
<
SVM
>&
svm
,
vector
<
float
>
&
hog_detector
)
{
{
// get the support vectors
// get the support vectors
Mat
sv
=
svm
->
getSupportVectors
();
Mat
sv
=
svm
->
getSupportVectors
();
const
int
sv_total
=
sv
.
rows
;
const
int
sv_total
=
sv
.
rows
;
// get the decision function
// get the decision function
Mat
alpha
,
svidx
;
Mat
alpha
,
svidx
;
double
rho
=
svm
->
getDecisionFunction
(
0
,
alpha
,
svidx
);
double
rho
=
svm
->
getDecisionFunction
(
0
,
alpha
,
svidx
);
CV_Assert
(
alpha
.
total
()
==
1
&&
svidx
.
total
()
==
1
&&
sv_total
==
1
);
CV_Assert
(
alpha
.
total
()
==
1
&&
svidx
.
total
()
==
1
&&
sv_total
==
1
);
CV_Assert
(
(
alpha
.
type
()
==
CV_64F
&&
alpha
.
at
<
double
>
(
0
)
==
1.
)
||
CV_Assert
(
(
alpha
.
type
()
==
CV_64F
&&
alpha
.
at
<
double
>
(
0
)
==
1.
)
||
...
@@ -37,70 +33,59 @@ void get_svm_detector(const Ptr<SVM>& svm, vector< float > & hog_detector )
...
@@ -37,70 +33,59 @@ void get_svm_detector(const Ptr<SVM>& svm, vector< float > & hog_detector )
hog_detector
.
clear
();
hog_detector
.
clear
();
hog_detector
.
resize
(
sv
.
cols
+
1
);
hog_detector
.
resize
(
sv
.
cols
+
1
);
memcpy
(
&
hog_detector
[
0
],
sv
.
ptr
(),
sv
.
cols
*
sizeof
(
hog_detector
[
0
])
);
memcpy
(
&
hog_detector
[
0
],
sv
.
ptr
(),
sv
.
cols
*
sizeof
(
hog_detector
[
0
]
)
);
hog_detector
[
sv
.
cols
]
=
(
float
)
-
rho
;
hog_detector
[
sv
.
cols
]
=
(
float
)
-
rho
;
}
}
/*
/*
* Convert training/testing set to be used by OpenCV Machine Learning algorithms.
* Convert training/testing set to be used by OpenCV Machine Learning algorithms.
* TrainData is a matrix of size (#samples x max(#cols,#rows) per samples), in 32FC1.
* TrainData is a matrix of size (#samples x max(#cols,#rows) per samples), in 32FC1.
* Transposition of samples are made if needed.
* Transposition of samples are made if needed.
*/
*/
void
convert_to_ml
(
const
std
::
vector
<
cv
::
Mat
>
&
train_samples
,
cv
::
Mat
&
trainData
)
void
convert_to_ml
(
const
vector
<
Mat
>
&
train_samples
,
Mat
&
trainData
)
{
{
//--Convert data
//--Convert data
const
int
rows
=
(
int
)
train_samples
.
size
();
const
int
rows
=
(
int
)
train_samples
.
size
();
const
int
cols
=
(
int
)
std
::
max
(
train_samples
[
0
].
cols
,
train_samples
[
0
].
rows
);
const
int
cols
=
(
int
)
std
::
max
(
train_samples
[
0
].
cols
,
train_samples
[
0
].
rows
);
cv
::
Mat
tmp
(
1
,
cols
,
CV_32FC1
);
//< used for transposition if needed
Mat
tmp
(
1
,
cols
,
CV_32FC1
);
//< used for transposition if needed
trainData
=
cv
::
Mat
(
rows
,
cols
,
CV_32FC1
);
trainData
=
Mat
(
rows
,
cols
,
CV_32FC1
);
vector
<
Mat
>::
const_iterator
itr
=
train_samples
.
begin
();
vector
<
Mat
>::
const_iterator
end
=
train_samples
.
end
();
for
(
size_t
i
=
0
;
i
<
train_samples
.
size
();
++
i
)
for
(
int
i
=
0
;
itr
!=
end
;
++
itr
,
++
i
)
{
{
CV_Assert
(
itr
->
cols
==
1
||
CV_Assert
(
train_samples
[
i
].
cols
==
1
||
train_samples
[
i
].
rows
==
1
);
itr
->
rows
==
1
);
if
(
itr
->
cols
==
1
)
if
(
train_samples
[
i
].
cols
==
1
)
{
{
transpose
(
*
(
itr
)
,
tmp
);
transpose
(
train_samples
[
i
]
,
tmp
);
tmp
.
copyTo
(
trainData
.
row
(
i
)
);
tmp
.
copyTo
(
trainData
.
row
(
(
int
)
i
)
);
}
}
else
if
(
itr
->
rows
==
1
)
else
if
(
train_samples
[
i
].
rows
==
1
)
{
{
itr
->
copyTo
(
trainData
.
row
(
i
)
);
train_samples
[
i
].
copyTo
(
trainData
.
row
(
(
int
)
i
)
);
}
}
}
}
}
}
void
load_images
(
const
string
&
prefix
,
const
string
&
filename
,
vector
<
Mat
>
&
img_lst
)
void
load_images
(
const
String
&
dirname
,
vector
<
Mat
>
&
img_lst
,
bool
showImages
=
false
)
{
{
string
line
;
vector
<
String
>
files
;
ifstream
file
;
glob
(
dirname
,
files
)
;
file
.
open
(
(
prefix
+
filename
).
c_str
()
);
for
(
size_t
i
=
0
;
i
<
files
.
size
();
++
i
)
if
(
!
file
.
is_open
()
)
{
{
cerr
<<
"Unable to open the list of images from "
<<
filename
<<
" filename."
<<
endl
;
Mat
img
=
imread
(
files
[
i
]
);
// load the image
exit
(
-
1
);
if
(
img
.
empty
()
)
// invalid image, skip it.
{
cout
<<
files
[
i
]
<<
" is invalid!"
<<
endl
;
continue
;
}
}
bool
end_of_parsing
=
false
;
if
(
showImages
)
while
(
!
end_of_parsing
)
{
{
getline
(
file
,
line
);
if
(
line
.
empty
()
)
// no more file to read
{
end_of_parsing
=
true
;
break
;
}
Mat
img
=
imread
(
(
prefix
+
line
).
c_str
()
);
// load the image
if
(
img
.
empty
()
)
// invalid image, just skip it.
continue
;
#ifdef _DEBUG
imshow
(
"image"
,
img
);
imshow
(
"image"
,
img
);
waitKey
(
10
);
waitKey
(
1
);
#endif
}
img_lst
.
push_back
(
img
.
clone
()
);
img_lst
.
push_back
(
img
);
}
}
}
}
...
@@ -115,331 +100,277 @@ void sample_neg( const vector< Mat > & full_neg_lst, vector< Mat > & neg_lst, co
...
@@ -115,331 +100,277 @@ void sample_neg( const vector< Mat > & full_neg_lst, vector< Mat > & neg_lst, co
srand
(
(
unsigned
int
)
time
(
NULL
)
);
srand
(
(
unsigned
int
)
time
(
NULL
)
);
vector
<
Mat
>::
const_iterator
img
=
full_neg_lst
.
begin
();
for
(
size_t
i
=
0
;
i
<
full_neg_lst
.
size
();
i
++
)
vector
<
Mat
>::
const_iterator
end
=
full_neg_lst
.
end
();
for
(
;
img
!=
end
;
++
img
)
{
{
box
.
x
=
rand
()
%
(
img
->
cols
-
size_x
);
box
.
x
=
rand
()
%
(
full_neg_lst
[
i
].
cols
-
size_x
);
box
.
y
=
rand
()
%
(
img
->
rows
-
size_y
);
box
.
y
=
rand
()
%
(
full_neg_lst
[
i
].
rows
-
size_y
);
Mat
roi
=
(
*
img
)(
box
);
Mat
roi
=
full_neg_lst
[
i
](
box
);
neg_lst
.
push_back
(
roi
.
clone
()
);
neg_lst
.
push_back
(
roi
.
clone
()
);
#ifdef _DEBUG
imshow
(
"img"
,
roi
.
clone
()
);
waitKey
(
10
);
#endif
}
}
}
}
// From http://www.juergenwiki.de/work/wiki/doku.php?id=public:hog_descriptor_computation_and_visualization
void
computeHOGs
(
const
Size
wsize
,
const
vector
<
Mat
>
&
img_lst
,
vector
<
Mat
>
&
gradient_lst
)
Mat
get_hogdescriptor_visu
(
const
Mat
&
color_origImg
,
vector
<
float
>&
descriptorValues
,
const
Size
&
size
)
{
{
const
int
DIMX
=
size
.
width
;
HOGDescriptor
hog
;
const
int
DIMY
=
size
.
height
;
hog
.
winSize
=
wsize
;
float
zoomFac
=
3
;
Mat
visu
;
resize
(
color_origImg
,
visu
,
Size
(
(
int
)(
color_origImg
.
cols
*
zoomFac
),
(
int
)(
color_origImg
.
rows
*
zoomFac
)
)
);
int
cellSize
=
8
;
int
gradientBinSize
=
9
;
float
radRangeForOneBin
=
(
float
)(
CV_PI
/
(
float
)
gradientBinSize
);
// dividing 180 into 9 bins, how large (in rad) is one bin?
// prepare data structure: 9 orientation / gradient strenghts for each cell
int
cells_in_x_dir
=
DIMX
/
cellSize
;
int
cells_in_y_dir
=
DIMY
/
cellSize
;
float
***
gradientStrengths
=
new
float
**
[
cells_in_y_dir
];
int
**
cellUpdateCounter
=
new
int
*
[
cells_in_y_dir
];
for
(
int
y
=
0
;
y
<
cells_in_y_dir
;
y
++
)
{
gradientStrengths
[
y
]
=
new
float
*
[
cells_in_x_dir
];
cellUpdateCounter
[
y
]
=
new
int
[
cells_in_x_dir
];
for
(
int
x
=
0
;
x
<
cells_in_x_dir
;
x
++
)
{
gradientStrengths
[
y
][
x
]
=
new
float
[
gradientBinSize
];
cellUpdateCounter
[
y
][
x
]
=
0
;
for
(
int
bin
=
0
;
bin
<
gradientBinSize
;
bin
++
)
gradientStrengths
[
y
][
x
][
bin
]
=
0.0
;
}
}
// nr of blocks = nr of cells - 1
Rect
r
=
Rect
(
0
,
0
,
wsize
.
width
,
wsize
.
height
);
// since there is a new block on each cell (overlapping blocks!) but the last one
r
.
x
+=
(
img_lst
[
0
].
cols
-
r
.
width
)
/
2
;
int
blocks_in_x_dir
=
cells_in_x_dir
-
1
;
r
.
y
+=
(
img_lst
[
0
].
rows
-
r
.
height
)
/
2
;
int
blocks_in_y_dir
=
cells_in_y_dir
-
1
;
// compute gradient strengths per cell
Mat
gray
;
int
descriptorDataIdx
=
0
;
vector
<
float
>
descriptors
;
int
cellx
=
0
;
int
celly
=
0
;
for
(
int
blockx
=
0
;
blockx
<
blocks_in_x_dir
;
blockx
++
)
for
(
size_t
i
=
0
;
i
<
img_lst
.
size
();
i
++
)
{
for
(
int
blocky
=
0
;
blocky
<
blocks_in_y_dir
;
blocky
++
)
{
// 4 cells per block ...
for
(
int
cellNr
=
0
;
cellNr
<
4
;
cellNr
++
)
{
{
// compute corresponding cell nr
cvtColor
(
img_lst
[
i
](
r
),
gray
,
COLOR_BGR2GRAY
);
cellx
=
blockx
;
hog
.
compute
(
gray
,
descriptors
,
Size
(
8
,
8
),
Size
(
0
,
0
)
);
celly
=
blocky
;
gradient_lst
.
push_back
(
Mat
(
descriptors
).
clone
()
);
if
(
cellNr
==
1
)
celly
++
;
if
(
cellNr
==
2
)
cellx
++
;
if
(
cellNr
==
3
)
{
cellx
++
;
celly
++
;
}
}
}
for
(
int
bin
=
0
;
bin
<
gradientBinSize
;
bin
++
)
int
test_trained_detector
(
String
obj_det_filename
,
String
test_dir
,
String
videofilename
)
{
{
float
gradientStrength
=
descriptorValues
[
descriptorDataIdx
];
cout
<<
"Testing trained detector..."
<<
endl
;
descriptorDataIdx
++
;
HOGDescriptor
hog
;
hog
.
load
(
obj_det_filename
);
gradientStrengths
[
celly
][
cellx
][
bin
]
+=
gradientStrength
;
vector
<
String
>
files
;
glob
(
test_dir
,
files
);
}
// for (all bins)
int
delay
=
0
;
VideoCapture
cap
;
if
(
videofilename
!=
""
)
{
cap
.
open
(
videofilename
);
}
// note: overlapping blocks lead to multiple updates of this sum!
obj_det_filename
=
"testing "
+
obj_det_filename
;
// we therefore keep track how often a cell was updated,
namedWindow
(
obj_det_filename
,
WINDOW_NORMAL
);
// to compute average gradient strengths
cellUpdateCounter
[
celly
][
cellx
]
++
;
}
// for (all cells)
for
(
size_t
i
=
0
;;
i
++
)
{
Mat
img
;
if
(
cap
.
isOpened
()
)
{
cap
>>
img
;
delay
=
1
;
}
else
if
(
i
<
files
.
size
()
)
{
img
=
imread
(
files
[
i
]
);
}
}
// for (all block x pos)
if
(
img
.
empty
()
)
}
// for (all block y pos)
{
return
0
;
}
vector
<
Rect
>
detections
;
vector
<
double
>
foundWeights
;
// compute average gradient strengths
hog
.
detectMultiScale
(
img
,
detections
,
foundWeights
);
for
(
celly
=
0
;
celly
<
cells_in_y_dir
;
celly
++
)
for
(
size_t
j
=
0
;
j
<
detections
.
size
();
j
++
)
{
for
(
cellx
=
0
;
cellx
<
cells_in_x_dir
;
cellx
++
)
{
{
Scalar
color
=
Scalar
(
0
,
foundWeights
[
j
]
*
foundWeights
[
j
]
*
200
,
0
);
rectangle
(
img
,
detections
[
j
],
color
,
img
.
cols
/
400
+
1
);
}
float
NrUpdatesForThisCell
=
(
float
)
cellUpdateCounter
[
celly
][
cellx
]
;
imshow
(
obj_det_filename
,
img
)
;
// compute average gradient strenghts for each gradient bin direction
if
(
27
==
waitKey
(
delay
)
)
for
(
int
bin
=
0
;
bin
<
gradientBinSize
;
bin
++
)
{
{
gradientStrengths
[
celly
][
cellx
][
bin
]
/=
NrUpdatesForThisCell
;
return
0
;
}
}
}
}
}
return
0
;
}
// draw cells
int
main
(
int
argc
,
char
**
argv
)
for
(
celly
=
0
;
celly
<
cells_in_y_dir
;
celly
++
)
{
const
char
*
keys
=
{
{
for
(
cellx
=
0
;
cellx
<
cells_in_x_dir
;
cellx
++
)
"{help h| | show help message}"
"{pd | | path of directory contains possitive images}"
"{nd | | path of directory contains negative images}"
"{td | | path of directory contains test images}"
"{tv | | test video file name}"
"{dw | | width of the detector}"
"{dh | | height of the detector}"
"{d |false| train twice}"
"{t |false| test a trained detector}"
"{v |false| visualize training steps}"
"{fn |my_detector.yml| file name of trained SVM}"
};
CommandLineParser
parser
(
argc
,
argv
,
keys
);
if
(
parser
.
has
(
"help"
)
)
{
{
int
drawX
=
cellx
*
cellSize
;
parser
.
printMessage
();
int
drawY
=
celly
*
cellSize
;
exit
(
0
);
}
int
mx
=
drawX
+
cellSize
/
2
;
int
my
=
drawY
+
cellSize
/
2
;
rectangle
(
visu
,
Point
((
int
)(
drawX
*
zoomFac
),
(
int
)(
drawY
*
zoomFac
)),
Point
((
int
)((
drawX
+
cellSize
)
*
zoomFac
),
(
int
)((
drawY
+
cellSize
)
*
zoomFac
)),
Scalar
(
100
,
100
,
100
),
1
);
// draw in each cell all 9 gradient strengths
String
pos_dir
=
parser
.
get
<
String
>
(
"pd"
);
for
(
int
bin
=
0
;
bin
<
gradientBinSize
;
bin
++
)
String
neg_dir
=
parser
.
get
<
String
>
(
"nd"
);
String
test_dir
=
parser
.
get
<
String
>
(
"td"
);
String
obj_det_filename
=
parser
.
get
<
String
>
(
"fn"
);
String
videofilename
=
parser
.
get
<
String
>
(
"tv"
);
int
detector_width
=
parser
.
get
<
int
>
(
"dw"
);
int
detector_height
=
parser
.
get
<
int
>
(
"dh"
);
bool
test_detector
=
parser
.
get
<
bool
>
(
"t"
);
bool
train_twice
=
parser
.
get
<
bool
>
(
"d"
);
bool
visualization
=
parser
.
get
<
bool
>
(
"v"
);
if
(
test_detector
)
{
{
float
currentGradStrength
=
gradientStrengths
[
celly
][
cellx
][
bin
];
test_trained_detector
(
obj_det_filename
,
test_dir
,
videofilename
);
exit
(
0
);
// no line to draw?
}
if
(
currentGradStrength
==
0
)
continue
;
float
currRad
=
bin
*
radRangeForOneBin
+
radRangeForOneBin
/
2
;
float
dirVecX
=
cos
(
currRad
);
float
dirVecY
=
sin
(
currRad
);
float
maxVecLen
=
(
float
)(
cellSize
/
2.
f
);
float
scale
=
2.5
;
// just a visualization scale, to see the lines better
// compute line coordinates
float
x1
=
mx
-
dirVecX
*
currentGradStrength
*
maxVecLen
*
scale
;
float
y1
=
my
-
dirVecY
*
currentGradStrength
*
maxVecLen
*
scale
;
float
x2
=
mx
+
dirVecX
*
currentGradStrength
*
maxVecLen
*
scale
;
float
y2
=
my
+
dirVecY
*
currentGradStrength
*
maxVecLen
*
scale
;
// draw gradient visualization
if
(
pos_dir
.
empty
()
||
neg_dir
.
empty
()
)
line
(
visu
,
Point
((
int
)(
x1
*
zoomFac
),(
int
)(
y1
*
zoomFac
)),
Point
((
int
)(
x2
*
zoomFac
),(
int
)(
y2
*
zoomFac
)),
Scalar
(
0
,
255
,
0
),
1
);
{
parser
.
printMessage
();
cout
<<
"Wrong number of parameters.
\n\n
"
<<
"Example command line:
\n
"
<<
argv
[
0
]
<<
" -pd=/INRIAPerson/96X160H96/Train/pos -nd=/INRIAPerson/neg -td=/INRIAPerson/Test/pos -fn=HOGpedestrian96x160.yml -d
\n
"
<<
"
\n
Example command line for testing trained detector:
\n
"
<<
argv
[
0
]
<<
" -t -dw=96 -dh=160 -fn=HOGpedestrian96x160.yml -td=/INRIAPerson/Test/pos"
;
exit
(
1
);
}
}
// for (all bins)
vector
<
Mat
>
pos_lst
,
full_neg_lst
,
neg_lst
,
gradient_lst
;
vector
<
int
>
labels
;
}
// for (cellx)
clog
<<
"Positive images are being loaded..."
;
}
// for (celly)
load_images
(
pos_dir
,
pos_lst
,
visualization
);
if
(
pos_lst
.
size
()
>
0
)
{
clog
<<
"...[done]"
<<
endl
;
}
else
{
clog
<<
"no image in "
<<
pos_dir
<<
endl
;
return
1
;
}
Size
pos_image_size
=
pos_lst
[
0
].
size
();
// don't forget to free memory allocated by helper data structures!
for
(
size_t
i
=
0
;
i
<
pos_lst
.
size
();
++
i
)
for
(
int
y
=
0
;
y
<
cells_in_y_dir
;
y
++
)
{
{
for
(
int
x
=
0
;
x
<
cells_in_x_dir
;
x
++
)
if
(
pos_lst
[
i
].
size
()
!=
pos_image_size
)
{
{
delete
[]
gradientStrengths
[
y
][
x
];
cout
<<
"All positive images should be same size!"
<<
endl
;
exit
(
1
);
}
}
delete
[]
gradientStrengths
[
y
];
delete
[]
cellUpdateCounter
[
y
];
}
}
delete
[]
gradientStrengths
;
delete
[]
cellUpdateCounter
;
return
visu
;
pos_image_size
=
pos_image_size
/
8
*
8
;
}
// get_hogdescriptor_visu
if
(
detector_width
&&
detector_height
)
void
compute_hog
(
const
vector
<
Mat
>
&
img_lst
,
vector
<
Mat
>
&
gradient_lst
,
const
Size
&
size
)
{
HOGDescriptor
hog
;
hog
.
winSize
=
size
;
Mat
gray
;
vector
<
Point
>
location
;
vector
<
float
>
descriptors
;
vector
<
Mat
>::
const_iterator
img
=
img_lst
.
begin
();
vector
<
Mat
>::
const_iterator
end
=
img_lst
.
end
();
for
(
;
img
!=
end
;
++
img
)
{
{
cvtColor
(
*
img
,
gray
,
COLOR_BGR2GRAY
);
pos_image_size
=
Size
(
detector_width
,
detector_height
);
hog
.
compute
(
gray
,
descriptors
,
Size
(
8
,
8
),
Size
(
0
,
0
),
location
);
gradient_lst
.
push_back
(
Mat
(
descriptors
).
clone
()
);
#ifdef _DEBUG
imshow
(
"gradient"
,
get_hogdescriptor_visu
(
img
->
clone
(),
descriptors
,
size
)
);
waitKey
(
10
);
#endif
}
}
}
void
train_svm
(
const
vector
<
Mat
>
&
gradient_lst
,
const
vector
<
int
>
&
labels
)
labels
.
assign
(
pos_lst
.
size
(),
+
1
);
{
const
unsigned
int
old
=
(
unsigned
int
)
labels
.
size
();
clog
<<
"Negative images are being loaded..."
;
load_images
(
neg_dir
,
full_neg_lst
,
false
);
sample_neg
(
full_neg_lst
,
neg_lst
,
pos_image_size
);
clog
<<
"...[done]"
<<
endl
;
labels
.
insert
(
labels
.
end
(),
neg_lst
.
size
(),
-
1
);
CV_Assert
(
old
<
labels
.
size
()
);
clog
<<
"Histogram of Gradients are being calculated for positive images..."
;
computeHOGs
(
pos_image_size
,
pos_lst
,
gradient_lst
);
clog
<<
"...[done]"
<<
endl
;
clog
<<
"Histogram of Gradients are being calculated for negative images..."
;
computeHOGs
(
pos_image_size
,
neg_lst
,
gradient_lst
);
clog
<<
"...[done]"
<<
endl
;
Mat
train_data
;
Mat
train_data
;
convert_to_ml
(
gradient_lst
,
train_data
);
convert_to_ml
(
gradient_lst
,
train_data
);
clog
<<
"
Start training
..."
;
clog
<<
"
Training SVM
..."
;
Ptr
<
SVM
>
svm
=
SVM
::
create
();
Ptr
<
SVM
>
svm
=
SVM
::
create
();
/* Default values to train SVM */
/* Default values to train SVM */
svm
->
setCoef0
(
0.0
);
svm
->
setCoef0
(
0.0
);
svm
->
setDegree
(
3
);
svm
->
setDegree
(
3
);
svm
->
setTermCriteria
(
TermCriteria
(
CV_TERMCRIT_ITER
+
CV_TERMCRIT_EPS
,
1000
,
1e-3
)
);
svm
->
setTermCriteria
(
TermCriteria
(
CV_TERMCRIT_ITER
+
CV_TERMCRIT_EPS
,
1000
,
1e-3
)
);
svm
->
setGamma
(
0
);
svm
->
setGamma
(
0
);
svm
->
setKernel
(
SVM
::
LINEAR
);
svm
->
setKernel
(
SVM
::
LINEAR
);
svm
->
setNu
(
0.5
);
svm
->
setNu
(
0.5
);
svm
->
setP
(
0.1
);
// for EPSILON_SVR, epsilon in loss function?
svm
->
setP
(
0.1
);
// for EPSILON_SVR, epsilon in loss function?
svm
->
setC
(
0.01
);
// From paper, soft classifier
svm
->
setC
(
0.01
);
// From paper, soft classifier
svm
->
setType
(
SVM
::
EPS_SVR
);
// C_SVC; // EPSILON_SVR; // may be also NU_SVR; // do regression task
svm
->
setType
(
SVM
::
EPS_SVR
);
// C_SVC; // EPSILON_SVR; // may be also NU_SVR; // do regression task
svm
->
train
(
train_data
,
ROW_SAMPLE
,
Mat
(
labels
)
);
svm
->
train
(
train_data
,
ROW_SAMPLE
,
Mat
(
labels
)
);
clog
<<
"...[done]"
<<
endl
;
clog
<<
"...[done]"
<<
endl
;
svm
->
save
(
"my_people_detector.yml"
);
if
(
train_twice
)
}
void
draw_locations
(
Mat
&
img
,
const
vector
<
Rect
>
&
locations
,
const
Scalar
&
color
)
{
if
(
!
locations
.
empty
()
)
{
vector
<
Rect
>::
const_iterator
loc
=
locations
.
begin
();
vector
<
Rect
>::
const_iterator
end
=
locations
.
end
();
for
(
;
loc
!=
end
;
++
loc
)
{
{
rectangle
(
img
,
*
loc
,
color
,
2
);
clog
<<
"Testing trained detector on negative images. This may take a few minutes..."
;
}
}
}
void
test_it
(
const
Size
&
size
)
{
char
key
=
27
;
Scalar
reference
(
0
,
255
,
0
);
Scalar
trained
(
0
,
0
,
255
);
Mat
img
,
draw
;
Ptr
<
SVM
>
svm
;
HOGDescriptor
hog
;
HOGDescriptor
my_hog
;
HOGDescriptor
my_hog
;
my_hog
.
winSize
=
size
;
my_hog
.
winSize
=
pos_image_size
;
VideoCapture
video
;
vector
<
Rect
>
locations
;
// Load the trained SVM.
svm
=
StatModel
::
load
<
SVM
>
(
"my_people_detector.yml"
);
// Set the trained svm to my_hog
// Set the trained svm to my_hog
vector
<
float
>
hog_detector
;
vector
<
float
>
hog_detector
;
get_svm_detector
(
svm
,
hog_detector
);
get_svm_detector
(
svm
,
hog_detector
);
my_hog
.
setSVMDetector
(
hog_detector
);
my_hog
.
setSVMDetector
(
hog_detector
);
// Set the people detector.
hog
.
setSVMDetector
(
hog
.
getDefaultPeopleDetector
()
);
// Open the camera.
video
.
open
(
0
);
if
(
!
video
.
isOpened
()
)
{
cerr
<<
"Unable to open the device 0"
<<
endl
;
exit
(
-
1
);
}
bool
end_of_process
=
false
;
while
(
!
end_of_process
)
{
video
>>
img
;
if
(
img
.
empty
()
)
break
;
draw
=
img
.
clone
();
locations
.
clear
();
vector
<
Rect
>
detections
;
hog
.
detectMultiScale
(
img
,
locations
);
vector
<
double
>
foundWeights
;
draw_locations
(
draw
,
locations
,
reference
);
locations
.
clear
();
my_hog
.
detectMultiScale
(
img
,
locations
);
draw_locations
(
draw
,
locations
,
trained
);
imshow
(
"Video"
,
draw
);
key
=
(
char
)
waitKey
(
10
);
if
(
27
==
key
)
end_of_process
=
true
;
}
}
int
main
(
int
argc
,
char
**
argv
)
for
(
size_t
i
=
0
;
i
<
full_neg_lst
.
size
();
i
++
)
{
cv
::
CommandLineParser
parser
(
argc
,
argv
,
"{help h|| show help message}"
"{pd||pos_dir}{p||pos.lst}{nd||neg_dir}{n||neg.lst}"
);
if
(
parser
.
has
(
"help"
))
{
{
parser
.
printMessage
();
my_hog
.
detectMultiScale
(
full_neg_lst
[
i
],
detections
,
foundWeights
);
exit
(
0
);
for
(
size_t
j
=
0
;
j
<
detections
.
size
();
j
++
)
{
Mat
detection
=
full_neg_lst
[
i
](
detections
[
j
]
).
clone
();
resize
(
detection
,
detection
,
pos_image_size
);
neg_lst
.
push_back
(
detection
);
}
}
vector
<
Mat
>
pos_lst
;
if
(
visualization
)
vector
<
Mat
>
full_neg_lst
;
{
vector
<
Mat
>
neg_lst
;
for
(
size_t
j
=
0
;
j
<
detections
.
size
();
j
++
)
vector
<
Mat
>
gradient_lst
;
vector
<
int
>
labels
;
string
pos_dir
=
parser
.
get
<
string
>
(
"pd"
);
string
pos
=
parser
.
get
<
string
>
(
"p"
);
string
neg_dir
=
parser
.
get
<
string
>
(
"nd"
);
string
neg
=
parser
.
get
<
string
>
(
"n"
);
if
(
pos_dir
.
empty
()
||
pos
.
empty
()
||
neg_dir
.
empty
()
||
neg
.
empty
()
)
{
{
cout
<<
"Wrong number of parameters."
<<
endl
rectangle
(
full_neg_lst
[
i
],
detections
[
j
],
Scalar
(
0
,
255
,
0
),
2
);
<<
"Usage: "
<<
argv
[
0
]
<<
" --pd=pos_dir -p=pos.lst --nd=neg_dir -n=neg.lst"
<<
endl
}
<<
"example: "
<<
argv
[
0
]
<<
" --pd=/INRIA_dataset/ -p=Train/pos.lst --nd=/INRIA_dataset/ -n=Train/neg.lst"
<<
endl
;
imshow
(
"testing trained detector on negative images"
,
full_neg_lst
[
i
]
);
exit
(
-
1
);
waitKey
(
5
);
}
}
}
load_images
(
pos_dir
,
pos
,
pos_lst
);
clog
<<
"...[done]"
<<
endl
;
labels
.
clear
();
labels
.
assign
(
pos_lst
.
size
(),
+
1
);
labels
.
assign
(
pos_lst
.
size
(),
+
1
);
const
unsigned
int
old
=
(
unsigned
int
)
labels
.
size
();
labels
.
insert
(
labels
.
end
(),
neg_lst
.
size
(),
-
1
);
load_images
(
neg_dir
,
neg
,
full_neg_lst
);
sample_neg
(
full_neg_lst
,
neg_lst
,
Size
(
96
,
160
)
);
gradient_lst
.
clear
();
labels
.
insert
(
labels
.
end
(),
neg_lst
.
size
(),
-
1
);
clog
<<
"Histogram of Gradients are being calculated for positive images..."
;
CV_Assert
(
old
<
labels
.
size
()
);
computeHOGs
(
pos_image_size
,
pos_lst
,
gradient_lst
);
clog
<<
"...[done]"
<<
endl
;
compute_hog
(
pos_lst
,
gradient_lst
,
Size
(
96
,
160
)
);
clog
<<
"Histogram of Gradients are being calculated for negative images..."
;
compute_hog
(
neg_lst
,
gradient_lst
,
Size
(
96
,
160
)
);
computeHOGs
(
pos_image_size
,
neg_lst
,
gradient_lst
);
clog
<<
"...[done]"
<<
endl
;
train_svm
(
gradient_lst
,
labels
);
clog
<<
"Training SVM again..."
;
convert_to_ml
(
gradient_lst
,
train_data
);
svm
->
train
(
train_data
,
ROW_SAMPLE
,
Mat
(
labels
)
);
clog
<<
"...[done]"
<<
endl
;
}
vector
<
float
>
hog_detector
;
get_svm_detector
(
svm
,
hog_detector
);
HOGDescriptor
hog
;
hog
.
winSize
=
pos_image_size
;
hog
.
setSVMDetector
(
hog_detector
);
hog
.
save
(
obj_det_filename
);
test_
it
(
Size
(
96
,
160
)
);
// change with your parameters
test_
trained_detector
(
obj_det_filename
,
test_dir
,
videofilename
);
return
0
;
return
0
;
}
}
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