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
68f26cca
Commit
68f26cca
authored
Mar 21, 2012
by
Alexey Spizhevoy
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Refactored videostab module
parent
67d76691
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
176 additions
and
178 deletions
+176
-178
global_motion.hpp
...les/videostab/include/opencv2/videostab/global_motion.hpp
+0
-7
motion_stabilizing.hpp
...ideostab/include/opencv2/videostab/motion_stabilizing.hpp
+6
-2
stabilizer.hpp
modules/videostab/include/opencv2/videostab/stabilizer.hpp
+1
-1
deblurring.cpp
modules/videostab/src/deblurring.cpp
+2
-2
global_motion.cpp
modules/videostab/src/global_motion.cpp
+0
-165
inpainting.cpp
modules/videostab/src/inpainting.cpp
+31
-0
motion_stabilizing.cpp
modules/videostab/src/motion_stabilizing.cpp
+136
-1
No files found.
modules/videostab/include/opencv2/videostab/global_motion.hpp
View file @
68f26cca
...
...
@@ -131,13 +131,6 @@ private:
CV_EXPORTS
Mat
getMotion
(
int
from
,
int
to
,
const
std
::
vector
<
Mat
>
&
motions
);
CV_EXPORTS
Mat
ensureInclusionConstraint
(
const
Mat
&
M
,
Size
size
,
float
trimRatio
);
CV_EXPORTS
float
estimateOptimalTrimRatio
(
const
Mat
&
M
,
Size
size
);
// frame1 is non-transformed frame
CV_EXPORTS
float
alignementError
(
const
Mat
&
M
,
const
Mat
&
frame0
,
const
Mat
&
mask0
,
const
Mat
&
frame1
);
}
// namespace videostab
}
// namespace cv
...
...
modules/videostab/include/opencv2/videostab/motion_
filter
ing.hpp
→
modules/videostab/include/opencv2/videostab/motion_
stabiliz
ing.hpp
View file @
68f26cca
...
...
@@ -40,8 +40,8 @@
//
//M*/
#ifndef __OPENCV_VIDEOSTAB_MOTION_
FILTER
ING_HPP__
#define __OPENCV_VIDEOSTAB_MOTION_
FILTER
ING_HPP__
#ifndef __OPENCV_VIDEOSTAB_MOTION_
STABILIZ
ING_HPP__
#define __OPENCV_VIDEOSTAB_MOTION_
STABILIZ
ING_HPP__
#include <vector>
#include "opencv2/core/core.hpp"
...
...
@@ -71,6 +71,10 @@ private:
std
::
vector
<
float
>
weight_
;
};
CV_EXPORTS
Mat
ensureInclusionConstraint
(
const
Mat
&
M
,
Size
size
,
float
trimRatio
);
CV_EXPORTS
float
estimateOptimalTrimRatio
(
const
Mat
&
M
,
Size
size
);
}
// namespace videostab
}
// namespace
...
...
modules/videostab/include/opencv2/videostab/stabilizer.hpp
View file @
68f26cca
...
...
@@ -47,7 +47,7 @@
#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/videostab/global_motion.hpp"
#include "opencv2/videostab/motion_
filter
ing.hpp"
#include "opencv2/videostab/motion_
stabiliz
ing.hpp"
#include "opencv2/videostab/frame_source.hpp"
#include "opencv2/videostab/log.hpp"
#include "opencv2/videostab/inpainting.hpp"
...
...
modules/videostab/src/deblurring.cpp
View file @
68f26cca
...
...
@@ -102,8 +102,8 @@ void WeightingDeblurer::deblur(int idx, Mat &frame)
{
for
(
int
x
=
0
;
x
<
frame
.
cols
;
++
x
)
{
int
x1
=
static_cast
<
int
>
(
M
(
0
,
0
)
*
x
+
M
(
0
,
1
)
*
y
+
M
(
0
,
2
));
int
y1
=
static_cast
<
int
>
(
M
(
1
,
0
)
*
x
+
M
(
1
,
1
)
*
y
+
M
(
1
,
2
));
int
x1
=
cvRound
(
M
(
0
,
0
)
*
x
+
M
(
0
,
1
)
*
y
+
M
(
0
,
2
));
int
y1
=
cvRound
(
M
(
1
,
0
)
*
x
+
M
(
1
,
1
)
*
y
+
M
(
1
,
2
));
if
(
x1
>=
0
&&
x1
<
neighbor
.
cols
&&
y1
>=
0
&&
y1
<
neighbor
.
rows
)
{
...
...
modules/videostab/src/global_motion.cpp
View file @
68f26cca
...
...
@@ -313,170 +313,5 @@ Mat getMotion(int from, int to, const vector<Mat> &motions)
return
M
;
}
static
inline
int
areaSign
(
Point2f
a
,
Point2f
b
,
Point2f
c
)
{
double
area
=
(
b
-
a
).
cross
(
c
-
a
);
if
(
area
<
-
1e-5
)
return
-
1
;
if
(
area
>
1e-5
)
return
1
;
return
0
;
}
static
inline
bool
segmentsIntersect
(
Point2f
a
,
Point2f
b
,
Point2f
c
,
Point2f
d
)
{
return
areaSign
(
a
,
b
,
c
)
*
areaSign
(
a
,
b
,
d
)
<
0
&&
areaSign
(
c
,
d
,
a
)
*
areaSign
(
c
,
d
,
b
)
<
0
;
}
// Checks if rect a (with sides parallel to axis) is inside rect b (arbitrary).
// Rects must be passed in the [(0,0), (w,0), (w,h), (0,h)] order.
static
inline
bool
isRectInside
(
const
Point2f
a
[
4
],
const
Point2f
b
[
4
])
{
for
(
int
i
=
0
;
i
<
4
;
++
i
)
if
(
b
[
i
].
x
>
a
[
0
].
x
&&
b
[
i
].
x
<
a
[
2
].
x
&&
b
[
i
].
y
>
a
[
0
].
y
&&
b
[
i
].
y
<
a
[
2
].
y
)
return
false
;
for
(
int
i
=
0
;
i
<
4
;
++
i
)
for
(
int
j
=
0
;
j
<
4
;
++
j
)
if
(
segmentsIntersect
(
a
[
i
],
a
[(
i
+
1
)
%
4
],
b
[
j
],
b
[(
j
+
1
)
%
4
]))
return
false
;
return
true
;
}
static
inline
bool
isGoodMotion
(
const
float
M
[],
float
w
,
float
h
,
float
dx
,
float
dy
)
{
Point2f
pt
[
4
]
=
{
Point2f
(
0
,
0
),
Point2f
(
w
,
0
),
Point2f
(
w
,
h
),
Point2f
(
0
,
h
)};
Point2f
Mpt
[
4
];
for
(
int
i
=
0
;
i
<
4
;
++
i
)
{
Mpt
[
i
].
x
=
M
[
0
]
*
pt
[
i
].
x
+
M
[
1
]
*
pt
[
i
].
y
+
M
[
2
];
Mpt
[
i
].
y
=
M
[
3
]
*
pt
[
i
].
x
+
M
[
4
]
*
pt
[
i
].
y
+
M
[
5
];
}
pt
[
0
]
=
Point2f
(
dx
,
dy
);
pt
[
1
]
=
Point2f
(
w
-
dx
,
dy
);
pt
[
2
]
=
Point2f
(
w
-
dx
,
h
-
dy
);
pt
[
3
]
=
Point2f
(
dx
,
h
-
dy
);
return
isRectInside
(
pt
,
Mpt
);
}
static
inline
void
relaxMotion
(
const
float
M
[],
float
t
,
float
res
[])
{
res
[
0
]
=
M
[
0
]
*
(
1.
f
-
t
)
+
t
;
res
[
1
]
=
M
[
1
]
*
(
1.
f
-
t
);
res
[
2
]
=
M
[
2
]
*
(
1.
f
-
t
);
res
[
3
]
=
M
[
3
]
*
(
1.
f
-
t
);
res
[
4
]
=
M
[
4
]
*
(
1.
f
-
t
)
+
t
;
res
[
5
]
=
M
[
5
]
*
(
1.
f
-
t
);
}
Mat
ensureInclusionConstraint
(
const
Mat
&
M
,
Size
size
,
float
trimRatio
)
{
CV_Assert
(
M
.
size
()
==
Size
(
3
,
3
)
&&
M
.
type
()
==
CV_32F
);
const
float
w
=
static_cast
<
float
>
(
size
.
width
);
const
float
h
=
static_cast
<
float
>
(
size
.
height
);
const
float
dx
=
floor
(
w
*
trimRatio
);
const
float
dy
=
floor
(
h
*
trimRatio
);
const
float
srcM
[
6
]
=
{
M
.
at
<
float
>
(
0
,
0
),
M
.
at
<
float
>
(
0
,
1
),
M
.
at
<
float
>
(
0
,
2
),
M
.
at
<
float
>
(
1
,
0
),
M
.
at
<
float
>
(
1
,
1
),
M
.
at
<
float
>
(
1
,
2
)};
float
curM
[
6
];
float
t
=
0
;
relaxMotion
(
srcM
,
t
,
curM
);
if
(
isGoodMotion
(
curM
,
w
,
h
,
dx
,
dy
))
return
M
;
float
l
=
0
,
r
=
1
;
while
(
r
-
l
>
1e-3
f
)
{
t
=
(
l
+
r
)
*
0.5
f
;
relaxMotion
(
srcM
,
t
,
curM
);
if
(
isGoodMotion
(
curM
,
w
,
h
,
dx
,
dy
))
r
=
t
;
else
l
=
t
;
t
=
r
;
relaxMotion
(
srcM
,
r
,
curM
);
}
return
(
1
-
r
)
*
M
+
r
*
Mat
::
eye
(
3
,
3
,
CV_32F
);
}
// TODO can be estimated for O(1) time
float
estimateOptimalTrimRatio
(
const
Mat
&
M
,
Size
size
)
{
CV_Assert
(
M
.
size
()
==
Size
(
3
,
3
)
&&
M
.
type
()
==
CV_32F
);
const
float
w
=
static_cast
<
float
>
(
size
.
width
);
const
float
h
=
static_cast
<
float
>
(
size
.
height
);
Mat_
<
float
>
M_
(
M
);
Point2f
pt
[
4
]
=
{
Point2f
(
0
,
0
),
Point2f
(
w
,
0
),
Point2f
(
w
,
h
),
Point2f
(
0
,
h
)};
Point2f
Mpt
[
4
];
for
(
int
i
=
0
;
i
<
4
;
++
i
)
{
Mpt
[
i
].
x
=
M_
(
0
,
0
)
*
pt
[
i
].
x
+
M_
(
0
,
1
)
*
pt
[
i
].
y
+
M_
(
0
,
2
);
Mpt
[
i
].
y
=
M_
(
1
,
0
)
*
pt
[
i
].
x
+
M_
(
1
,
1
)
*
pt
[
i
].
y
+
M_
(
1
,
2
);
}
float
l
=
0
,
r
=
0.5
f
;
while
(
r
-
l
>
1e-3
f
)
{
float
t
=
(
l
+
r
)
*
0.5
f
;
float
dx
=
floor
(
w
*
t
);
float
dy
=
floor
(
h
*
t
);
pt
[
0
]
=
Point2f
(
dx
,
dy
);
pt
[
1
]
=
Point2f
(
w
-
dx
,
dy
);
pt
[
2
]
=
Point2f
(
w
-
dx
,
h
-
dy
);
pt
[
3
]
=
Point2f
(
dx
,
h
-
dy
);
if
(
isRectInside
(
pt
,
Mpt
))
r
=
t
;
else
l
=
t
;
}
return
r
;
}
float
alignementError
(
const
Mat
&
M
,
const
Mat
&
frame0
,
const
Mat
&
mask0
,
const
Mat
&
frame1
)
{
CV_Assert
(
frame0
.
type
()
==
CV_8UC3
&&
frame1
.
type
()
==
CV_8UC3
);
CV_Assert
(
mask0
.
type
()
==
CV_8U
&&
mask0
.
size
()
==
frame0
.
size
());
CV_Assert
(
frame0
.
size
()
==
frame1
.
size
());
CV_Assert
(
M
.
size
()
==
Size
(
3
,
3
)
&&
M
.
type
()
==
CV_32F
);
Mat_
<
uchar
>
mask0_
(
mask0
);
Mat_
<
float
>
M_
(
M
);
float
err
=
0
;
for
(
int
y0
=
0
;
y0
<
frame0
.
rows
;
++
y0
)
{
for
(
int
x0
=
0
;
x0
<
frame0
.
cols
;
++
x0
)
{
if
(
mask0_
(
y0
,
x0
))
{
int
x1
=
cvRound
(
M_
(
0
,
0
)
*
x0
+
M_
(
0
,
1
)
*
y0
+
M_
(
0
,
2
));
int
y1
=
cvRound
(
M_
(
1
,
0
)
*
x0
+
M_
(
1
,
1
)
*
y0
+
M_
(
1
,
2
));
if
(
y1
>=
0
&&
y1
<
frame1
.
rows
&&
x1
>=
0
&&
x1
<
frame1
.
cols
)
err
+=
std
::
abs
(
intensity
(
frame1
.
at
<
Point3_
<
uchar
>
>
(
y1
,
x1
))
-
intensity
(
frame0
.
at
<
Point3_
<
uchar
>
>
(
y0
,
x0
)));
}
}
}
return
err
;
}
}
// namespace videostab
}
// namespace cv
modules/videostab/src/inpainting.cpp
View file @
68f26cca
...
...
@@ -188,6 +188,37 @@ void ConsistentMosaicInpainter::inpaint(int idx, Mat &frame, Mat &mask)
}
static
float
alignementError
(
const
Mat
&
M
,
const
Mat
&
frame0
,
const
Mat
&
mask0
,
const
Mat
&
frame1
)
{
CV_Assert
(
frame0
.
type
()
==
CV_8UC3
&&
frame1
.
type
()
==
CV_8UC3
);
CV_Assert
(
mask0
.
type
()
==
CV_8U
&&
mask0
.
size
()
==
frame0
.
size
());
CV_Assert
(
frame0
.
size
()
==
frame1
.
size
());
CV_Assert
(
M
.
size
()
==
Size
(
3
,
3
)
&&
M
.
type
()
==
CV_32F
);
Mat_
<
uchar
>
mask0_
(
mask0
);
Mat_
<
float
>
M_
(
M
);
float
err
=
0
;
for
(
int
y0
=
0
;
y0
<
frame0
.
rows
;
++
y0
)
{
for
(
int
x0
=
0
;
x0
<
frame0
.
cols
;
++
x0
)
{
if
(
mask0_
(
y0
,
x0
))
{
int
x1
=
cvRound
(
M_
(
0
,
0
)
*
x0
+
M_
(
0
,
1
)
*
y0
+
M_
(
0
,
2
));
int
y1
=
cvRound
(
M_
(
1
,
0
)
*
x0
+
M_
(
1
,
1
)
*
y0
+
M_
(
1
,
2
));
if
(
y1
>=
0
&&
y1
<
frame1
.
rows
&&
x1
>=
0
&&
x1
<
frame1
.
cols
)
err
+=
std
::
abs
(
intensity
(
frame1
.
at
<
Point3_
<
uchar
>
>
(
y1
,
x1
))
-
intensity
(
frame0
.
at
<
Point3_
<
uchar
>
>
(
y0
,
x0
)));
}
}
}
return
err
;
}
class
MotionInpaintBody
{
public
:
...
...
modules/videostab/src/motion_
filter
ing.cpp
→
modules/videostab/src/motion_
stabiliz
ing.cpp
View file @
68f26cca
...
...
@@ -41,7 +41,7 @@
//M*/
#include "precomp.hpp"
#include "opencv2/videostab/motion_
filter
ing.hpp"
#include "opencv2/videostab/motion_
stabiliz
ing.hpp"
#include "opencv2/videostab/global_motion.hpp"
using
namespace
std
;
...
...
@@ -75,5 +75,140 @@ Mat GaussianMotionFilter::apply(int idx, vector<Mat> &motions) const
return
res
/
sum
;
}
static
inline
int
areaSign
(
Point2f
a
,
Point2f
b
,
Point2f
c
)
{
double
area
=
(
b
-
a
).
cross
(
c
-
a
);
if
(
area
<
-
1e-5
)
return
-
1
;
if
(
area
>
1e-5
)
return
1
;
return
0
;
}
static
inline
bool
segmentsIntersect
(
Point2f
a
,
Point2f
b
,
Point2f
c
,
Point2f
d
)
{
return
areaSign
(
a
,
b
,
c
)
*
areaSign
(
a
,
b
,
d
)
<
0
&&
areaSign
(
c
,
d
,
a
)
*
areaSign
(
c
,
d
,
b
)
<
0
;
}
// Checks if rect a (with sides parallel to axis) is inside rect b (arbitrary).
// Rects must be passed in the [(0,0), (w,0), (w,h), (0,h)] order.
static
inline
bool
isRectInside
(
const
Point2f
a
[
4
],
const
Point2f
b
[
4
])
{
for
(
int
i
=
0
;
i
<
4
;
++
i
)
if
(
b
[
i
].
x
>
a
[
0
].
x
&&
b
[
i
].
x
<
a
[
2
].
x
&&
b
[
i
].
y
>
a
[
0
].
y
&&
b
[
i
].
y
<
a
[
2
].
y
)
return
false
;
for
(
int
i
=
0
;
i
<
4
;
++
i
)
for
(
int
j
=
0
;
j
<
4
;
++
j
)
if
(
segmentsIntersect
(
a
[
i
],
a
[(
i
+
1
)
%
4
],
b
[
j
],
b
[(
j
+
1
)
%
4
]))
return
false
;
return
true
;
}
static
inline
bool
isGoodMotion
(
const
float
M
[],
float
w
,
float
h
,
float
dx
,
float
dy
)
{
Point2f
pt
[
4
]
=
{
Point2f
(
0
,
0
),
Point2f
(
w
,
0
),
Point2f
(
w
,
h
),
Point2f
(
0
,
h
)};
Point2f
Mpt
[
4
];
for
(
int
i
=
0
;
i
<
4
;
++
i
)
{
Mpt
[
i
].
x
=
M
[
0
]
*
pt
[
i
].
x
+
M
[
1
]
*
pt
[
i
].
y
+
M
[
2
];
Mpt
[
i
].
y
=
M
[
3
]
*
pt
[
i
].
x
+
M
[
4
]
*
pt
[
i
].
y
+
M
[
5
];
}
pt
[
0
]
=
Point2f
(
dx
,
dy
);
pt
[
1
]
=
Point2f
(
w
-
dx
,
dy
);
pt
[
2
]
=
Point2f
(
w
-
dx
,
h
-
dy
);
pt
[
3
]
=
Point2f
(
dx
,
h
-
dy
);
return
isRectInside
(
pt
,
Mpt
);
}
static
inline
void
relaxMotion
(
const
float
M
[],
float
t
,
float
res
[])
{
res
[
0
]
=
M
[
0
]
*
(
1.
f
-
t
)
+
t
;
res
[
1
]
=
M
[
1
]
*
(
1.
f
-
t
);
res
[
2
]
=
M
[
2
]
*
(
1.
f
-
t
);
res
[
3
]
=
M
[
3
]
*
(
1.
f
-
t
);
res
[
4
]
=
M
[
4
]
*
(
1.
f
-
t
)
+
t
;
res
[
5
]
=
M
[
5
]
*
(
1.
f
-
t
);
}
Mat
ensureInclusionConstraint
(
const
Mat
&
M
,
Size
size
,
float
trimRatio
)
{
CV_Assert
(
M
.
size
()
==
Size
(
3
,
3
)
&&
M
.
type
()
==
CV_32F
);
const
float
w
=
static_cast
<
float
>
(
size
.
width
);
const
float
h
=
static_cast
<
float
>
(
size
.
height
);
const
float
dx
=
floor
(
w
*
trimRatio
);
const
float
dy
=
floor
(
h
*
trimRatio
);
const
float
srcM
[
6
]
=
{
M
.
at
<
float
>
(
0
,
0
),
M
.
at
<
float
>
(
0
,
1
),
M
.
at
<
float
>
(
0
,
2
),
M
.
at
<
float
>
(
1
,
0
),
M
.
at
<
float
>
(
1
,
1
),
M
.
at
<
float
>
(
1
,
2
)};
float
curM
[
6
];
float
t
=
0
;
relaxMotion
(
srcM
,
t
,
curM
);
if
(
isGoodMotion
(
curM
,
w
,
h
,
dx
,
dy
))
return
M
;
float
l
=
0
,
r
=
1
;
while
(
r
-
l
>
1e-3
f
)
{
t
=
(
l
+
r
)
*
0.5
f
;
relaxMotion
(
srcM
,
t
,
curM
);
if
(
isGoodMotion
(
curM
,
w
,
h
,
dx
,
dy
))
r
=
t
;
else
l
=
t
;
t
=
r
;
relaxMotion
(
srcM
,
r
,
curM
);
}
return
(
1
-
r
)
*
M
+
r
*
Mat
::
eye
(
3
,
3
,
CV_32F
);
}
// TODO can be estimated for O(1) time
float
estimateOptimalTrimRatio
(
const
Mat
&
M
,
Size
size
)
{
CV_Assert
(
M
.
size
()
==
Size
(
3
,
3
)
&&
M
.
type
()
==
CV_32F
);
const
float
w
=
static_cast
<
float
>
(
size
.
width
);
const
float
h
=
static_cast
<
float
>
(
size
.
height
);
Mat_
<
float
>
M_
(
M
);
Point2f
pt
[
4
]
=
{
Point2f
(
0
,
0
),
Point2f
(
w
,
0
),
Point2f
(
w
,
h
),
Point2f
(
0
,
h
)};
Point2f
Mpt
[
4
];
for
(
int
i
=
0
;
i
<
4
;
++
i
)
{
Mpt
[
i
].
x
=
M_
(
0
,
0
)
*
pt
[
i
].
x
+
M_
(
0
,
1
)
*
pt
[
i
].
y
+
M_
(
0
,
2
);
Mpt
[
i
].
y
=
M_
(
1
,
0
)
*
pt
[
i
].
x
+
M_
(
1
,
1
)
*
pt
[
i
].
y
+
M_
(
1
,
2
);
}
float
l
=
0
,
r
=
0.5
f
;
while
(
r
-
l
>
1e-3
f
)
{
float
t
=
(
l
+
r
)
*
0.5
f
;
float
dx
=
floor
(
w
*
t
);
float
dy
=
floor
(
h
*
t
);
pt
[
0
]
=
Point2f
(
dx
,
dy
);
pt
[
1
]
=
Point2f
(
w
-
dx
,
dy
);
pt
[
2
]
=
Point2f
(
w
-
dx
,
h
-
dy
);
pt
[
3
]
=
Point2f
(
dx
,
h
-
dy
);
if
(
isRectInside
(
pt
,
Mpt
))
r
=
t
;
else
l
=
t
;
}
return
r
;
}
}
// namespace videostab
}
// namespace cv
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