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
a60dc947
Commit
a60dc947
authored
Mar 19, 2012
by
Alexey Spizhevoy
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added first version of videostab module
parent
1d2c6ef4
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
23 changed files
with
1449 additions
and
1 deletion
+1449
-1
CMakeLists.txt
modules/videostab/CMakeLists.txt
+3
-0
deblurring.hpp
modules/videostab/include/opencv2/videostab/deblurring.hpp
+66
-0
fast_marching.hpp
...les/videostab/include/opencv2/videostab/fast_marching.hpp
+61
-0
fast_marching_inl.hpp
...videostab/include/opencv2/videostab/fast_marching_inl.hpp
+122
-0
frame_source.hpp
modules/videostab/include/opencv2/videostab/frame_source.hpp
+48
-0
global_motion.hpp
...les/videostab/include/opencv2/videostab/global_motion.hpp
+102
-0
log.hpp
modules/videostab/include/opencv2/videostab/log.hpp
+31
-0
motion_filtering.hpp
.../videostab/include/opencv2/videostab/motion_filtering.hpp
+35
-0
optical_flow.hpp
modules/videostab/include/opencv2/videostab/optical_flow.hpp
+72
-0
stabilizer.hpp
modules/videostab/include/opencv2/videostab/stabilizer.hpp
+95
-0
videostab.hpp
modules/videostab/include/opencv2/videostab/videostab.hpp
+6
-0
deblurring.cpp
modules/videostab/src/deblurring.cpp
+94
-0
fast_marching.cpp
modules/videostab/src/fast_marching.cpp
+99
-0
global_motion.cpp
modules/videostab/src/global_motion.cpp
+0
-0
inpainting.cpp
modules/videostab/src/inpainting.cpp
+0
-0
log.cpp
modules/videostab/src/log.cpp
+23
-0
motion_filtering.cpp
modules/videostab/src/motion_filtering.cpp
+33
-0
optical_flow.cpp
modules/videostab/src/optical_flow.cpp
+50
-0
precomp.cpp
modules/videostab/src/precomp.cpp
+1
-0
precomp.hpp
modules/videostab/src/precomp.hpp
+34
-0
stabilizer.cpp
modules/videostab/src/stabilizer.cpp
+248
-0
CMakeLists.txt
samples/cpp/CMakeLists.txt
+1
-1
videostab.cpp
samples/cpp/videostab.cpp
+225
-0
No files found.
modules/videostab/CMakeLists.txt
0 → 100644
View file @
a60dc947
set
(
the_description
"Video stabilization"
)
ocv_define_module
(
videostab opencv_imgproc opencv_features2d opencv_video OPTIONAL opencv_gpu
)
modules/videostab/include/opencv2/videostab/deblurring.hpp
0 → 100644
View file @
a60dc947
#ifndef __OPENCV_VIDEOSTAB_DEBLURRING_HPP__
#define __OPENCV_VIDEOSTAB_DEBLURRING_HPP__
#include <vector>
#include "opencv2/core/core.hpp"
namespace
cv
{
namespace
videostab
{
float
calcBlurriness
(
const
Mat
&
frame
);
class
IDeblurer
{
public
:
IDeblurer
()
:
radius_
(
0
),
frames_
(
0
),
motions_
(
0
)
{}
virtual
~
IDeblurer
()
{}
virtual
void
setRadius
(
int
val
)
{
radius_
=
val
;
}
int
radius
()
const
{
return
radius_
;
}
virtual
void
setFrames
(
const
std
::
vector
<
Mat
>
&
val
)
{
frames_
=
&
val
;
}
const
std
::
vector
<
Mat
>&
frames
()
const
{
return
*
frames_
;
}
virtual
void
setMotions
(
const
std
::
vector
<
Mat
>
&
val
)
{
motions_
=
&
val
;
}
const
std
::
vector
<
Mat
>&
motions
()
const
{
return
*
motions_
;
}
virtual
void
setBlurrinessRates
(
const
std
::
vector
<
float
>
&
val
)
{
blurrinessRates_
=
&
val
;
}
const
std
::
vector
<
float
>&
blurrinessRates
()
const
{
return
*
blurrinessRates_
;
}
virtual
void
deblur
(
int
idx
,
Mat
&
frame
)
=
0
;
protected
:
int
radius_
;
const
std
::
vector
<
Mat
>
*
frames_
;
const
std
::
vector
<
Mat
>
*
motions_
;
const
std
::
vector
<
float
>
*
blurrinessRates_
;
};
class
NullDeblurer
:
public
IDeblurer
{
public
:
virtual
void
deblur
(
int
idx
,
Mat
&
frame
)
{}
};
class
WeightingDeblurer
:
public
IDeblurer
{
public
:
WeightingDeblurer
();
void
setSensitivity
(
float
val
)
{
sensitivity_
=
val
;
}
float
sensitivity
()
const
{
return
sensitivity_
;
}
virtual
void
deblur
(
int
idx
,
Mat
&
frame
);
private
:
float
sensitivity_
;
Mat_
<
float
>
bSum_
,
gSum_
,
rSum_
,
wSum_
;
};
}
// namespace videostab
}
// namespace cv
#endif
modules/videostab/include/opencv2/videostab/fast_marching.hpp
0 → 100644
View file @
a60dc947
#ifndef __OPENCV_VIDEOSTAB_FAST_MARCHING_HPP__
#define __OPENCV_VIDEOSTAB_FAST_MARCHING_HPP__
#include <cmath>
#include <queue>
#include <algorithm>
#include "opencv2/core/core.hpp"
namespace
cv
{
namespace
videostab
{
// See http://iwi.eldoc.ub.rug.nl/FILES/root/2004/JGraphToolsTelea/2004JGraphToolsTelea.pdf
class
FastMarchingMethod
{
public
:
FastMarchingMethod
()
:
inf_
(
1e6
f
)
{}
template
<
typename
Inpaint
>
void
run
(
const
Mat
&
mask
,
Inpaint
inpaint
);
Mat
distanceMap
()
const
{
return
dist_
;
}
private
:
enum
{
INSIDE
=
0
,
BAND
=
1
,
KNOWN
=
255
};
struct
DXY
{
float
dist
;
int
x
,
y
;
DXY
()
{}
DXY
(
float
dist
,
int
x
,
int
y
)
:
dist
(
dist
),
x
(
x
),
y
(
y
)
{}
bool
operator
<
(
const
DXY
&
dxy
)
const
{
return
dist
<
dxy
.
dist
;
}
};
float
solve
(
int
x1
,
int
y1
,
int
x2
,
int
y2
)
const
;
int
&
indexOf
(
const
DXY
&
dxy
)
{
return
index_
(
dxy
.
y
,
dxy
.
x
);
}
void
heapUp
(
int
idx
);
void
heapDown
(
int
idx
);
void
heapAdd
(
const
DXY
&
dxy
);
void
heapRemoveMin
();
float
inf_
;
cv
::
Mat_
<
uchar
>
flag_
;
// flag map
cv
::
Mat_
<
float
>
dist_
;
// distance map
cv
::
Mat_
<
int
>
index_
;
// index of point in the narrow band
std
::
vector
<
DXY
>
narrowBand_
;
// narrow band heap
int
size_
;
// narrow band size
};
}
// namespace videostab
}
// namespace cv
#include "fast_marching_inl.hpp"
#endif
modules/videostab/include/opencv2/videostab/fast_marching_inl.hpp
0 → 100644
View file @
a60dc947
#ifndef __OPENCV_VIDEOSTAB_FAST_MARCHING_INL_HPP__
#define __OPENCV_VIDEOSTAB_FAST_MARCHING_INL_HPP__
#include "opencv2/videostab/fast_marching.hpp"
namespace
cv
{
namespace
videostab
{
template
<
typename
Inpaint
>
void
FastMarchingMethod
::
run
(
const
cv
::
Mat
&
mask
,
Inpaint
inpaint
)
{
using
namespace
std
;
using
namespace
cv
;
CV_Assert
(
mask
.
type
()
==
CV_8U
);
static
const
int
lut
[
4
][
2
]
=
{{
-
1
,
0
},
{
0
,
-
1
},
{
1
,
0
},
{
0
,
1
}};
mask
.
copyTo
(
flag_
);
flag_
.
create
(
mask
.
size
());
dist_
.
create
(
mask
.
size
());
index_
.
create
(
mask
.
size
());
narrowBand_
.
clear
();
size_
=
0
;
// init
for
(
int
y
=
0
;
y
<
flag_
.
rows
;
++
y
)
{
for
(
int
x
=
0
;
x
<
flag_
.
cols
;
++
x
)
{
if
(
flag_
(
y
,
x
)
==
KNOWN
)
dist_
(
y
,
x
)
=
0.
f
;
else
{
int
n
=
0
;
int
nunknown
=
0
;
for
(
int
i
=
0
;
i
<
4
;
++
i
)
{
int
xn
=
x
+
lut
[
i
][
0
];
int
yn
=
y
+
lut
[
i
][
1
];
if
(
xn
>=
0
&&
xn
<
flag_
.
cols
&&
yn
>=
0
&&
yn
<
flag_
.
rows
)
{
n
++
;
if
(
flag_
(
yn
,
xn
)
!=
KNOWN
)
nunknown
++
;
}
}
if
(
n
>
0
&&
nunknown
==
n
)
{
dist_
(
y
,
x
)
=
inf_
;
flag_
(
y
,
x
)
=
INSIDE
;
}
else
{
dist_
(
y
,
x
)
=
0.
f
;
flag_
(
y
,
x
)
=
BAND
;
inpaint
(
x
,
y
);
narrowBand_
.
push_back
(
DXY
(
0.
f
,
x
,
y
));
index_
(
y
,
x
)
=
size_
++
;
}
}
}
}
// make heap
for
(
int
i
=
size_
/
2
-
1
;
i
>=
0
;
--
i
)
heapDown
(
i
);
// main cycle
while
(
size_
>
0
)
{
int
x
=
narrowBand_
[
0
].
x
;
int
y
=
narrowBand_
[
0
].
y
;
heapRemoveMin
();
flag_
(
y
,
x
)
=
KNOWN
;
for
(
int
n
=
0
;
n
<
4
;
++
n
)
{
int
xn
=
x
+
lut
[
n
][
0
];
int
yn
=
y
+
lut
[
n
][
1
];
if
(
xn
>=
0
&&
xn
<
flag_
.
cols
&&
yn
>=
0
&&
yn
<
flag_
.
rows
&&
flag_
(
yn
,
xn
)
!=
KNOWN
)
{
dist_
(
yn
,
xn
)
=
min
(
min
(
solve
(
xn
-
1
,
yn
,
xn
,
yn
-
1
),
solve
(
xn
+
1
,
yn
,
xn
,
yn
-
1
)),
min
(
solve
(
xn
-
1
,
yn
,
xn
,
yn
+
1
),
solve
(
xn
+
1
,
yn
,
xn
,
yn
+
1
)));
if
(
flag_
(
yn
,
xn
)
==
INSIDE
)
{
flag_
(
yn
,
xn
)
=
BAND
;
inpaint
(
xn
,
yn
);
heapAdd
(
DXY
(
dist_
(
yn
,
xn
),
xn
,
yn
));
}
else
{
int
i
=
index_
(
yn
,
xn
);
if
(
dist_
(
yn
,
xn
)
<
narrowBand_
[
i
].
dist
)
{
narrowBand_
[
i
].
dist
=
dist_
(
yn
,
xn
);
heapUp
(
i
);
}
// works better if it's commented out
/*else if (dist(yn,xn) > narrowBand[i].dist)
{
narrowBand[i].dist = dist(yn,xn);
heapDown(i);
}*/
}
}
}
}
}
}
// namespace videostab
}
// namespace cv
#endif
modules/videostab/include/opencv2/videostab/frame_source.hpp
0 → 100644
View file @
a60dc947
#ifndef __OPENCV_VIDEOSTAB_FRAME_SOURCE_HPP__
#define __OPENCV_VIDEOSTAB_FRAME_SOURCE_HPP__
#include <vector>
#include <string>
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
namespace
cv
{
namespace
videostab
{
class
IFrameSource
{
public
:
virtual
~
IFrameSource
()
{}
virtual
void
reset
()
=
0
;
virtual
Mat
nextFrame
()
=
0
;
};
class
NullFrameSource
:
public
IFrameSource
{
public
:
virtual
void
reset
()
{}
virtual
Mat
nextFrame
()
{
return
Mat
();
}
};
class
VideoFileSource
:
public
IFrameSource
{
public
:
VideoFileSource
(
const
std
::
string
&
path
,
bool
volatileFrame
=
false
);
virtual
void
reset
();
virtual
Mat
nextFrame
();
int
frameCount
()
{
return
reader_
.
get
(
CV_CAP_PROP_FRAME_COUNT
);
}
double
fps
()
{
return
reader_
.
get
(
CV_CAP_PROP_FPS
);
}
private
:
std
::
string
path_
;
bool
volatileFrame_
;
VideoCapture
reader_
;
};
}
// namespace videostab
}
// namespace cv
#endif
modules/videostab/include/opencv2/videostab/global_motion.hpp
0 → 100644
View file @
a60dc947
#ifndef __OPENCV_VIDEOSTAB_GLOBAL_MOTION_HPP__
#define __OPENCV_VIDEOSTAB_GLOBAL_MOTION_HPP__
#include <vector>
#include "opencv2/core/core.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/videostab/optical_flow.hpp"
namespace
cv
{
namespace
videostab
{
enum
MotionModel
{
TRANSLATION
=
0
,
TRANSLATION_AND_SCALE
=
1
,
AFFINE
=
2
};
Mat
estimateGlobalMotionLeastSquares
(
const
std
::
vector
<
Point2f
>
&
points0
,
const
std
::
vector
<
Point2f
>
&
points1
,
int
model
=
AFFINE
,
float
*
rmse
=
0
);
struct
RansacParams
{
int
size
;
// subset size
float
thresh
;
// max error to classify as inlier
float
eps
;
// max outliers ratio
float
prob
;
// probability of success
RansacParams
(
int
size
,
float
thresh
,
float
eps
,
float
prob
)
:
size
(
size
),
thresh
(
thresh
),
eps
(
eps
),
prob
(
prob
)
{}
static
RansacParams
affine2dMotionStd
()
{
return
RansacParams
(
6
,
0.5
f
,
0.5
f
,
0.99
f
);
}
static
RansacParams
translationAndScale2dMotionStd
()
{
return
RansacParams
(
3
,
0.5
f
,
0.5
f
,
0.99
f
);
}
static
RansacParams
translationMotionStd
()
{
return
RansacParams
(
2
,
0.5
f
,
0.5
f
,
0.99
f
);
}
};
Mat
estimateGlobalMotionRobust
(
const
std
::
vector
<
Point2f
>
&
points0
,
const
std
::
vector
<
Point2f
>
&
points1
,
int
model
=
AFFINE
,
const
RansacParams
&
params
=
RansacParams
::
affine2dMotionStd
(),
float
*
rmse
=
0
,
int
*
ninliers
=
0
);
class
IGlobalMotionEstimator
{
public
:
virtual
~
IGlobalMotionEstimator
()
{}
virtual
Mat
estimate
(
const
Mat
&
frame0
,
const
Mat
&
frame1
)
=
0
;
};
class
PyrLkRobustMotionEstimator
:
public
IGlobalMotionEstimator
{
public
:
PyrLkRobustMotionEstimator
();
void
setDetector
(
Ptr
<
FeatureDetector
>
val
)
{
detector_
=
val
;
}
Ptr
<
FeatureDetector
>
detector
()
const
{
return
detector_
;
}
void
setOptFlowEstimator
(
Ptr
<
ISparseOptFlowEstimator
>
val
)
{
optFlowEstimator_
=
val
;
}
Ptr
<
ISparseOptFlowEstimator
>
optFlowEstimator
()
const
{
return
optFlowEstimator_
;
}
void
setMotionModel
(
MotionModel
val
)
{
motionModel_
=
val
;
}
MotionModel
motionModel
()
const
{
return
motionModel_
;
}
void
setRansacParams
(
const
RansacParams
&
val
)
{
ransacParams_
=
val
;
}
RansacParams
ransacParams
()
const
{
return
ransacParams_
;
}
void
setMaxRmse
(
float
val
)
{
maxRmse_
=
val
;
}
float
maxRmse
()
const
{
return
maxRmse_
;
}
void
setMinInlierRatio
(
float
val
)
{
minInlierRatio_
=
val
;
}
float
minInlierRatio
()
const
{
return
minInlierRatio_
;
}
virtual
Mat
estimate
(
const
Mat
&
frame0
,
const
Mat
&
frame1
);
private
:
Ptr
<
FeatureDetector
>
detector_
;
Ptr
<
ISparseOptFlowEstimator
>
optFlowEstimator_
;
MotionModel
motionModel_
;
RansacParams
ransacParams_
;
std
::
vector
<
uchar
>
status_
;
std
::
vector
<
KeyPoint
>
keypointsPrev_
;
std
::
vector
<
Point2f
>
pointsPrev_
,
points_
;
std
::
vector
<
Point2f
>
pointsPrevGood_
,
pointsGood_
;
float
maxRmse_
;
float
minInlierRatio_
;
};
Mat
getMotion
(
int
from
,
int
to
,
const
std
::
vector
<
Mat
>
&
motions
);
Mat
ensureInclusionConstraint
(
const
Mat
&
M
,
Size
size
,
float
trimRatio
);
float
estimateOptimalTrimRatio
(
const
Mat
&
M
,
Size
size
);
// frame1 is non-transformed frame
float
alignementError
(
const
Mat
&
M
,
const
Mat
&
frame0
,
const
Mat
&
mask0
,
const
Mat
&
frame1
);
}
// namespace videostab
}
// namespace cv
#endif
modules/videostab/include/opencv2/videostab/log.hpp
0 → 100644
View file @
a60dc947
#ifndef __OPENCV_VIDEOSTAB_LOG_HPP__
#define __OPENCV_VIDEOSTAB_LOG_HPP__
namespace
cv
{
namespace
videostab
{
class
ILog
{
public
:
virtual
~
ILog
()
{}
virtual
void
print
(
const
char
*
format
,
...)
=
0
;
};
class
NullLog
:
public
ILog
{
public
:
virtual
void
print
(
const
char
*
format
,
...)
{}
};
class
LogToStdout
:
public
ILog
{
public
:
virtual
void
print
(
const
char
*
format
,
...);
};
}
// namespace videostab
}
// namespace cv
#endif
modules/videostab/include/opencv2/videostab/motion_filtering.hpp
0 → 100644
View file @
a60dc947
#ifndef __OPENCV_VIDEOSTAB_MOTION_FILTERING_HPP__
#define __OPENCV_VIDEOSTAB_MOTION_FILTERING_HPP__
#include <vector>
#include "opencv2/core/core.hpp"
namespace
cv
{
namespace
videostab
{
class
IMotionFilter
{
public
:
virtual
~
IMotionFilter
()
{}
virtual
int
radius
()
const
=
0
;
virtual
Mat
apply
(
int
index
,
std
::
vector
<
Mat
>
&
Ms
)
const
=
0
;
};
class
GaussianMotionFilter
:
public
IMotionFilter
{
public
:
GaussianMotionFilter
(
int
radius
,
float
stdev
);
virtual
int
radius
()
const
{
return
radius_
;
}
virtual
Mat
apply
(
int
idx
,
std
::
vector
<
Mat
>
&
motions
)
const
;
private
:
int
radius_
;
std
::
vector
<
float
>
weight_
;
};
}
// namespace videostab
}
// namespace
#endif
modules/videostab/include/opencv2/videostab/optical_flow.hpp
0 → 100644
View file @
a60dc947
#ifndef __OPENCV_VIDEOSTAB_OPTICAL_FLOW_HPP__
#define __OPENCV_VIDEOSTAB_OPTICAL_FLOW_HPP__
#include "opencv2/core/core.hpp"
#include "opencv2/gpu/gpu.hpp"
namespace
cv
{
namespace
videostab
{
class
ISparseOptFlowEstimator
{
public
:
virtual
~
ISparseOptFlowEstimator
()
{}
virtual
void
run
(
InputArray
frame0
,
InputArray
frame1
,
InputArray
points0
,
InputOutputArray
points1
,
OutputArray
status
,
OutputArray
errors
)
=
0
;
};
class
IDenseOptFlowEstimator
{
public
:
virtual
~
IDenseOptFlowEstimator
()
{}
virtual
void
run
(
InputArray
frame0
,
InputArray
frame1
,
InputOutputArray
flowX
,
InputOutputArray
flowY
,
OutputArray
errors
)
=
0
;
};
class
PyrLkOptFlowEstimatorBase
{
public
:
PyrLkOptFlowEstimatorBase
()
{
setWinSize
(
Size
(
21
,
21
));
setMaxLevel
(
3
);
}
void
setWinSize
(
Size
val
)
{
winSize_
=
val
;
}
Size
winSize
()
const
{
return
winSize_
;
}
void
setMaxLevel
(
int
val
)
{
maxLevel_
=
val
;
}
int
maxLevel
()
const
{
return
maxLevel_
;
}
protected
:
Size
winSize_
;
int
maxLevel_
;
};
class
SparsePyrLkOptFlowEstimator
:
public
PyrLkOptFlowEstimatorBase
,
public
ISparseOptFlowEstimator
{
public
:
virtual
void
run
(
InputArray
frame0
,
InputArray
frame1
,
InputArray
points0
,
InputOutputArray
points1
,
OutputArray
status
,
OutputArray
errors
);
};
class
DensePyrLkOptFlowEstimatorGpu
:
public
PyrLkOptFlowEstimatorBase
,
public
IDenseOptFlowEstimator
{
public
:
DensePyrLkOptFlowEstimatorGpu
();
virtual
void
run
(
InputArray
frame0
,
InputArray
frame1
,
InputOutputArray
flowX
,
InputOutputArray
flowY
,
OutputArray
errors
);
private
:
gpu
::
PyrLKOpticalFlow
optFlowEstimator_
;
gpu
::
GpuMat
frame0_
,
frame1_
,
flowX_
,
flowY_
,
errors_
;
};
}
// namespace videostab
}
// namespace cv
#endif
modules/videostab/include/opencv2/videostab/stabilizer.hpp
0 → 100644
View file @
a60dc947
#ifndef __OPENCV_VIDEOSTAB_STABILIZER_HPP__
#define __OPENCV_VIDEOSTAB_STABILIZER_HPP__
#include <vector>
#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/videostab/global_motion.hpp"
#include "opencv2/videostab/motion_filtering.hpp"
#include "opencv2/videostab/frame_source.hpp"
#include "opencv2/videostab/log.hpp"
#include "opencv2/videostab/inpainting.hpp"
#include "opencv2/videostab/deblurring.hpp"
namespace
cv
{
namespace
videostab
{
class
Stabilizer
:
public
IFrameSource
{
public
:
Stabilizer
();
void
setLog
(
Ptr
<
ILog
>
log
)
{
log_
=
log
;
}
Ptr
<
ILog
>
log
()
const
{
return
log_
;
}
void
setFrameSource
(
Ptr
<
IFrameSource
>
val
)
{
frameSource_
=
val
;
reset
();
}
Ptr
<
IFrameSource
>
frameSource
()
const
{
return
frameSource_
;
}
void
setMotionEstimator
(
Ptr
<
IGlobalMotionEstimator
>
val
)
{
motionEstimator_
=
val
;
}
Ptr
<
IGlobalMotionEstimator
>
motionEstimator
()
const
{
return
motionEstimator_
;
}
void
setMotionFilter
(
Ptr
<
IMotionFilter
>
val
)
{
motionFilter_
=
val
;
reset
();
}
Ptr
<
IMotionFilter
>
motionFilter
()
const
{
return
motionFilter_
;
}
void
setDeblurer
(
Ptr
<
IDeblurer
>
val
)
{
deblurer_
=
val
;
reset
();
}
Ptr
<
IDeblurer
>
deblurrer
()
const
{
return
deblurer_
;
}
void
setEstimateTrimRatio
(
bool
val
)
{
mustEstimateTrimRatio_
=
val
;
reset
();
}
bool
mustEstimateTrimRatio
()
const
{
return
mustEstimateTrimRatio_
;
}
void
setTrimRatio
(
float
val
)
{
trimRatio_
=
val
;
reset
();
}
int
trimRatio
()
const
{
return
trimRatio_
;
}
void
setInclusionConstraint
(
bool
val
)
{
inclusionConstraint_
=
val
;
}
bool
inclusionConstraint
()
const
{
return
inclusionConstraint_
;
}
void
setBorderMode
(
int
val
)
{
borderMode_
=
val
;
}
int
borderMode
()
const
{
return
borderMode_
;
}
void
setInpainter
(
Ptr
<
IInpainter
>
val
)
{
inpainter_
=
val
;
reset
();
}
Ptr
<
IInpainter
>
inpainter
()
const
{
return
inpainter_
;
}
virtual
void
reset
();
virtual
Mat
nextFrame
();
private
:
void
estimateMotionsAndTrimRatio
();
void
processFirstFrame
(
Mat
&
frame
);
bool
processNextFrame
();
void
stabilizeFrame
(
int
idx
);
Ptr
<
IFrameSource
>
frameSource_
;
Ptr
<
IGlobalMotionEstimator
>
motionEstimator_
;
Ptr
<
IMotionFilter
>
motionFilter_
;
Ptr
<
IDeblurer
>
deblurer_
;
Ptr
<
IInpainter
>
inpainter_
;
bool
mustEstimateTrimRatio_
;
float
trimRatio_
;
bool
inclusionConstraint_
;
int
borderMode_
;
Ptr
<
ILog
>
log_
;
Size
frameSize_
;
Mat
frameMask_
;
int
radius_
;
int
curPos_
;
int
curStabilizedPos_
;
bool
auxPassWasDone_
;
bool
doDeblurring_
;
Mat
preProcessedFrame_
;
bool
doInpainting_
;
Mat
inpaintingMask_
;
std
::
vector
<
Mat
>
frames_
;
std
::
vector
<
Mat
>
motions_
;
// motions_[i] is the motion from i to i+1 frame
std
::
vector
<
float
>
blurrinessRates_
;
std
::
vector
<
Mat
>
stabilizedFrames_
;
std
::
vector
<
Mat
>
stabilizedMasks_
;
std
::
vector
<
Mat
>
stabilizationMotions_
;
};
}
// namespace videostab
}
// namespace cv
#endif
modules/videostab/include/opencv2/videostab/videostab.hpp
0 → 100644
View file @
a60dc947
#ifndef __OPENCV_VIDEOSTAB_HPP__
#define __OPENCV_VIDEOSTAB_HPP__
#include "opencv2/videostab/stabilizer.hpp"
#endif
modules/videostab/src/deblurring.cpp
0 → 100644
View file @
a60dc947
#include "precomp.hpp"
#include "opencv2/videostab/deblurring.hpp"
#include "opencv2/videostab/global_motion.hpp"
using
namespace
std
;
namespace
cv
{
namespace
videostab
{
float
calcBlurriness
(
const
Mat
&
frame
)
{
Mat
Gx
,
Gy
;
Sobel
(
frame
,
Gx
,
CV_32F
,
1
,
0
);
Sobel
(
frame
,
Gy
,
CV_32F
,
0
,
1
);
double
normGx
=
norm
(
Gx
);
double
normGy
=
norm
(
Gx
);
double
sumSq
=
normGx
*
normGx
+
normGy
*
normGy
;
return
1.
f
/
(
sumSq
/
frame
.
size
().
area
()
+
1e-6
);
}
WeightingDeblurer
::
WeightingDeblurer
()
{
setSensitivity
(
0.1
);
}
void
WeightingDeblurer
::
deblur
(
int
idx
,
Mat
&
frame
)
{
CV_Assert
(
frame
.
type
()
==
CV_8UC3
);
bSum_
.
create
(
frame
.
size
());
gSum_
.
create
(
frame
.
size
());
rSum_
.
create
(
frame
.
size
());
wSum_
.
create
(
frame
.
size
());
for
(
int
y
=
0
;
y
<
frame
.
rows
;
++
y
)
{
for
(
int
x
=
0
;
x
<
frame
.
cols
;
++
x
)
{
Point3_
<
uchar
>
p
=
frame
.
at
<
Point3_
<
uchar
>
>
(
y
,
x
);
bSum_
(
y
,
x
)
=
p
.
x
;
gSum_
(
y
,
x
)
=
p
.
y
;
rSum_
(
y
,
x
)
=
p
.
z
;
wSum_
(
y
,
x
)
=
1.
f
;
}
}
for
(
int
k
=
idx
-
radius_
;
k
<=
idx
+
radius_
;
++
k
)
{
const
Mat
&
neighbor
=
at
(
k
,
*
frames_
);
float
bRatio
=
at
(
idx
,
*
blurrinessRates_
)
/
at
(
k
,
*
blurrinessRates_
);
Mat_
<
float
>
M
=
getMotion
(
idx
,
k
,
*
motions_
);
if
(
bRatio
>
1.
f
)
{
for
(
int
y
=
0
;
y
<
frame
.
rows
;
++
y
)
{
for
(
int
x
=
0
;
x
<
frame
.
cols
;
++
x
)
{
int
x1
=
M
(
0
,
0
)
*
x
+
M
(
0
,
1
)
*
y
+
M
(
0
,
2
);
int
y1
=
M
(
1
,
0
)
*
x
+
M
(
1
,
1
)
*
y
+
M
(
1
,
2
);
if
(
x1
>=
0
&&
x1
<
neighbor
.
cols
&&
y1
>=
0
&&
y1
<
neighbor
.
rows
)
{
const
Point3_
<
uchar
>
&
p
=
frame
.
at
<
Point3_
<
uchar
>
>
(
y
,
x
);
const
Point3_
<
uchar
>
&
p1
=
neighbor
.
at
<
Point3_
<
uchar
>
>
(
y1
,
x1
);
float
w
=
bRatio
*
sensitivity_
/
(
sensitivity_
+
std
::
abs
(
intensity
(
p1
)
-
intensity
(
p
)));
bSum_
(
y
,
x
)
+=
w
*
p1
.
x
;
gSum_
(
y
,
x
)
+=
w
*
p1
.
y
;
rSum_
(
y
,
x
)
+=
w
*
p1
.
z
;
wSum_
(
y
,
x
)
+=
w
;
}
}
}
}
}
for
(
int
y
=
0
;
y
<
frame
.
rows
;
++
y
)
{
for
(
int
x
=
0
;
x
<
frame
.
cols
;
++
x
)
{
float
wSumInv
=
1.
f
/
wSum_
(
y
,
x
);
frame
.
at
<
Point3_
<
uchar
>
>
(
y
,
x
)
=
Point3_
<
uchar
>
(
bSum_
(
y
,
x
)
*
wSumInv
,
gSum_
(
y
,
x
)
*
wSumInv
,
rSum_
(
y
,
x
)
*
wSumInv
);
}
}
}
}
// namespace videostab
}
// namespace cv
modules/videostab/src/fast_marching.cpp
0 → 100644
View file @
a60dc947
#include "precomp.hpp"
#include "opencv2/videostab/fast_marching.hpp"
using
namespace
std
;
namespace
cv
{
namespace
videostab
{
float
FastMarchingMethod
::
solve
(
int
x1
,
int
y1
,
int
x2
,
int
y2
)
const
{
float
sol
=
inf_
;
if
(
y1
>=
0
&&
y1
<
flag_
.
rows
&&
x1
>=
0
&&
x1
<
flag_
.
cols
&&
flag_
(
y1
,
x1
)
==
KNOWN
)
{
float
t1
=
dist_
(
y1
,
x1
);
if
(
y2
>=
0
&&
y2
<
flag_
.
rows
&&
x2
>=
0
&&
x2
<
flag_
.
cols
&&
flag_
(
y2
,
x2
)
==
KNOWN
)
{
float
t2
=
dist_
(
y2
,
x2
);
float
r
=
sqrt
(
2
-
sqr
(
t1
-
t2
));
float
s
=
(
t1
+
t2
-
r
)
/
2
;
if
(
s
>=
t1
&&
s
>=
t2
)
sol
=
s
;
else
{
s
+=
r
;
if
(
s
>=
t1
&&
s
>=
t2
)
sol
=
s
;
}
}
else
sol
=
1
+
t1
;
}
else
if
(
y2
>=
0
&&
y2
<
flag_
.
rows
&&
x2
>=
0
&&
x2
<
flag_
.
cols
&&
flag_
(
y2
,
x2
)
==
KNOWN
)
sol
=
1
+
dist_
(
y2
,
x1
);
return
sol
;
}
void
FastMarchingMethod
::
heapUp
(
int
idx
)
{
int
p
=
(
idx
-
1
)
/
2
;
while
(
idx
>
0
&&
narrowBand_
[
idx
]
<
narrowBand_
[
p
])
{
std
::
swap
(
indexOf
(
narrowBand_
[
p
]),
indexOf
(
narrowBand_
[
idx
]));
std
::
swap
(
narrowBand_
[
p
],
narrowBand_
[
idx
]);
idx
=
p
;
p
=
(
idx
-
1
)
/
2
;
}
}
void
FastMarchingMethod
::
heapDown
(
int
idx
)
{
int
l
,
r
,
smallest
;
while
(
true
)
{
l
=
2
*
idx
+
1
;
r
=
2
*
idx
+
2
;
smallest
=
idx
;
if
(
l
<
size_
&&
narrowBand_
[
l
]
<
narrowBand_
[
smallest
])
smallest
=
l
;
if
(
r
<
size_
&&
narrowBand_
[
r
]
<
narrowBand_
[
smallest
])
smallest
=
r
;
if
(
smallest
==
idx
)
break
;
else
{
std
::
swap
(
indexOf
(
narrowBand_
[
idx
]),
indexOf
(
narrowBand_
[
smallest
]));
std
::
swap
(
narrowBand_
[
idx
],
narrowBand_
[
smallest
]);
idx
=
smallest
;
}
}
}
void
FastMarchingMethod
::
heapAdd
(
const
DXY
&
dxy
)
{
if
(
static_cast
<
int
>
(
narrowBand_
.
size
())
<
size_
+
1
)
narrowBand_
.
resize
(
size_
*
2
+
1
);
narrowBand_
[
size_
]
=
dxy
;
indexOf
(
dxy
)
=
size_
++
;
heapUp
(
size_
-
1
);
}
void
FastMarchingMethod
::
heapRemoveMin
()
{
if
(
size_
>
0
)
{
size_
--
;
std
::
swap
(
indexOf
(
narrowBand_
[
0
]),
indexOf
(
narrowBand_
[
size_
]));
std
::
swap
(
narrowBand_
[
0
],
narrowBand_
[
size_
]);
heapDown
(
0
);
}
}
}
// namespace videostab
}
// namespace cv
modules/videostab/src/global_motion.cpp
0 → 100644
View file @
a60dc947
This diff is collapsed.
Click to expand it.
modules/videostab/src/inpainting.cpp
0 → 100644
View file @
a60dc947
This diff is collapsed.
Click to expand it.
modules/videostab/src/log.cpp
0 → 100644
View file @
a60dc947
#include "precomp.hpp"
#include <cstdio>
#include <cstdarg>
#include "opencv2/videostab/log.hpp"
using
namespace
std
;
namespace
cv
{
namespace
videostab
{
void
LogToStdout
::
print
(
const
char
*
format
,
...)
{
va_list
args
;
va_start
(
args
,
format
);
vprintf
(
format
,
args
);
fflush
(
stdout
);
va_end
(
args
);
}
}
// namespace videostab
}
// namespace cv
modules/videostab/src/motion_filtering.cpp
0 → 100644
View file @
a60dc947
#include "precomp.hpp"
#include "opencv2/videostab/motion_filtering.hpp"
#include "opencv2/videostab/global_motion.hpp"
using
namespace
std
;
namespace
cv
{
namespace
videostab
{
GaussianMotionFilter
::
GaussianMotionFilter
(
int
radius
,
float
stdev
)
:
radius_
(
radius
)
{
float
sum
=
0
;
weight_
.
resize
(
2
*
radius_
+
1
);
for
(
int
i
=
-
radius_
;
i
<=
radius_
;
++
i
)
sum
+=
weight_
[
radius_
+
i
]
=
std
::
exp
(
-
i
*
i
/
(
stdev
*
stdev
));
for
(
int
i
=
-
radius_
;
i
<=
radius_
;
++
i
)
weight_
[
radius_
+
i
]
/=
sum
;
}
Mat
GaussianMotionFilter
::
apply
(
int
idx
,
vector
<
Mat
>
&
motions
)
const
{
const
Mat
&
cur
=
at
(
idx
,
motions
);
Mat
res
=
Mat
::
zeros
(
cur
.
size
(),
cur
.
type
());
for
(
int
i
=
-
radius_
;
i
<=
radius_
;
++
i
)
res
+=
weight_
[
radius_
+
i
]
*
getMotion
(
idx
,
idx
+
i
,
motions
);
return
res
;
}
}
// namespace videostab
}
// namespace cv
modules/videostab/src/optical_flow.cpp
0 → 100644
View file @
a60dc947
#include "precomp.hpp"
#include "opencv2/gpu/gpu.hpp"
#include "opencv2/video/video.hpp"
#include "opencv2/videostab/optical_flow.hpp"
using
namespace
std
;
namespace
cv
{
namespace
videostab
{
void
SparsePyrLkOptFlowEstimator
::
run
(
InputArray
frame0
,
InputArray
frame1
,
InputArray
points0
,
InputOutputArray
points1
,
OutputArray
status
,
OutputArray
errors
)
{
calcOpticalFlowPyrLK
(
frame0
,
frame1
,
points0
,
points1
,
status
,
errors
,
winSize_
,
maxLevel_
);
}
DensePyrLkOptFlowEstimatorGpu
::
DensePyrLkOptFlowEstimatorGpu
()
{
CV_Assert
(
gpu
::
getCudaEnabledDeviceCount
()
>
0
);
}
void
DensePyrLkOptFlowEstimatorGpu
::
run
(
InputArray
frame0
,
InputArray
frame1
,
InputOutputArray
flowX
,
InputOutputArray
flowY
,
OutputArray
errors
)
{
frame0_
.
upload
(
frame0
.
getMat
());
frame1_
.
upload
(
frame1
.
getMat
());
optFlowEstimator_
.
winSize
=
winSize_
;
optFlowEstimator_
.
maxLevel
=
maxLevel_
;
if
(
errors
.
needed
())
{
optFlowEstimator_
.
dense
(
frame0_
,
frame1_
,
flowX_
,
flowY_
,
&
errors_
);
errors_
.
download
(
errors
.
getMatRef
());
}
else
optFlowEstimator_
.
dense
(
frame0_
,
frame1_
,
flowX_
,
flowY_
);
flowX_
.
download
(
flowX
.
getMatRef
());
flowY_
.
download
(
flowY
.
getMatRef
());
}
}
// namespace videostab
}
// namespace cv
modules/videostab/src/precomp.cpp
0 → 100644
View file @
a60dc947
#include "precomp.hpp"
modules/videostab/src/precomp.hpp
0 → 100644
View file @
a60dc947
#ifndef __OPENCV_PRECOMP_HPP__
#define __OPENCV_PRECOMP_HPP__
#ifdef HAVE_CVCONFIG_H
#include "cvconfig.h"
#endif
#include <stdexcept>
#include <iostream>
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/video/video.hpp"
#include "opencv2/features2d/features2d.hpp"
inline
float
sqr
(
float
x
)
{
return
x
*
x
;
}
inline
float
intensity
(
const
cv
::
Point3_
<
uchar
>
&
bgr
)
{
return
0.3
f
*
bgr
.
x
+
0.59
f
*
bgr
.
y
+
0.11
f
*
bgr
.
z
;
}
template
<
typename
T
>
inline
T
&
at
(
int
index
,
std
::
vector
<
T
>
&
items
)
{
return
items
[
cv
::
borderInterpolate
(
index
,
items
.
size
(),
cv
::
BORDER_WRAP
)];
}
template
<
typename
T
>
inline
const
T
&
at
(
int
index
,
const
std
::
vector
<
T
>
&
items
)
{
return
items
[
cv
::
borderInterpolate
(
index
,
items
.
size
(),
cv
::
BORDER_WRAP
)];
}
#endif
modules/videostab/src/stabilizer.cpp
0 → 100644
View file @
a60dc947
#include "precomp.hpp"
#include "opencv2/videostab/stabilizer.hpp"
using
namespace
std
;
namespace
cv
{
namespace
videostab
{
Stabilizer
::
Stabilizer
()
{
setFrameSource
(
new
NullFrameSource
());
setMotionEstimator
(
new
PyrLkRobustMotionEstimator
());
setMotionFilter
(
new
GaussianMotionFilter
(
15
,
sqrt
(
15
)));
setDeblurer
(
new
NullDeblurer
());
setInpainter
(
new
NullInpainter
());
setEstimateTrimRatio
(
true
);
setTrimRatio
(
0
);
setInclusionConstraint
(
false
);
setBorderMode
(
BORDER_REPLICATE
);
setLog
(
new
NullLog
());
}
void
Stabilizer
::
reset
()
{
radius_
=
0
;
curPos_
=
-
1
;
curStabilizedPos_
=
-
1
;
auxPassWasDone_
=
false
;
frames_
.
clear
();
motions_
.
clear
();
stabilizedFrames_
.
clear
();
stabilizationMotions_
.
clear
();
doDeblurring_
=
false
;
doInpainting_
=
false
;
}
Mat
Stabilizer
::
nextFrame
()
{
if
(
mustEstimateTrimRatio_
&&
!
auxPassWasDone_
)
{
estimateMotionsAndTrimRatio
();
auxPassWasDone_
=
true
;
frameSource_
->
reset
();
}
if
(
curStabilizedPos_
==
curPos_
&&
curStabilizedPos_
!=
-
1
)
return
Mat
();
// we've processed all frames already
bool
processed
;
do
{
processed
=
processNextFrame
();
}
while
(
processed
&&
curStabilizedPos_
==
-
1
);
if
(
curStabilizedPos_
==
-
1
)
return
Mat
();
// frame source is empty
const
Mat
&
stabilizedFrame
=
at
(
curStabilizedPos_
,
stabilizedFrames_
);
int
dx
=
floor
(
trimRatio_
*
stabilizedFrame
.
cols
);
int
dy
=
floor
(
trimRatio_
*
stabilizedFrame
.
rows
);
return
stabilizedFrame
(
Rect
(
dx
,
dy
,
stabilizedFrame
.
cols
-
2
*
dx
,
stabilizedFrame
.
rows
-
2
*
dy
));
}
void
Stabilizer
::
estimateMotionsAndTrimRatio
()
{
log_
->
print
(
"estimating motions and trim ratio"
);
Size
size
;
Mat
prevFrame
,
frame
;
int
frameCount
=
0
;
while
(
!
(
frame
=
frameSource_
->
nextFrame
()).
empty
())
{
if
(
frameCount
>
0
)
motions_
.
push_back
(
motionEstimator_
->
estimate
(
prevFrame
,
frame
));
else
size
=
frame
.
size
();
prevFrame
=
frame
;
frameCount
++
;
log_
->
print
(
"."
);
}
radius_
=
motionFilter_
->
radius
();
for
(
int
i
=
0
;
i
<
radius_
;
++
i
)
motions_
.
push_back
(
Mat
::
eye
(
3
,
3
,
CV_32F
));
log_
->
print
(
"
\n
"
);
trimRatio_
=
0
;
for
(
int
i
=
0
;
i
<
frameCount
;
++
i
)
{
Mat
S
=
motionFilter_
->
apply
(
i
,
motions_
);
trimRatio_
=
std
::
max
(
trimRatio_
,
estimateOptimalTrimRatio
(
S
,
size
));
stabilizationMotions_
.
push_back
(
S
);
}
log_
->
print
(
"estimated trim ratio: %f
\n
"
,
static_cast
<
double
>
(
trimRatio_
));
}
void
Stabilizer
::
processFirstFrame
(
Mat
&
frame
)
{
log_
->
print
(
"processing frames"
);
frameSize_
=
frame
.
size
();
frameMask_
.
create
(
frameSize_
,
CV_8U
);
frameMask_
.
setTo
(
255
);
radius_
=
motionFilter_
->
radius
();
int
cacheSize
=
2
*
radius_
+
1
;
frames_
.
resize
(
cacheSize
);
stabilizedFrames_
.
resize
(
cacheSize
);
stabilizedMasks_
.
resize
(
cacheSize
);
if
(
!
auxPassWasDone_
)
{
motions_
.
resize
(
cacheSize
);
stabilizationMotions_
.
resize
(
cacheSize
);
}
for
(
int
i
=
-
radius_
;
i
<
0
;
++
i
)
{
at
(
i
,
motions_
)
=
Mat
::
eye
(
3
,
3
,
CV_32F
);
at
(
i
,
frames_
)
=
frame
;
}
at
(
0
,
frames_
)
=
frame
;
IInpainter
*
inpainter
=
static_cast
<
IInpainter
*>
(
inpainter_
);
doInpainting_
=
dynamic_cast
<
NullInpainter
*>
(
inpainter
)
==
0
;
if
(
doInpainting_
)
{
inpainter_
->
setRadius
(
radius_
);
inpainter_
->
setFrames
(
frames_
);
inpainter_
->
setMotions
(
motions_
);
inpainter_
->
setStabilizedFrames
(
stabilizedFrames_
);
inpainter_
->
setStabilizationMotions
(
stabilizationMotions_
);
}
IDeblurer
*
deblurer
=
static_cast
<
IDeblurer
*>
(
deblurer_
);
doDeblurring_
=
dynamic_cast
<
NullDeblurer
*>
(
deblurer
)
==
0
;
if
(
doDeblurring_
)
{
blurrinessRates_
.
resize
(
cacheSize
);
float
blurriness
=
calcBlurriness
(
frame
);
for
(
int
i
=
-
radius_
;
i
<=
0
;
++
i
)
at
(
i
,
blurrinessRates_
)
=
blurriness
;
deblurer_
->
setRadius
(
radius_
);
deblurer_
->
setFrames
(
frames_
);
deblurer_
->
setMotions
(
motions_
);
deblurer_
->
setBlurrinessRates
(
blurrinessRates_
);
}
}
bool
Stabilizer
::
processNextFrame
()
{
Mat
frame
=
frameSource_
->
nextFrame
();
if
(
!
frame
.
empty
())
{
curPos_
++
;
if
(
curPos_
>
0
)
{
at
(
curPos_
,
frames_
)
=
frame
;
if
(
doDeblurring_
)
at
(
curPos_
,
blurrinessRates_
)
=
calcBlurriness
(
frame
);
if
(
!
auxPassWasDone_
)
{
Mat
motionPrevToCur
=
motionEstimator_
->
estimate
(
at
(
curPos_
-
1
,
frames_
),
at
(
curPos_
,
frames_
));
at
(
curPos_
-
1
,
motions_
)
=
motionPrevToCur
;
}
if
(
curPos_
>=
radius_
)
{
curStabilizedPos_
=
curPos_
-
radius_
;
stabilizeFrame
(
curStabilizedPos_
);
}
}
else
processFirstFrame
(
frame
);
log_
->
print
(
"."
);
return
true
;
}
if
(
curStabilizedPos_
<
curPos_
)
{
curStabilizedPos_
++
;
at
(
curStabilizedPos_
+
radius_
,
frames_
)
=
at
(
curPos_
,
frames_
);
at
(
curStabilizedPos_
+
radius_
-
1
,
motions_
)
=
at
(
curPos_
-
1
,
motions_
);
stabilizeFrame
(
curStabilizedPos_
);
log_
->
print
(
"."
);
return
true
;
}
return
false
;
}
void
Stabilizer
::
stabilizeFrame
(
int
idx
)
{
Mat
stabMotion
;
if
(
!
auxPassWasDone_
)
stabMotion
=
motionFilter_
->
apply
(
idx
,
motions_
);
else
stabMotion
=
at
(
idx
,
stabilizationMotions_
);
if
(
inclusionConstraint_
&&
!
mustEstimateTrimRatio_
)
stabMotion
=
ensureInclusionConstraint
(
stabMotion
,
frameSize_
,
trimRatio_
);
at
(
idx
,
stabilizationMotions_
)
=
stabMotion
;
if
(
doDeblurring_
)
{
at
(
idx
,
frames_
).
copyTo
(
preProcessedFrame_
);
deblurer_
->
deblur
(
idx
,
preProcessedFrame_
);
}
else
preProcessedFrame_
=
at
(
idx
,
frames_
);
// apply stabilization transformation
warpAffine
(
preProcessedFrame_
,
at
(
idx
,
stabilizedFrames_
),
stabMotion
(
Rect
(
0
,
0
,
3
,
2
)),
frameSize_
,
INTER_LINEAR
,
borderMode_
);
if
(
doInpainting_
)
{
warpAffine
(
frameMask_
,
at
(
idx
,
stabilizedMasks_
),
stabMotion
(
Rect
(
0
,
0
,
3
,
2
)),
frameSize_
,
INTER_NEAREST
);
erode
(
at
(
idx
,
stabilizedMasks_
),
at
(
idx
,
stabilizedMasks_
),
Mat
());
at
(
idx
,
stabilizedMasks_
).
copyTo
(
inpaintingMask_
);
inpainter_
->
inpaint
(
idx
,
at
(
idx
,
stabilizedFrames_
),
inpaintingMask_
);
}
}
}
// namespace videostab
}
// namespace cv
samples/cpp/CMakeLists.txt
View file @
a60dc947
...
...
@@ -5,7 +5,7 @@
SET
(
OPENCV_CPP_SAMPLES_REQUIRED_DEPS opencv_core opencv_flann opencv_imgproc
opencv_highgui opencv_ml opencv_video opencv_objdetect opencv_photo opencv_nonfree
opencv_features2d opencv_calib3d opencv_legacy opencv_contrib opencv_stitching
)
opencv_features2d opencv_calib3d opencv_legacy opencv_contrib opencv_stitching
opencv_videostab
)
ocv_check_dependencies
(
${
OPENCV_CPP_SAMPLES_REQUIRED_DEPS
}
)
...
...
samples/cpp/videostab.cpp
0 → 100644
View file @
a60dc947
#include <string>
#include <iostream>
#include <sstream>
#include <stdexcept>
#include "opencv2/core/core.hpp"
#include "opencv2/video/video.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/videostab/videostab.hpp"
using
namespace
std
;
using
namespace
cv
;
using
namespace
cv
::
videostab
;
Ptr
<
Stabilizer
>
stabilizer
;
double
outputFps
;
string
outputPath
;
void
run
();
void
printHelp
();
void
run
()
{
VideoWriter
writer
;
Mat
stabilizedFrame
;
while
(
!
(
stabilizedFrame
=
stabilizer
->
nextFrame
()).
empty
())
{
if
(
!
outputPath
.
empty
())
{
if
(
!
writer
.
isOpened
())
writer
.
open
(
outputPath
,
CV_FOURCC
(
'X'
,
'V'
,
'I'
,
'D'
),
outputFps
,
stabilizedFrame
.
size
());
writer
<<
stabilizedFrame
;
}
imshow
(
"stabilizedFrame"
,
stabilizedFrame
);
char
key
=
static_cast
<
char
>
(
waitKey
(
3
));
if
(
key
==
27
)
break
;
}
cout
<<
"
\n
finished
\n
"
;
}
void
printHelp
()
{
cout
<<
"OpenCV video stabilizer.
\n
"
"Usage: videostab <file_path> [arguments]
\n\n
"
"Arguments:
\n
"
" -m, --model=(transl|transl_and_scale|affine)
\n
"
" Set motion model. The default is affine.
\n
"
" --outlier-ratio=<float_number>
\n
"
" Outliers ratio in motion estimation. The default is 0.5.
\n
"
" --min-inlier-ratio=<float_number>
\n
"
" Minimum inlier ratio to decide if estiamted motion is OK. The default is 0.1,
\n
"
" but may want to increase it.
\n
"
" -r, --radius=<int_number>
\n
"
" Set smoothing radius. The default is 15.
\n
"
" --stdev=<float_number>
\n
"
" Set smoothing weights standard deviation. The default is sqrt(radius).
\n
"
" --deblur=(yes|no)
\n
"
" Do deblurring.
\n
"
" --deblur-sens=<float_number>
\n
"
" Set deblurring sensitivity (from 0 to +inf). The default is 0.1.
\n
"
" -t, --trim-ratio=<float_number>
\n
"
" Set trimming ratio (from 0 to 0.5). The default is 0.
\n
"
" --est-trim=(yes|no)
\n
"
" Estimate trim ratio automatically. The default is yes.
\n
"
" --incl-constr=(yes|no)
\n
"
" Ensure the inclusion constraint is always satisfied. The default is no.
\n
"
" --border-mode=(replicate|const)
\n
"
" Set border extrapolation mode. The default is replicate.
\n
"
" --mosaic=(yes|no)
\n
"
" Do consistent mosaicing. The default is no.
\n
"
" --mosaic-stdev=<float_number>
\n
"
" Consistent mosaicing stdev threshold. The default is 10.
\n
"
" --motion-inpaint=(yes|no)
\n
"
" Do motion inpainting (requires GPU support). The default is no.
\n
"
" --color-inpaint=(yes|no)
\n
"
" Do color inpainting. The defailt is no.
\n
"
" -o, --output=<file_path>
\n
"
" Set output file path explicitely. The default is stabilized.avi.
\n
"
" --fps=<int_number>
\n
"
" Set output video FPS explicitely. By default the source FPS is used.
\n
"
" -h, --help
\n
"
" Print help.
\n
"
"
\n
"
;
}
int
main
(
int
argc
,
const
char
**
argv
)
{
try
{
const
char
*
keys
=
"{ 1 | | | | }"
"{ m | model | | }"
"{ | min-inlier-ratio | | }"
"{ | outlier-ratio | | }"
"{ r | radius | | }"
"{ | stdev | | }"
"{ | deblur | | }"
"{ | deblur-sens | | }"
"{ | est-trim | | }"
"{ t | trim-ratio | | }"
"{ | incl-constr | | }"
"{ | border-mode | | }"
"{ | mosaic | | }"
"{ | mosaic-stdev | | }"
"{ | motion-inpaint | | }"
"{ | color-inpaint | | }"
"{ o | output | stabilized.avi | }"
"{ | fps | | }"
"{ h | help | false | }"
;
CommandLineParser
cmd
(
argc
,
argv
,
keys
);
// parse command arguments
if
(
cmd
.
get
<
bool
>
(
"help"
))
{
printHelp
();
return
0
;
}
stabilizer
=
new
Stabilizer
();
string
inputPath
=
cmd
.
get
<
string
>
(
"1"
);
if
(
inputPath
.
empty
())
throw
runtime_error
(
"specify video file path"
);
VideoFileSource
*
frameSource
=
new
VideoFileSource
(
inputPath
);
outputFps
=
frameSource
->
fps
();
stabilizer
->
setFrameSource
(
frameSource
);
cout
<<
"frame count: "
<<
frameSource
->
frameCount
()
<<
endl
;
PyrLkRobustMotionEstimator
*
motionEstimator
=
new
PyrLkRobustMotionEstimator
();
if
(
cmd
.
get
<
string
>
(
"model"
)
==
"transl"
)
motionEstimator
->
setMotionModel
(
TRANSLATION
);
else
if
(
cmd
.
get
<
string
>
(
"model"
)
==
"transl_and_scale"
)
motionEstimator
->
setMotionModel
(
TRANSLATION_AND_SCALE
);
else
if
(
cmd
.
get
<
string
>
(
"model"
)
==
"affine"
)
motionEstimator
->
setMotionModel
(
AFFINE
);
else
if
(
!
cmd
.
get
<
string
>
(
"model"
).
empty
())
throw
runtime_error
(
"unknow motion mode: "
+
cmd
.
get
<
string
>
(
"model"
));
if
(
!
cmd
.
get
<
string
>
(
"outlier-ratio"
).
empty
())
{
RansacParams
ransacParams
=
motionEstimator
->
ransacParams
();
ransacParams
.
eps
=
atof
(
cmd
.
get
<
string
>
(
"outlier-ratio"
).
c_str
());
motionEstimator
->
setRansacParams
(
ransacParams
);
}
if
(
!
cmd
.
get
<
string
>
(
"min-inlier-ratio"
).
empty
())
motionEstimator
->
setMinInlierRatio
(
atof
(
cmd
.
get
<
string
>
(
"min-inlier-ratio"
).
c_str
()));
stabilizer
->
setMotionEstimator
(
motionEstimator
);
int
smoothRadius
=
-
1
;
float
smoothStdev
=
-
1
;
if
(
!
cmd
.
get
<
string
>
(
"radius"
).
empty
())
smoothRadius
=
atoi
(
cmd
.
get
<
string
>
(
"radius"
).
c_str
());
if
(
!
cmd
.
get
<
string
>
(
"stdev"
).
empty
())
smoothStdev
=
atof
(
cmd
.
get
<
string
>
(
"stdev"
).
c_str
());
if
(
smoothRadius
>
0
&&
smoothStdev
>
0
)
stabilizer
->
setMotionFilter
(
new
GaussianMotionFilter
(
smoothRadius
,
smoothStdev
));
else
if
(
smoothRadius
>
0
&&
smoothStdev
<
0
)
stabilizer
->
setMotionFilter
(
new
GaussianMotionFilter
(
smoothRadius
,
sqrt
(
smoothRadius
)));
if
(
cmd
.
get
<
string
>
(
"deblur"
)
==
"yes"
)
{
WeightingDeblurer
*
deblurer
=
new
WeightingDeblurer
();
if
(
!
cmd
.
get
<
string
>
(
"deblur-sens"
).
empty
())
deblurer
->
setSensitivity
(
atof
(
cmd
.
get
<
string
>
(
"deblur-sens"
).
c_str
()));
stabilizer
->
setDeblurer
(
deblurer
);
}
if
(
!
cmd
.
get
<
string
>
(
"est-trim"
).
empty
())
stabilizer
->
setEstimateTrimRatio
(
cmd
.
get
<
string
>
(
"est-trim"
)
==
"yes"
);
if
(
!
cmd
.
get
<
string
>
(
"trim-ratio"
).
empty
())
stabilizer
->
setTrimRatio
(
atof
(
cmd
.
get
<
string
>
(
"trim-ratio"
).
c_str
()));
stabilizer
->
setInclusionConstraint
(
cmd
.
get
<
string
>
(
"incl-constr"
)
==
"yes"
);
if
(
cmd
.
get
<
string
>
(
"border-mode"
)
==
"replicate"
)
stabilizer
->
setBorderMode
(
BORDER_REPLICATE
);
else
if
(
cmd
.
get
<
string
>
(
"border-mode"
)
==
"const"
)
stabilizer
->
setBorderMode
(
BORDER_CONSTANT
);
else
if
(
!
cmd
.
get
<
string
>
(
"border-mode"
).
empty
())
throw
runtime_error
(
"unknown border extrapolation mode: "
+
cmd
.
get
<
string
>
(
"border-mode"
));
InpaintingPipeline
*
inpainters
=
new
InpaintingPipeline
();
if
(
cmd
.
get
<
string
>
(
"mosaic"
)
==
"yes"
)
{
ConsistentMosaicInpainter
*
inpainter
=
new
ConsistentMosaicInpainter
();
if
(
!
cmd
.
get
<
string
>
(
"mosaic-stdev"
).
empty
())
inpainter
->
setStdevThresh
(
atof
(
cmd
.
get
<
string
>
(
"mosaic-stdev"
).
c_str
()));
inpainters
->
pushBack
(
inpainter
);
}
if
(
cmd
.
get
<
string
>
(
"motion-inpaint"
)
==
"yes"
)
inpainters
->
pushBack
(
new
MotionInpainter
());
if
(
cmd
.
get
<
string
>
(
"color-inpaint"
)
==
"yes"
)
inpainters
->
pushBack
(
new
ColorAverageInpainter
());
if
(
!
inpainters
->
empty
())
stabilizer
->
setInpainter
(
inpainters
);
stabilizer
->
setLog
(
new
LogToStdout
());
outputPath
=
cmd
.
get
<
string
>
(
"output"
);
if
(
!
cmd
.
get
<
string
>
(
"fps"
).
empty
())
outputFps
=
atoi
(
cmd
.
get
<
string
>
(
"fps"
).
c_str
());
// run video processing
run
();
}
catch
(
const
exception
&
e
)
{
cout
<<
e
.
what
()
<<
endl
;
stabilizer
.
release
();
return
-
1
;
}
stabilizer
.
release
();
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