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
17831add
Commit
17831add
authored
Jul 25, 2016
by
Vladislav Samsonov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added new method for training forest
parent
7f93d951
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
79 additions
and
67 deletions
+79
-67
sparse_matching_gpc.hpp
...s/optflow/include/opencv2/optflow/sparse_matching_gpc.hpp
+44
-29
gpc_train.cpp
modules/optflow/samples/gpc_train.cpp
+3
-7
sparse_matching_gpc.cpp
modules/optflow/src/sparse_matching_gpc.cpp
+32
-31
No files found.
modules/optflow/include/opencv2/optflow/sparse_matching_gpc.hpp
View file @
17831add
...
...
@@ -63,20 +63,41 @@ namespace optflow
struct
CV_EXPORTS_W
GPCPatchDescriptor
{
static
const
unsigned
nFeatures
=
18
;
// number of features in a patch descriptor
Vec
<
double
,
nFeatures
>
feature
;
Vec
<
double
,
nFeatures
>
feature
;
GPCPatchDescriptor
(
const
Mat
*
imgCh
,
int
i
,
int
j
);
};
typedef
std
::
pair
<
GPCPatchDescriptor
,
GPCPatchDescriptor
>
GPCPatchSample
;
typedef
std
::
vector
<
GPCPatchSample
>
GPCSamplesVector
;
typedef
std
::
pair
<
GPCPatchDescriptor
,
GPCPatchDescriptor
>
GPCPatchSample
;
typedef
std
::
vector
<
GPCPatchSample
>
GPCSamplesVector
;
/** @brief Class encapsulating training samples.
*/
class
CV_EXPORTS_W
GPCTrainingSamples
{
private
:
GPCSamplesVector
samples
;
public
:
/** @brief This function can be used to extract samples from a pair of images and a ground truth flow.
* Sizes of all the provided vectors must be equal.
*/
static
Ptr
<
GPCTrainingSamples
>
create
(
const
std
::
vector
<
String
>
&
imagesFrom
,
const
std
::
vector
<
String
>
&
imagesTo
,
const
std
::
vector
<
String
>
&
gt
);
size_t
size
()
const
{
return
samples
.
size
();
}
operator
GPCSamplesVector
()
const
{
return
samples
;
}
operator
GPCSamplesVector
&
()
{
return
samples
;
}
};
class
CV_EXPORTS_W
GPCTree
:
public
Algorithm
{
public
:
struct
Node
{
Vec
<
double
,
GPCPatchDescriptor
::
nFeatures
>
coef
;
// hyperplane coefficients
Vec
<
double
,
GPCPatchDescriptor
::
nFeatures
>
coef
;
// hyperplane coefficients
double
rhs
;
unsigned
left
;
unsigned
right
;
...
...
@@ -87,7 +108,7 @@ public:
private
:
typedef
GPCSamplesVector
::
iterator
SIter
;
std
::
vector
<
Node
>
nodes
;
std
::
vector
<
Node
>
nodes
;
bool
trainNode
(
size_t
nodeId
,
SIter
begin
,
SIter
end
,
unsigned
depth
);
...
...
@@ -98,23 +119,38 @@ public:
void
read
(
const
FileNode
&
fn
);
static
Ptr
<
GPCTree
>
create
()
{
return
makePtr
<
GPCTree
>
();
}
static
Ptr
<
GPCTree
>
create
()
{
return
makePtr
<
GPCTree
>
();
}
bool
operator
==
(
const
GPCTree
&
t
)
const
{
return
nodes
==
t
.
nodes
;
}
};
template
<
int
T
>
class
CV_EXPORTS_W
GPCForest
:
public
Algorithm
template
<
int
T
>
class
CV_EXPORTS_W
GPCForest
:
public
Algorithm
{
private
:
GPCTree
tree
[
T
];
public
:
/** @brief Train the forest using one sample set for every tree.
* Please, consider using the next method instead of this one for better quality.
*/
void
train
(
GPCSamplesVector
&
samples
)
{
for
(
int
i
=
0
;
i
<
T
;
++
i
)
tree
[
i
].
train
(
samples
);
}
/** @brief Train the forest using individual samples for each tree.
* It is generally better to use this instead of the first method.
*/
void
train
(
const
std
::
vector
<
String
>
&
imagesFrom
,
const
std
::
vector
<
String
>
&
imagesTo
,
const
std
::
vector
<
String
>
&
gt
)
{
for
(
int
i
=
0
;
i
<
T
;
++
i
)
{
Ptr
<
GPCTrainingSamples
>
samples
=
GPCTrainingSamples
::
create
(
imagesFrom
,
imagesTo
,
gt
);
// Create training set for the tree
tree
[
i
].
train
(
*
samples
);
}
}
void
write
(
FileStorage
&
fs
)
const
{
fs
<<
"ntrees"
<<
T
<<
"trees"
...
...
@@ -136,28 +172,7 @@ public:
tree
[
i
].
read
(
*
it
);
}
static
Ptr
<
GPCForest
>
create
()
{
return
makePtr
<
GPCForest
>
();
}
};
/** @brief Class encapsulating training samples.
*/
class
CV_EXPORTS_W
GPCTrainingSamples
{
private
:
GPCSamplesVector
samples
;
public
:
/** @brief This function can be used to extract samples from a pair of images and a ground truth flow.
* Sizes of all the provided vectors must be equal.
*/
static
Ptr
<
GPCTrainingSamples
>
create
(
const
std
::
vector
<
String
>
&
imagesFrom
,
const
std
::
vector
<
String
>
&
imagesTo
,
const
std
::
vector
<
String
>
&
gt
);
size_t
size
()
const
{
return
samples
.
size
();
}
operator
GPCSamplesVector
()
const
{
return
samples
;
}
operator
GPCSamplesVector
&
()
{
return
samples
;
}
static
Ptr
<
GPCForest
>
create
()
{
return
makePtr
<
GPCForest
>
();
}
};
}
...
...
modules/optflow/samples/gpc_train.cpp
View file @
17831add
...
...
@@ -14,7 +14,7 @@ int main( int argc, const char **argv )
}
nSequences
/=
3
;
std
::
vector
<
cv
::
String
>
img1
,
img2
,
gt
;
std
::
vector
<
cv
::
String
>
img1
,
img2
,
gt
;
for
(
int
i
=
0
;
i
<
nSequences
;
++
i
)
{
...
...
@@ -23,12 +23,8 @@ int main( int argc, const char **argv )
gt
.
push_back
(
argv
[
1
+
i
*
3
+
2
]
);
}
cv
::
Ptr
<
cv
::
optflow
::
GPCTrainingSamples
>
ts
=
cv
::
optflow
::
GPCTrainingSamples
::
create
(
img1
,
img2
,
gt
);
std
::
cout
<<
"Got "
<<
ts
->
size
()
<<
" samples."
<<
std
::
endl
;
cv
::
Ptr
<
cv
::
optflow
::
GPCForest
<
nTrees
>
>
forest
=
cv
::
optflow
::
GPCForest
<
nTrees
>::
create
();
forest
->
train
(
*
ts
);
cv
::
Ptr
<
cv
::
optflow
::
GPCForest
<
nTrees
>
>
forest
=
cv
::
optflow
::
GPCForest
<
nTrees
>::
create
();
forest
->
train
(
img1
,
img2
,
gt
);
forest
->
save
(
"forest.dump"
);
return
0
;
...
...
modules/optflow/src/sparse_matching_gpc.cpp
View file @
17831add
...
...
@@ -72,10 +72,10 @@ struct Magnitude
struct
PartitionPredicate1
{
Vec
<
double
,
GPCPatchDescriptor
::
nFeatures
>
coef
;
Vec
<
double
,
GPCPatchDescriptor
::
nFeatures
>
coef
;
double
rhs
;
PartitionPredicate1
(
const
Vec
<
double
,
GPCPatchDescriptor
::
nFeatures
>
&
_coef
,
double
_rhs
)
:
coef
(
_coef
),
rhs
(
_rhs
)
{}
PartitionPredicate1
(
const
Vec
<
double
,
GPCPatchDescriptor
::
nFeatures
>
&
_coef
,
double
_rhs
)
:
coef
(
_coef
),
rhs
(
_rhs
)
{}
bool
operator
()(
const
GPCPatchSample
&
sample
)
const
{
...
...
@@ -87,10 +87,10 @@ struct PartitionPredicate1
struct
PartitionPredicate2
{
Vec
<
double
,
GPCPatchDescriptor
::
nFeatures
>
coef
;
Vec
<
double
,
GPCPatchDescriptor
::
nFeatures
>
coef
;
double
rhs
;
PartitionPredicate2
(
const
Vec
<
double
,
GPCPatchDescriptor
::
nFeatures
>
&
_coef
,
double
_rhs
)
:
coef
(
_coef
),
rhs
(
_rhs
)
{}
PartitionPredicate2
(
const
Vec
<
double
,
GPCPatchDescriptor
::
nFeatures
>
&
_coef
,
double
_rhs
)
:
coef
(
_coef
),
rhs
(
_rhs
)
{}
bool
operator
()(
const
GPCPatchSample
&
sample
)
const
{
...
...
@@ -110,13 +110,14 @@ bool checkBounds( int i, int j, Size sz )
void
getTrainingSamples
(
const
Mat
&
from
,
const
Mat
&
to
,
const
Mat
&
gt
,
GPCSamplesVector
&
samples
)
{
const
Size
sz
=
gt
.
size
();
std
::
vector
<
Magnitude
>
mag
;
std
::
vector
<
Magnitude
>
mag
;
for
(
int
i
=
patchRadius
;
i
+
patchRadius
<
sz
.
height
;
++
i
)
for
(
int
j
=
patchRadius
;
j
+
patchRadius
<
sz
.
width
;
++
j
)
mag
.
push_back
(
Magnitude
(
normL2Sqr
(
gt
.
at
<
Vec2f
>
(
i
,
j
)
),
i
,
j
)
);
mag
.
push_back
(
Magnitude
(
normL2Sqr
(
gt
.
at
<
Vec2f
>
(
i
,
j
)
),
i
,
j
)
);
size_t
n
=
mag
.
size
()
*
thresholdMagnitudeFrac
;
size_t
n
=
mag
.
size
()
*
thresholdMagnitudeFrac
;
// As suggested in the paper, we discard part of the training samples
// with a small displacement and train to better distinguish hard pairs.
std
::
nth_element
(
mag
.
begin
(),
mag
.
begin
()
+
n
,
mag
.
end
()
);
mag
.
resize
(
n
);
std
::
random_shuffle
(
mag
.
begin
(),
mag
.
end
()
);
...
...
@@ -131,8 +132,8 @@ void getTrainingSamples( const Mat &from, const Mat &to, const Mat >, GPCSampl
{
int
i0
=
mag
[
k
].
i
;
int
j0
=
mag
[
k
].
j
;
int
i1
=
i0
+
cvRound
(
gt
.
at
<
Vec2f
>
(
i0
,
j0
)[
1
]
);
int
j1
=
j0
+
cvRound
(
gt
.
at
<
Vec2f
>
(
i0
,
j0
)[
0
]
);
int
i1
=
i0
+
cvRound
(
gt
.
at
<
Vec2f
>
(
i0
,
j0
)[
1
]
);
int
j1
=
j0
+
cvRound
(
gt
.
at
<
Vec2f
>
(
i0
,
j0
)[
0
]
);
if
(
checkBounds
(
i1
,
j1
,
sz
)
)
samples
.
push_back
(
std
::
make_pair
(
GPCPatchDescriptor
(
fromCh
,
i0
,
j0
),
GPCPatchDescriptor
(
toCh
,
i1
,
j1
)
)
);
}
...
...
@@ -149,7 +150,7 @@ double getRandomCauchyScalar()
/* Sample random vector from Cauchy distribution (pointwise, i.e. vector whose components are independent random
* variables from Cauchy distribution) */
void
getRandomCauchyVector
(
Vec
<
double
,
GPCPatchDescriptor
::
nFeatures
>
&
v
)
void
getRandomCauchyVector
(
Vec
<
double
,
GPCPatchDescriptor
::
nFeatures
>
&
v
)
{
for
(
unsigned
i
=
0
;
i
<
GPCPatchDescriptor
::
nFeatures
;
++
i
)
v
[
i
]
=
getRandomCauchyScalar
();
...
...
@@ -162,25 +163,25 @@ GPCPatchDescriptor::GPCPatchDescriptor( const Mat *imgCh, int i, int j )
Mat
freqDomain
;
dct
(
imgCh
[
0
](
roi
),
freqDomain
);
feature
[
0
]
=
freqDomain
.
at
<
float
>
(
0
,
0
);
feature
[
1
]
=
freqDomain
.
at
<
float
>
(
0
,
1
);
feature
[
2
]
=
freqDomain
.
at
<
float
>
(
0
,
2
);
feature
[
3
]
=
freqDomain
.
at
<
float
>
(
0
,
3
);
feature
[
0
]
=
freqDomain
.
at
<
float
>
(
0
,
0
);
feature
[
1
]
=
freqDomain
.
at
<
float
>
(
0
,
1
);
feature
[
2
]
=
freqDomain
.
at
<
float
>
(
0
,
2
);
feature
[
3
]
=
freqDomain
.
at
<
float
>
(
0
,
3
);
feature
[
4
]
=
freqDomain
.
at
<
float
>
(
1
,
0
);
feature
[
5
]
=
freqDomain
.
at
<
float
>
(
1
,
1
);
feature
[
6
]
=
freqDomain
.
at
<
float
>
(
1
,
2
);
feature
[
7
]
=
freqDomain
.
at
<
float
>
(
1
,
3
);
feature
[
4
]
=
freqDomain
.
at
<
float
>
(
1
,
0
);
feature
[
5
]
=
freqDomain
.
at
<
float
>
(
1
,
1
);
feature
[
6
]
=
freqDomain
.
at
<
float
>
(
1
,
2
);
feature
[
7
]
=
freqDomain
.
at
<
float
>
(
1
,
3
);
feature
[
8
]
=
freqDomain
.
at
<
float
>
(
2
,
0
);
feature
[
9
]
=
freqDomain
.
at
<
float
>
(
2
,
1
);
feature
[
10
]
=
freqDomain
.
at
<
float
>
(
2
,
2
);
feature
[
11
]
=
freqDomain
.
at
<
float
>
(
2
,
3
);
feature
[
8
]
=
freqDomain
.
at
<
float
>
(
2
,
0
);
feature
[
9
]
=
freqDomain
.
at
<
float
>
(
2
,
1
);
feature
[
10
]
=
freqDomain
.
at
<
float
>
(
2
,
2
);
feature
[
11
]
=
freqDomain
.
at
<
float
>
(
2
,
3
);
feature
[
12
]
=
freqDomain
.
at
<
float
>
(
3
,
0
);
feature
[
13
]
=
freqDomain
.
at
<
float
>
(
3
,
1
);
feature
[
14
]
=
freqDomain
.
at
<
float
>
(
3
,
2
);
feature
[
15
]
=
freqDomain
.
at
<
float
>
(
3
,
3
);
feature
[
12
]
=
freqDomain
.
at
<
float
>
(
3
,
0
);
feature
[
13
]
=
freqDomain
.
at
<
float
>
(
3
,
1
);
feature
[
14
]
=
freqDomain
.
at
<
float
>
(
3
,
2
);
feature
[
15
]
=
freqDomain
.
at
<
float
>
(
3
,
3
);
feature
[
16
]
=
cv
::
sum
(
imgCh
[
1
](
roi
)
)[
0
]
/
(
2
*
patchRadius
);
feature
[
17
]
=
cv
::
sum
(
imgCh
[
2
](
roi
)
)[
0
]
/
(
2
*
patchRadius
);
...
...
@@ -198,11 +199,11 @@ bool GPCTree::trainNode( size_t nodeId, SIter begin, SIter end, unsigned depth )
// Select the best hyperplane
unsigned
globalBestScore
=
0
;
std
::
vector
<
double
>
values
;
std
::
vector
<
double
>
values
;
for
(
int
j
=
0
;
j
<
globalIters
;
++
j
)
{
// Global search step
Vec
<
double
,
GPCPatchDescriptor
::
nFeatures
>
coef
;
Vec
<
double
,
GPCPatchDescriptor
::
nFeatures
>
coef
;
unsigned
localBestScore
=
0
;
getRandomCauchyVector
(
coef
);
...
...
@@ -280,13 +281,13 @@ void GPCTree::write( FileStorage &fs ) const
void
GPCTree
::
read
(
const
FileNode
&
fn
)
{
fn
[
"nodes"
]
>>
nodes
;
}
Ptr
<
GPCTrainingSamples
>
GPCTrainingSamples
::
create
(
const
std
::
vector
<
String
>
&
imagesFrom
,
const
std
::
vector
<
String
>
&
imagesTo
,
const
std
::
vector
<
String
>
&
gt
)
Ptr
<
GPCTrainingSamples
>
GPCTrainingSamples
::
create
(
const
std
::
vector
<
String
>
&
imagesFrom
,
const
std
::
vector
<
String
>
&
imagesTo
,
const
std
::
vector
<
String
>
&
gt
)
{
CV_Assert
(
imagesFrom
.
size
()
==
imagesTo
.
size
()
);
CV_Assert
(
imagesFrom
.
size
()
==
gt
.
size
()
);
Ptr
<
GPCTrainingSamples
>
ts
=
makePtr
<
GPCTrainingSamples
>
();
Ptr
<
GPCTrainingSamples
>
ts
=
makePtr
<
GPCTrainingSamples
>
();
for
(
size_t
i
=
0
;
i
<
imagesFrom
.
size
();
++
i
)
{
Mat
from
=
imread
(
imagesFrom
[
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