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
f6daaccc
Commit
f6daaccc
authored
Jun 26, 2016
by
Suleyman TURKMEN
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update train_HOG.cpp
parent
0e436c3f
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
249 additions
and
318 deletions
+249
-318
train_HOG.cpp
samples/cpp/train_HOG.cpp
+249
-318
No files found.
samples/cpp/train_HOG.cpp
View file @
f6daaccc
#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
;
imshow
(
"image"
,
img
)
;
break
;
waitKey
(
1
)
;
}
}
Mat
img
=
imread
(
(
prefix
+
line
).
c_str
()
);
// load the image
img_lst
.
push_back
(
img
);
if
(
img
.
empty
()
)
// invalid image, just skip it.
continue
;
#ifdef _DEBUG
imshow
(
"image"
,
img
);
waitKey
(
10
);
#endif
img_lst
.
push_back
(
img
.
clone
()
);
}
}
}
}
...
@@ -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
++
)
cvtColor
(
img_lst
[
i
](
r
),
gray
,
COLOR_BGR2GRAY
);
{
hog
.
compute
(
gray
,
descriptors
,
Size
(
8
,
8
),
Size
(
0
,
0
)
);
// 4 cells per block ...
gradient_lst
.
push_back
(
Mat
(
descriptors
).
clone
()
);
for
(
int
cellNr
=
0
;
cellNr
<
4
;
cellNr
++
)
}
{
}
// compute corresponding cell nr
cellx
=
blockx
;
celly
=
blocky
;
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
++
)
{
{
return
0
;
gradientStrengths
[
celly
][
cellx
][
bin
]
/=
NrUpdatesForThisCell
;
}
}
}
}
}
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}"
int
drawX
=
cellx
*
cellSize
;
"{nd | | path of directory contains negative images}"
int
drawY
=
celly
*
cellSize
;
"{td | | path of directory contains test images}"
"{tv | | test video file name}"
int
mx
=
drawX
+
cellSize
/
2
;
"{dw | | width of the detector}"
int
my
=
drawY
+
cellSize
/
2
;
"{dh | | height of the detector}"
"{d |false| train twice}"
rectangle
(
visu
,
Point
((
int
)(
drawX
*
zoomFac
),
(
int
)(
drawY
*
zoomFac
)),
Point
((
int
)((
drawX
+
cellSize
)
*
zoomFac
),
(
int
)((
drawY
+
cellSize
)
*
zoomFac
)),
Scalar
(
100
,
100
,
100
),
1
);
"{t |false| test a trained detector}"
"{v |false| visualize training steps}"
// draw in each cell all 9 gradient strengths
"{fn |my_detector.yml| file name of trained SVM}"
for
(
int
bin
=
0
;
bin
<
gradientBinSize
;
bin
++
)
};
{
float
currentGradStrength
=
gradientStrengths
[
celly
][
cellx
][
bin
];
CommandLineParser
parser
(
argc
,
argv
,
keys
);
// no line to draw?
if
(
parser
.
has
(
"help"
)
)
if
(
currentGradStrength
==
0
)
{
continue
;
parser
.
printMessage
();
exit
(
0
);
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
String
pos_dir
=
parser
.
get
<
String
>
(
"pd"
);
float
x1
=
mx
-
dirVecX
*
currentGradStrength
*
maxVecLen
*
scale
;
String
neg_dir
=
parser
.
get
<
String
>
(
"nd"
);
float
y1
=
my
-
dirVecY
*
currentGradStrength
*
maxVecLen
*
scale
;
String
test_dir
=
parser
.
get
<
String
>
(
"td"
);
float
x2
=
mx
+
dirVecX
*
currentGradStrength
*
maxVecLen
*
scale
;
String
obj_det_filename
=
parser
.
get
<
String
>
(
"fn"
);
float
y2
=
my
+
dirVecY
*
currentGradStrength
*
maxVecLen
*
scale
;
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
)
{
test_trained_detector
(
obj_det_filename
,
test_dir
,
videofilename
);
exit
(
0
);
}
// 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
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
();
if
(
detector_width
&&
detector_height
)
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
();
clog
<<
"Testing trained detector on negative images. This may take a few minutes..."
;
vector
<
Rect
>::
const_iterator
end
=
locations
.
end
();
HOGDescriptor
my_hog
;
for
(
;
loc
!=
end
;
++
loc
)
my_hog
.
winSize
=
pos_image_size
;
{
rectangle
(
img
,
*
loc
,
color
,
2
);
}
}
}
void
test_it
(
const
Size
&
size
)
// Set the trained svm to my_hog
{
vector
<
float
>
hog_detector
;
char
key
=
27
;
get_svm_detector
(
svm
,
hog_detector
);
Scalar
reference
(
0
,
255
,
0
);
my_hog
.
setSVMDetector
(
hog_detector
);
Scalar
trained
(
0
,
0
,
255
);
Mat
img
,
draw
;
Ptr
<
SVM
>
svm
;
HOGDescriptor
hog
;
HOGDescriptor
my_hog
;
my_hog
.
winSize
=
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
vector
<
float
>
hog_detector
;
get_svm_detector
(
svm
,
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
;
vector
<
Rect
>
detections
;
while
(
!
end_of_process
)
vector
<
double
>
foundWeights
;
{
video
>>
img
;
if
(
img
.
empty
()
)
break
;
draw
=
img
.
clone
();
for
(
size_t
i
=
0
;
i
<
full_neg_lst
.
size
();
i
++
)
{
my_hog
.
detectMultiScale
(
full_neg_lst
[
i
],
detections
,
foundWeights
);
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
);
}
if
(
visualization
)
{
for
(
size_t
j
=
0
;
j
<
detections
.
size
();
j
++
)
{
rectangle
(
full_neg_lst
[
i
],
detections
[
j
],
Scalar
(
0
,
255
,
0
),
2
);
}
imshow
(
"testing trained detector on negative images"
,
full_neg_lst
[
i
]
);
waitKey
(
5
);
}
}
clog
<<
"...[done]"
<<
endl
;
l
ocation
s
.
clear
();
l
abel
s
.
clear
();
hog
.
detectMultiScale
(
img
,
locations
);
labels
.
assign
(
pos_lst
.
size
(),
+
1
);
draw_locations
(
draw
,
locations
,
reference
);
labels
.
insert
(
labels
.
end
(),
neg_lst
.
size
(),
-
1
);
locations
.
clear
();
gradient_lst
.
clear
();
my_hog
.
detectMultiScale
(
img
,
locations
);
clog
<<
"Histogram of Gradients are being calculated for positive images..."
;
draw_locations
(
draw
,
locations
,
trained
);
computeHOGs
(
pos_image_size
,
pos_lst
,
gradient_lst
);
clog
<<
"...[done]"
<<
endl
;
imshow
(
"Video"
,
draw
);
clog
<<
"Histogram of Gradients are being calculated for negative images..."
;
key
=
(
char
)
waitKey
(
10
);
computeHOGs
(
pos_image_size
,
neg_lst
,
gradient_lst
);
if
(
27
==
key
)
clog
<<
"...[done]"
<<
endl
;
end_of_process
=
true
;
}
}
int
main
(
int
argc
,
char
**
argv
)
clog
<<
"Training SVM again..."
;
{
convert_to_ml
(
gradient_lst
,
train_data
);
cv
::
CommandLineParser
parser
(
argc
,
argv
,
"{help h|| show help message}"
svm
->
train
(
train_data
,
ROW_SAMPLE
,
Mat
(
labels
)
);
"{pd||pos_dir}{p||pos.lst}{nd||neg_dir}{n||neg.lst}"
);
clog
<<
"...[done]"
<<
endl
;
if
(
parser
.
has
(
"help"
))
{
parser
.
printMessage
();
exit
(
0
);
}
}
vector
<
Mat
>
pos_lst
;
vector
<
Mat
>
full_neg_lst
;
vector
<
Mat
>
neg_lst
;
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
<<
"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
;
exit
(
-
1
);
}
load_images
(
pos_dir
,
pos
,
pos_lst
);
labels
.
assign
(
pos_lst
.
size
(),
+
1
);
const
unsigned
int
old
=
(
unsigned
int
)
labels
.
size
();
load_images
(
neg_dir
,
neg
,
full_neg_lst
);
sample_neg
(
full_neg_lst
,
neg_lst
,
Size
(
96
,
160
)
);
labels
.
insert
(
labels
.
end
(),
neg_lst
.
size
(),
-
1
);
CV_Assert
(
old
<
labels
.
size
()
);
compute_hog
(
pos_lst
,
gradient_lst
,
Size
(
96
,
160
)
);
compute_hog
(
neg_lst
,
gradient_lst
,
Size
(
96
,
160
)
);
train_svm
(
gradient_lst
,
labels
);
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