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
9be4701f
Commit
9be4701f
authored
Sep 05, 2011
by
Alexey Spizhevoy
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
turned opencv_stitching application to module and sample
parent
30ecb288
Hide whitespace changes
Inline
Side-by-side
Showing
26 changed files
with
1104 additions
and
1009 deletions
+1104
-1009
CMakeLists.txt
modules/stitching/CMakeLists.txt
+2
-40
autocalib.hpp
modules/stitching/include/opencv2/stitching/autocalib.hpp
+11
-6
blenders.hpp
modules/stitching/include/opencv2/stitching/blenders.hpp
+32
-27
camera.hpp
modules/stitching/include/opencv2/stitching/camera.hpp
+10
-6
exposure_compensate.hpp
...itching/include/opencv2/stitching/exposure_compensate.hpp
+62
-59
matchers.hpp
modules/stitching/include/opencv2/stitching/matchers.hpp
+10
-4
motion_estimators.hpp
...stitching/include/opencv2/stitching/motion_estimators.hpp
+14
-9
seam_finders.hpp
modules/stitching/include/opencv2/stitching/seam_finders.hpp
+68
-63
stitching.hpp
modules/stitching/include/opencv2/stitching/stitching.hpp
+54
-0
util.hpp
modules/stitching/include/opencv2/stitching/util.hpp
+9
-5
util_inl.hpp
modules/stitching/include/opencv2/stitching/util_inl.hpp
+85
-79
warpers.hpp
modules/stitching/include/opencv2/stitching/warpers.hpp
+31
-24
warpers_inl.hpp
modules/stitching/include/opencv2/stitching/warpers_inl.hpp
+18
-12
autocalib.cpp
modules/stitching/src/autocalib.cpp
+10
-7
blenders.cpp
modules/stitching/src/blenders.cpp
+8
-7
camera.cpp
modules/stitching/src/camera.cpp
+5
-3
exposure_compensate.cpp
modules/stitching/src/exposure_compensate.cpp
+5
-4
matchers.cpp
modules/stitching/src/matchers.cpp
+16
-12
motion_estimators.cpp
modules/stitching/src/motion_estimators.cpp
+5
-8
precomp.cpp
modules/stitching/src/precomp.cpp
+0
-0
precomp.hpp
modules/stitching/src/precomp.hpp
+10
-1
seam_finders.cpp
modules/stitching/src/seam_finders.cpp
+5
-3
util.cpp
modules/stitching/src/util.cpp
+6
-2
warpers.cpp
modules/stitching/src/warpers.cpp
+6
-2
CMakeLists.txt
samples/cpp/CMakeLists.txt
+4
-2
stitching.cpp
samples/cpp/stitching.cpp
+618
-624
No files found.
modules/stitching/CMakeLists.txt
View file @
9be4701f
project
(
stitching
)
include_directories
(
"
${
OpenCV_SOURCE_DIR
}
/modules/imgproc/src"
)
# For gcgraph.hpp
define_opencv_module
(
stitching opencv_core opencv_imgproc opencv_features2d opencv_calib3d opencv_gpu opencv_flann opencv_objdetect
)
include_directories
(
"
${
CMAKE_CURRENT_SOURCE_DIR
}
"
"
${
OpenCV_SOURCE_DIR
}
/modules/core/include"
"
${
OpenCV_SOURCE_DIR
}
/modules/imgproc/include"
"
${
OpenCV_SOURCE_DIR
}
/modules/objdetect/include"
"
${
OpenCV_SOURCE_DIR
}
/modules/ml/include"
"
${
OpenCV_SOURCE_DIR
}
/modules/highgui/include"
"
${
OpenCV_SOURCE_DIR
}
/modules/video/include"
"
${
OpenCV_SOURCE_DIR
}
/modules/features2d/include"
"
${
OpenCV_SOURCE_DIR
}
/modules/flann/include"
"
${
OpenCV_SOURCE_DIR
}
/modules/calib3d/include"
"
${
OpenCV_SOURCE_DIR
}
/modules/legacy/include"
"
${
OpenCV_SOURCE_DIR
}
/modules/imgproc/src"
# for gcgraph.hpp
"
${
OpenCV_SOURCE_DIR
}
/modules/gpu/include"
)
set
(
stitching_libs opencv_core opencv_imgproc opencv_highgui opencv_features2d opencv_calib3d opencv_gpu
)
FILE
(
GLOB stitching_files
"*.hpp"
"*.cpp"
)
set
(
the_target opencv_stitching
)
add_executable
(
${
the_target
}
${
stitching_files
}
)
add_dependencies
(
${
the_target
}
${
stitching_libs
}
)
set_target_properties
(
${
the_target
}
PROPERTIES
DEBUG_POSTFIX
"
${
OPENCV_DEBUG_POSTFIX
}
"
ARCHIVE_OUTPUT_DIRECTORY
${
LIBRARY_OUTPUT_PATH
}
RUNTIME_OUTPUT_DIRECTORY
${
EXECUTABLE_OUTPUT_PATH
}
INSTALL_NAME_DIR lib
OUTPUT_NAME
"opencv_stitching"
)
if
(
ENABLE_SOLUTION_FOLDERS
)
set_target_properties
(
${
the_target
}
PROPERTIES FOLDER
"applications"
)
endif
()
target_link_libraries
(
${
the_target
}
${
stitching_libs
}
)
install
(
TARGETS
${
the_target
}
RUNTIME DESTINATION bin COMPONENT main
)
modules/stitching/autocalib.hpp
→
modules/stitching/
include/opencv2/stitching/
autocalib.hpp
View file @
9be4701f
...
@@ -39,19 +39,24 @@
...
@@ -39,19 +39,24 @@
// the use of this software, even if advised of the possibility of such damage.
// the use of this software, even if advised of the possibility of such damage.
//
//
//M*/
//M*/
#ifndef __OPENCV_AUTOCALIB_HPP__
#ifndef __OPENCV_
STITCHING_
AUTOCALIB_HPP__
#define __OPENCV_AUTOCALIB_HPP__
#define __OPENCV_
STITCHING_
AUTOCALIB_HPP__
#include "
precomp
.hpp"
#include "
opencv2/core/core
.hpp"
#include "matchers.hpp"
#include "matchers.hpp"
namespace
cv
{
// See "Construction of Panoramic Image Mosaics with Global and Local Alignment"
// See "Construction of Panoramic Image Mosaics with Global and Local Alignment"
// by Heung-Yeung Shum and Richard Szeliski.
// by Heung-Yeung Shum and Richard Szeliski.
void
focalsFromHomography
(
const
cv
::
Mat
&
H
,
double
&
f0
,
double
&
f1
,
bool
&
f0_ok
,
bool
&
f1_ok
);
void
focalsFromHomography
(
const
Mat
&
H
,
double
&
f0
,
double
&
f1
,
bool
&
f0_ok
,
bool
&
f1_ok
);
void
estimateFocal
(
const
std
::
vector
<
ImageFeatures
>
&
features
,
const
std
::
vector
<
MatchesInfo
>
&
pairwise_matches
,
void
estimateFocal
(
const
std
::
vector
<
ImageFeatures
>
&
features
,
const
std
::
vector
<
MatchesInfo
>
&
pairwise_matches
,
std
::
vector
<
double
>
&
focals
);
std
::
vector
<
double
>
&
focals
);
bool
calibrateRotatingCamera
(
const
std
::
vector
<
cv
::
Mat
>
&
Hs
,
cv
::
Mat
&
K
);
bool
calibrateRotatingCamera
(
const
std
::
vector
<
Mat
>
&
Hs
,
Mat
&
K
);
}
// namespace cv
#endif // __OPENCV_AUTOCALIB_HPP__
#endif // __OPENCV_
STITCHING_
AUTOCALIB_HPP__
modules/stitching/blenders.hpp
→
modules/stitching/
include/opencv2/stitching/
blenders.hpp
View file @
9be4701f
...
@@ -39,26 +39,29 @@
...
@@ -39,26 +39,29 @@
// the use of this software, even if advised of the possibility of such damage.
// the use of this software, even if advised of the possibility of such damage.
//
//
//M*/
//M*/
#ifndef __OPENCV_BLENDERS_HPP__
#ifndef __OPENCV_
STITCHING_
BLENDERS_HPP__
#define __OPENCV_BLENDERS_HPP__
#define __OPENCV_
STITCHING_
BLENDERS_HPP__
#include "precomp.hpp"
#include "opencv2/core/core.hpp"
namespace
cv
{
// Simple blender which puts one image over another
// Simple blender which puts one image over another
class
Blender
class
Blender
{
{
public
:
public
:
enum
{
NO
,
FEATHER
,
MULTI_BAND
};
enum
{
NO
,
FEATHER
,
MULTI_BAND
};
static
cv
::
Ptr
<
Blender
>
createDefault
(
int
type
,
bool
try_gpu
=
false
);
static
Ptr
<
Blender
>
createDefault
(
int
type
,
bool
try_gpu
=
false
);
void
prepare
(
const
std
::
vector
<
cv
::
Point
>
&
corners
,
const
std
::
vector
<
cv
::
Size
>
&
sizes
);
void
prepare
(
const
std
::
vector
<
Point
>
&
corners
,
const
std
::
vector
<
Size
>
&
sizes
);
virtual
void
prepare
(
cv
::
Rect
dst_roi
);
virtual
void
prepare
(
Rect
dst_roi
);
virtual
void
feed
(
const
cv
::
Mat
&
img
,
const
cv
::
Mat
&
mask
,
cv
::
Point
tl
);
virtual
void
feed
(
const
Mat
&
img
,
const
Mat
&
mask
,
Point
tl
);
virtual
void
blend
(
cv
::
Mat
&
dst
,
cv
::
Mat
&
dst_mask
);
virtual
void
blend
(
Mat
&
dst
,
Mat
&
dst_mask
);
protected
:
protected
:
cv
::
Mat
dst_
,
dst_mask_
;
Mat
dst_
,
dst_mask_
;
cv
::
Rect
dst_roi_
;
Rect
dst_roi_
;
};
};
...
@@ -69,14 +72,14 @@ public:
...
@@ -69,14 +72,14 @@ public:
float
sharpness
()
const
{
return
sharpness_
;
}
float
sharpness
()
const
{
return
sharpness_
;
}
void
setSharpness
(
float
val
)
{
sharpness_
=
val
;
}
void
setSharpness
(
float
val
)
{
sharpness_
=
val
;
}
void
prepare
(
cv
::
Rect
dst_roi
);
void
prepare
(
Rect
dst_roi
);
void
feed
(
const
cv
::
Mat
&
img
,
const
cv
::
Mat
&
mask
,
cv
::
Point
tl
);
void
feed
(
const
Mat
&
img
,
const
Mat
&
mask
,
Point
tl
);
void
blend
(
cv
::
Mat
&
dst
,
cv
::
Mat
&
dst_mask
);
void
blend
(
Mat
&
dst
,
Mat
&
dst_mask
);
private
:
private
:
float
sharpness_
;
float
sharpness_
;
cv
::
Mat
weight_map_
;
Mat
weight_map_
;
cv
::
Mat
dst_weight_map_
;
Mat
dst_weight_map_
;
};
};
...
@@ -87,15 +90,15 @@ public:
...
@@ -87,15 +90,15 @@ public:
int
numBands
()
const
{
return
actual_num_bands_
;
}
int
numBands
()
const
{
return
actual_num_bands_
;
}
void
setNumBands
(
int
val
)
{
actual_num_bands_
=
val
;
}
void
setNumBands
(
int
val
)
{
actual_num_bands_
=
val
;
}
void
prepare
(
cv
::
Rect
dst_roi
);
void
prepare
(
Rect
dst_roi
);
void
feed
(
const
cv
::
Mat
&
img
,
const
cv
::
Mat
&
mask
,
cv
::
Point
tl
);
void
feed
(
const
Mat
&
img
,
const
Mat
&
mask
,
Point
tl
);
void
blend
(
cv
::
Mat
&
dst
,
cv
::
Mat
&
dst_mask
);
void
blend
(
Mat
&
dst
,
Mat
&
dst_mask
);
private
:
private
:
int
actual_num_bands_
,
num_bands_
;
int
actual_num_bands_
,
num_bands_
;
std
::
vector
<
cv
::
Mat
>
dst_pyr_laplace_
;
std
::
vector
<
Mat
>
dst_pyr_laplace_
;
std
::
vector
<
cv
::
Mat
>
dst_band_weights_
;
std
::
vector
<
Mat
>
dst_band_weights_
;
cv
::
Rect
dst_roi_final_
;
Rect
dst_roi_final_
;
bool
can_use_gpu_
;
bool
can_use_gpu_
;
};
};
...
@@ -103,15 +106,17 @@ private:
...
@@ -103,15 +106,17 @@ private:
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
// Auxiliary functions
// Auxiliary functions
void
normalize
(
const
cv
::
Mat
&
weight
,
cv
::
Mat
&
src
);
void
normalize
UsingWeightMap
(
const
Mat
&
weight
,
Mat
&
src
);
void
createWeightMap
(
const
cv
::
Mat
&
mask
,
float
sharpness
,
cv
::
Mat
&
weight
);
void
createWeightMap
(
const
Mat
&
mask
,
float
sharpness
,
Mat
&
weight
);
void
createLaplacePyr
(
const
cv
::
Mat
&
img
,
int
num_levels
,
std
::
vector
<
cv
::
Mat
>&
pyr
);
void
createLaplacePyr
(
const
Mat
&
img
,
int
num_levels
,
std
::
vector
<
Mat
>&
pyr
);
void
createLaplacePyrGpu
(
const
cv
::
Mat
&
img
,
int
num_levels
,
std
::
vector
<
cv
::
Mat
>&
pyr
);
void
createLaplacePyrGpu
(
const
Mat
&
img
,
int
num_levels
,
std
::
vector
<
Mat
>&
pyr
);
// Restores source image
// Restores source image
void
restoreImageFromLaplacePyr
(
std
::
vector
<
cv
::
Mat
>&
pyr
);
void
restoreImageFromLaplacePyr
(
std
::
vector
<
Mat
>&
pyr
);
}
// namespace cv
#endif // __OPENCV_BLENDERS_HPP__
#endif // __OPENCV_
STITCHING_
BLENDERS_HPP__
modules/stitching/camera.hpp
→
modules/stitching/
include/opencv2/stitching/
camera.hpp
View file @
9be4701f
...
@@ -39,11 +39,13 @@
...
@@ -39,11 +39,13 @@
// the use of this software, even if advised of the possibility of such damage.
// the use of this software, even if advised of the possibility of such damage.
//
//
//M*/
//M*/
#ifndef __OPENCV_CAMERA_HPP__
#ifndef __OPENCV_
STITCHING_
CAMERA_HPP__
#define __OPENCV_CAMERA_HPP__
#define __OPENCV_
STITCHING_
CAMERA_HPP__
#include "
precomp
.hpp"
#include "
opencv2/core/core
.hpp"
namespace
cv
{
struct
CameraParams
struct
CameraParams
{
{
...
@@ -52,8 +54,10 @@ struct CameraParams
...
@@ -52,8 +54,10 @@ struct CameraParams
const
CameraParams
&
operator
=
(
const
CameraParams
&
other
);
const
CameraParams
&
operator
=
(
const
CameraParams
&
other
);
double
focal
;
// Focal length
double
focal
;
// Focal length
cv
::
Mat
R
;
// Rotation
Mat
R
;
// Rotation
cv
::
Mat
t
;
// Translation
Mat
t
;
// Translation
};
};
#endif // #ifndef __OPENCV_CAMERA_HPP__
}
// namespace cv
#endif // #ifndef __OPENCV_STITCHING_CAMERA_HPP__
modules/stitching/exposure_compensate.hpp
→
modules/stitching/
include/opencv2/stitching/
exposure_compensate.hpp
View file @
9be4701f
...
@@ -38,61 +38,65 @@
...
@@ -38,61 +38,65 @@
// or tort (including negligence or otherwise) arising in any way out of
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
// the use of this software, even if advised of the possibility of such damage.
//
//
//M*/
//M*/
#ifndef __OPENCV_EXPOSURE_COMPENSATE_HPP__
#ifndef __OPENCV_STITCHING_EXPOSURE_COMPENSATE_HPP__
#define __OPENCV_EXPOSURE_COMPENSATE_HPP__
#define __OPENCV_STITCHING_EXPOSURE_COMPENSATE_HPP__
#include "precomp.hpp"
#include "opencv2/core/core.hpp"
namespace
cv
class
ExposureCompensator
{
{
public
:
class
ExposureCompensator
enum
{
NO
,
GAIN
,
GAIN_BLOCKS
};
{
static
cv
::
Ptr
<
ExposureCompensator
>
createDefault
(
int
type
);
public
:
enum
{
NO
,
GAIN
,
GAIN_BLOCKS
};
void
feed
(
const
std
::
vector
<
cv
::
Point
>
&
corners
,
const
std
::
vector
<
cv
::
Mat
>
&
images
,
static
Ptr
<
ExposureCompensator
>
createDefault
(
int
type
);
const
std
::
vector
<
cv
::
Mat
>
&
masks
);
virtual
void
feed
(
const
std
::
vector
<
cv
::
Point
>
&
corners
,
const
std
::
vector
<
cv
::
Mat
>
&
images
,
void
feed
(
const
std
::
vector
<
Point
>
&
corners
,
const
std
::
vector
<
Mat
>
&
images
,
const
std
::
vector
<
std
::
pair
<
cv
::
Mat
,
uchar
>
>
&
masks
)
=
0
;
const
std
::
vector
<
Mat
>
&
masks
);
virtual
void
apply
(
int
index
,
cv
::
Point
corner
,
cv
::
Mat
&
image
,
const
cv
::
Mat
&
mask
)
=
0
;
virtual
void
feed
(
const
std
::
vector
<
Point
>
&
corners
,
const
std
::
vector
<
Mat
>
&
images
,
};
const
std
::
vector
<
std
::
pair
<
Mat
,
uchar
>
>
&
masks
)
=
0
;
virtual
void
apply
(
int
index
,
Point
corner
,
Mat
&
image
,
const
Mat
&
mask
)
=
0
;
};
class
NoExposureCompensator
:
public
ExposureCompensator
{
public
:
class
NoExposureCompensator
:
public
ExposureCompensator
void
feed
(
const
std
::
vector
<
cv
::
Point
>
&
/*corners*/
,
const
std
::
vector
<
cv
::
Mat
>
&
/*images*/
,
{
const
std
::
vector
<
std
::
pair
<
cv
::
Mat
,
uchar
>
>
&
/*masks*/
)
{};
public
:
void
apply
(
int
/*index*/
,
cv
::
Point
/*corner*/
,
cv
::
Mat
&
/*image*/
,
const
cv
::
Mat
&
/*mask*/
)
{};
void
feed
(
const
std
::
vector
<
Point
>
&
/*corners*/
,
const
std
::
vector
<
Mat
>
&
/*images*/
,
};
const
std
::
vector
<
std
::
pair
<
Mat
,
uchar
>
>
&
/*masks*/
)
{};
void
apply
(
int
/*index*/
,
Point
/*corner*/
,
Mat
&
/*image*/
,
const
Mat
&
/*mask*/
)
{};
};
class
GainCompensator
:
public
ExposureCompensator
{
public
:
class
GainCompensator
:
public
ExposureCompensator
void
feed
(
const
std
::
vector
<
cv
::
Point
>
&
corners
,
const
std
::
vector
<
cv
::
Mat
>
&
images
,
{
const
std
::
vector
<
std
::
pair
<
cv
::
Mat
,
uchar
>
>
&
masks
);
public
:
void
apply
(
int
index
,
cv
::
Point
corner
,
cv
::
Mat
&
image
,
const
cv
::
Mat
&
mask
);
void
feed
(
const
std
::
vector
<
Point
>
&
corners
,
const
std
::
vector
<
Mat
>
&
images
,
std
::
vector
<
double
>
gains
()
const
;
const
std
::
vector
<
std
::
pair
<
Mat
,
uchar
>
>
&
masks
);
void
apply
(
int
index
,
Point
corner
,
Mat
&
image
,
const
Mat
&
mask
);
private
:
std
::
vector
<
double
>
gains
()
const
;
cv
::
Mat_
<
double
>
gains_
;
};
private
:
Mat_
<
double
>
gains_
;
};
class
BlocksGainCompensator
:
public
ExposureCompensator
{
public
:
class
BlocksGainCompensator
:
public
ExposureCompensator
BlocksGainCompensator
(
int
bl_width
=
32
,
int
bl_height
=
32
)
{
:
bl_width_
(
bl_width
),
bl_height_
(
bl_height
)
{}
public
:
void
feed
(
const
std
::
vector
<
cv
::
Point
>
&
corners
,
const
std
::
vector
<
cv
::
Mat
>
&
images
,
BlocksGainCompensator
(
int
bl_width
=
32
,
int
bl_height
=
32
)
const
std
::
vector
<
std
::
pair
<
cv
::
Mat
,
uchar
>
>
&
masks
);
:
bl_width_
(
bl_width
),
bl_height_
(
bl_height
)
{}
void
apply
(
int
index
,
cv
::
Point
corner
,
cv
::
Mat
&
image
,
const
cv
::
Mat
&
mask
);
void
feed
(
const
std
::
vector
<
Point
>
&
corners
,
const
std
::
vector
<
Mat
>
&
images
,
const
std
::
vector
<
std
::
pair
<
Mat
,
uchar
>
>
&
masks
);
private
:
void
apply
(
int
index
,
Point
corner
,
Mat
&
image
,
const
Mat
&
mask
);
int
bl_width_
,
bl_height_
;
std
::
vector
<
cv
::
Mat_
<
float
>
>
gain_maps_
;
private
:
};
int
bl_width_
,
bl_height_
;
std
::
vector
<
Mat_
<
float
>
>
gain_maps_
;
#endif // __OPENCV_EXPOSURE_COMPENSATE_HPP__
};
\ No newline at end of file
}
// namespace cv
#endif // __OPENCV_STITCHING_EXPOSURE_COMPENSATE_HPP__
modules/stitching/matchers.hpp
→
modules/stitching/
include/opencv2/stitching/
matchers.hpp
View file @
9be4701f
...
@@ -39,10 +39,14 @@
...
@@ -39,10 +39,14 @@
// the use of this software, even if advised of the possibility of such damage.
// the use of this software, even if advised of the possibility of such damage.
//
//
//M*/
//M*/
#ifndef __OPENCV_MATCHERS_HPP__
#ifndef __OPENCV_
STITCHING_
MATCHERS_HPP__
#define __OPENCV_MATCHERS_HPP__
#define __OPENCV_
STITCHING_
MATCHERS_HPP__
#include "precomp.hpp"
#include "opencv2/core/core.hpp"
#include "opencv2/features2d/features2d.hpp"
namespace
cv
{
struct
ImageFeatures
struct
ImageFeatures
{
{
...
@@ -136,4 +140,6 @@ protected:
...
@@ -136,4 +140,6 @@ protected:
cv
::
Ptr
<
FeaturesMatcher
>
impl_
;
cv
::
Ptr
<
FeaturesMatcher
>
impl_
;
};
};
#endif // __OPENCV_MATCHERS_HPP__
}
// namespace cv
#endif // __OPENCV_STITCHING_MATCHERS_HPP__
modules/stitching/motion_estimators.hpp
→
modules/stitching/
include/opencv2/stitching/
motion_estimators.hpp
View file @
9be4701f
...
@@ -39,14 +39,17 @@
...
@@ -39,14 +39,17 @@
// the use of this software, even if advised of the possibility of such damage.
// the use of this software, even if advised of the possibility of such damage.
//
//
//M*/
//M*/
#ifndef __OPENCV_MOTION_ESTIMATORS_HPP__
#ifndef __OPENCV_
STITCHING_
MOTION_ESTIMATORS_HPP__
#define __OPENCV_MOTION_ESTIMATORS_HPP__
#define __OPENCV_
STITCHING_
MOTION_ESTIMATORS_HPP__
#include "
precomp
.hpp"
#include "
opencv2/core/core
.hpp"
#include "matchers.hpp"
#include "matchers.hpp"
#include "util.hpp"
#include "util.hpp"
#include "camera.hpp"
#include "camera.hpp"
namespace
cv
{
class
Estimator
class
Estimator
{
{
public
:
public
:
...
@@ -88,24 +91,24 @@ private:
...
@@ -88,24 +91,24 @@ private:
void
estimate
(
const
std
::
vector
<
ImageFeatures
>
&
features
,
const
std
::
vector
<
MatchesInfo
>
&
pairwise_matches
,
void
estimate
(
const
std
::
vector
<
ImageFeatures
>
&
features
,
const
std
::
vector
<
MatchesInfo
>
&
pairwise_matches
,
std
::
vector
<
CameraParams
>
&
cameras
);
std
::
vector
<
CameraParams
>
&
cameras
);
void
calcError
(
cv
::
Mat
&
err
);
void
calcError
(
Mat
&
err
);
void
calcJacobian
();
void
calcJacobian
();
int
num_images_
;
int
num_images_
;
int
total_num_matches_
;
int
total_num_matches_
;
const
ImageFeatures
*
features_
;
const
ImageFeatures
*
features_
;
const
MatchesInfo
*
pairwise_matches_
;
const
MatchesInfo
*
pairwise_matches_
;
cv
::
Mat
cameras_
;
Mat
cameras_
;
std
::
vector
<
std
::
pair
<
int
,
int
>
>
edges_
;
std
::
vector
<
std
::
pair
<
int
,
int
>
>
edges_
;
int
cost_space_
;
int
cost_space_
;
float
conf_thresh_
;
float
conf_thresh_
;
cv
::
Mat
err_
,
err1_
,
err2_
;
Mat
err_
,
err1_
,
err2_
;
cv
::
Mat
J_
;
Mat
J_
;
};
};
void
waveCorrect
(
std
::
vector
<
cv
::
Mat
>
&
rmats
);
void
waveCorrect
(
std
::
vector
<
Mat
>
&
rmats
);
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
...
@@ -121,4 +124,6 @@ std::vector<int> leaveBiggestComponent(std::vector<ImageFeatures> &features, std
...
@@ -121,4 +124,6 @@ std::vector<int> leaveBiggestComponent(std::vector<ImageFeatures> &features, std
void
findMaxSpanningTree
(
int
num_images
,
const
std
::
vector
<
MatchesInfo
>
&
pairwise_matches
,
void
findMaxSpanningTree
(
int
num_images
,
const
std
::
vector
<
MatchesInfo
>
&
pairwise_matches
,
Graph
&
span_tree
,
std
::
vector
<
int
>
&
centers
);
Graph
&
span_tree
,
std
::
vector
<
int
>
&
centers
);
#endif // __OPENCV_MOTION_ESTIMATORS_HPP__
}
// namespace cv
#endif // __OPENCV_STITCHING_MOTION_ESTIMATORS_HPP__
modules/stitching/seam_finders.hpp
→
modules/stitching/
include/opencv2/stitching/
seam_finders.hpp
View file @
9be4701f
...
@@ -38,66 +38,71 @@
...
@@ -38,66 +38,71 @@
// or tort (including negligence or otherwise) arising in any way out of
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
// the use of this software, even if advised of the possibility of such damage.
//
//
//M*/
//M*/
#ifndef __OPENCV_SEAM_FINDERS_HPP__
#ifndef __OPENCV_STITCHING_SEAM_FINDERS_HPP__
#define __OPENCV_SEAM_FINDERS_HPP__
#define __OPENCV_STITCHING_SEAM_FINDERS_HPP__
#include "precomp.hpp"
#include "opencv2/core/core.hpp"
class
SeamFinder
namespace
cv
{
{
public
:
enum
{
NO
,
VORONOI
,
GC_COLOR
,
GC_COLOR_GRAD
};
class
SeamFinder
static
cv
::
Ptr
<
SeamFinder
>
createDefault
(
int
type
);
{
public
:
virtual
~
SeamFinder
()
{}
enum
{
NO
,
VORONOI
,
GC_COLOR
,
GC_COLOR_GRAD
};
virtual
void
find
(
const
std
::
vector
<
cv
::
Mat
>
&
src
,
const
std
::
vector
<
cv
::
Point
>
&
corners
,
static
Ptr
<
SeamFinder
>
createDefault
(
int
type
);
std
::
vector
<
cv
::
Mat
>
&
masks
)
=
0
;
};
virtual
~
SeamFinder
()
{}
virtual
void
find
(
const
std
::
vector
<
Mat
>
&
src
,
const
std
::
vector
<
Point
>
&
corners
,
std
::
vector
<
Mat
>
&
masks
)
=
0
;
class
NoSeamFinder
:
public
SeamFinder
};
{
public
:
void
find
(
const
std
::
vector
<
cv
::
Mat
>&
,
const
std
::
vector
<
cv
::
Point
>&
,
std
::
vector
<
cv
::
Mat
>&
)
{}
class
NoSeamFinder
:
public
SeamFinder
};
{
public
:
void
find
(
const
std
::
vector
<
Mat
>&
,
const
std
::
vector
<
Point
>&
,
std
::
vector
<
Mat
>&
)
{}
class
PairwiseSeamFinder
:
public
SeamFinder
};
{
public
:
virtual
void
find
(
const
std
::
vector
<
cv
::
Mat
>
&
src
,
const
std
::
vector
<
cv
::
Point
>
&
corners
,
class
PairwiseSeamFinder
:
public
SeamFinder
std
::
vector
<
cv
::
Mat
>
&
masks
);
{
public
:
protected
:
virtual
void
find
(
const
std
::
vector
<
Mat
>
&
src
,
const
std
::
vector
<
Point
>
&
corners
,
virtual
void
findInPair
(
size_t
first
,
size_t
second
,
cv
::
Rect
roi
)
=
0
;
std
::
vector
<
Mat
>
&
masks
);
std
::
vector
<
cv
::
Mat
>
images_
;
protected
:
std
::
vector
<
cv
::
Point
>
corners_
;
virtual
void
findInPair
(
size_t
first
,
size_t
second
,
Rect
roi
)
=
0
;
std
::
vector
<
cv
::
Mat
>
masks_
;
};
std
::
vector
<
Mat
>
images_
;
std
::
vector
<
Point
>
corners_
;
std
::
vector
<
Mat
>
masks_
;
class
VoronoiSeamFinder
:
public
PairwiseSeamFinder
};
{
private
:
void
findInPair
(
size_t
first
,
size_t
second
,
cv
::
Rect
roi
);
class
VoronoiSeamFinder
:
public
PairwiseSeamFinder
};
{
private
:
void
findInPair
(
size_t
first
,
size_t
second
,
Rect
roi
);
class
GraphCutSeamFinder
:
public
SeamFinder
};
{
public
:
enum
{
COST_COLOR
,
COST_COLOR_GRAD
};
class
GraphCutSeamFinder
:
public
SeamFinder
GraphCutSeamFinder
(
int
cost_type
=
COST_COLOR_GRAD
,
float
terminal_cost
=
10000.
f
,
{
float
bad_region_penalty
=
1000.
f
);
public
:
enum
{
COST_COLOR
,
COST_COLOR_GRAD
};
void
find
(
const
std
::
vector
<
cv
::
Mat
>
&
src
,
const
std
::
vector
<
cv
::
Point
>
&
corners
,
GraphCutSeamFinder
(
int
cost_type
=
COST_COLOR_GRAD
,
float
terminal_cost
=
10000.
f
,
std
::
vector
<
cv
::
Mat
>
&
masks
);
float
bad_region_penalty
=
1000.
f
);
private
:
void
find
(
const
std
::
vector
<
Mat
>
&
src
,
const
std
::
vector
<
Point
>
&
corners
,
class
Impl
;
std
::
vector
<
Mat
>
&
masks
);
cv
::
Ptr
<
Impl
>
impl_
;
};
private
:
class
Impl
;
#endif // __OPENCV_SEAM_FINDERS_HPP__
Ptr
<
Impl
>
impl_
;
};
}
// namespace cv
#endif // __OPENCV_STITCHING_SEAM_FINDERS_HPP__
modules/stitching/include/opencv2/stitching/stitching.hpp
0 → 100644
View file @
9be4701f
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#ifndef __OPENCV_STITCHING_HPP__
#define __OPENCV_STITCHING_HPP__
#include "opencv2/stitching/autocalib.hpp"
#include "opencv2/stitching/blenders.hpp"
#include "opencv2/stitching/camera.hpp"
#include "opencv2/stitching/exposure_compensate.hpp"
#include "opencv2/stitching/matchers.hpp"
#include "opencv2/stitching/motion_estimators.hpp"
#include "opencv2/stitching/seam_finders.hpp"
#include "opencv2/stitching/util.hpp"
#include "opencv2/stitching/warpers.hpp"
#endif // __OPENCV_STITCHING_HPP__
modules/stitching/util.hpp
→
modules/stitching/
include/opencv2/stitching/
util.hpp
View file @
9be4701f
...
@@ -43,7 +43,7 @@
...
@@ -43,7 +43,7 @@
#define __OPENCV_STITCHING_UTIL_HPP__
#define __OPENCV_STITCHING_UTIL_HPP__
#include <list>
#include <list>
#include "
precomp
.hpp"
#include "
opencv2/core/core
.hpp"
#define ENABLE_LOG 1
#define ENABLE_LOG 1
...
@@ -56,6 +56,8 @@
...
@@ -56,6 +56,8 @@
#define LOGLN(msg) LOG(msg << std::endl)
#define LOGLN(msg) LOG(msg << std::endl)
namespace
cv
{
class
DisjointSets
class
DisjointSets
{
{
...
@@ -104,14 +106,16 @@ private:
...
@@ -104,14 +106,16 @@ private:
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
// Auxiliary functions
// Auxiliary functions
bool
overlapRoi
(
cv
::
Point
tl1
,
cv
::
Point
tl2
,
cv
::
Size
sz1
,
cv
::
Size
sz2
,
cv
::
Rect
&
roi
);
bool
overlapRoi
(
Point
tl1
,
Point
tl2
,
Size
sz1
,
Size
sz2
,
Rect
&
roi
);
cv
::
Rect
resultRoi
(
const
std
::
vector
<
cv
::
Point
>
&
corners
,
const
std
::
vector
<
cv
::
Mat
>
&
images
);
Rect
resultRoi
(
const
std
::
vector
<
Point
>
&
corners
,
const
std
::
vector
<
Mat
>
&
images
);
cv
::
Rect
resultRoi
(
const
std
::
vector
<
cv
::
Point
>
&
corners
,
const
std
::
vector
<
cv
::
Size
>
&
sizes
);
Rect
resultRoi
(
const
std
::
vector
<
Point
>
&
corners
,
const
std
::
vector
<
Size
>
&
sizes
);
cv
::
Point
resultTl
(
const
std
::
vector
<
cv
::
Point
>
&
corners
);
Point
resultTl
(
const
std
::
vector
<
Point
>
&
corners
);
// Returns random 'count' element subset of the {0,1,...,size-1} set
// Returns random 'count' element subset of the {0,1,...,size-1} set
void
selectRandomSubset
(
int
count
,
int
size
,
std
::
vector
<
int
>
&
subset
);
void
selectRandomSubset
(
int
count
,
int
size
,
std
::
vector
<
int
>
&
subset
);
}
// namespace cv
#include "util_inl.hpp"
#include "util_inl.hpp"
#endif // __OPENCV_STITCHING_UTIL_HPP__
#endif // __OPENCV_STITCHING_UTIL_HPP__
modules/stitching/util_inl.hpp
→
modules/stitching/
include/opencv2/stitching/
util_inl.hpp
View file @
9be4701f
...
@@ -38,82 +38,88 @@
...
@@ -38,82 +38,88 @@
// or tort (including negligence or otherwise) arising in any way out of
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
// the use of this software, even if advised of the possibility of such damage.
//
//
//M*/
//M*/
#ifndef __OPENCV_STITCHING_UTIL_INL_HPP__
#ifndef __OPENCV_STITCHING_UTIL_INL_HPP__
#define __OPENCV_STITCHING_UTIL_INL_HPP__
#define __OPENCV_STITCHING_UTIL_INL_HPP__
#include <queue>
#include <queue>
#include "util.hpp" // Make your IDE see declarations
#include "opencv2/core/core.hpp"
#include "util.hpp" // Make your IDE see declarations
template
<
typename
B
>
B
Graph
::
forEach
(
B
body
)
const
namespace
cv
{
{
for
(
int
i
=
0
;
i
<
numVertices
();
++
i
)
{
template
<
typename
B
>
std
::
list
<
GraphEdge
>::
const_iterator
edge
=
edges_
[
i
].
begin
();
B
Graph
::
forEach
(
B
body
)
const
for
(;
edge
!=
edges_
[
i
].
end
();
++
edge
)
{
body
(
*
edge
);
for
(
int
i
=
0
;
i
<
numVertices
();
++
i
)
}
{
return
body
;
std
::
list
<
GraphEdge
>::
const_iterator
edge
=
edges_
[
i
].
begin
();
}
for
(;
edge
!=
edges_
[
i
].
end
();
++
edge
)
body
(
*
edge
);
}
template
<
typename
B
>
return
body
;
B
Graph
::
walkBreadthFirst
(
int
from
,
B
body
)
const
}
{
std
::
vector
<
bool
>
was
(
numVertices
(),
false
);
std
::
queue
<
int
>
vertices
;
template
<
typename
B
>
B
Graph
::
walkBreadthFirst
(
int
from
,
B
body
)
const
was
[
from
]
=
true
;
{
vertices
.
push
(
from
);
std
::
vector
<
bool
>
was
(
numVertices
(),
false
);
std
::
queue
<
int
>
vertices
;
while
(
!
vertices
.
empty
())
{
was
[
from
]
=
true
;
int
vertex
=
vertices
.
front
();
vertices
.
push
(
from
);
vertices
.
pop
();
while
(
!
vertices
.
empty
())
std
::
list
<
GraphEdge
>::
const_iterator
edge
=
edges_
[
vertex
].
begin
();
{
for
(;
edge
!=
edges_
[
vertex
].
end
();
++
edge
)
int
vertex
=
vertices
.
front
();
{
vertices
.
pop
();
if
(
!
was
[
edge
->
to
])
{
std
::
list
<
GraphEdge
>::
const_iterator
edge
=
edges_
[
vertex
].
begin
();
body
(
*
edge
);
for
(;
edge
!=
edges_
[
vertex
].
end
();
++
edge
)
was
[
edge
->
to
]
=
true
;
{
vertices
.
push
(
edge
->
to
);
if
(
!
was
[
edge
->
to
])
}
{
}
body
(
*
edge
);
}
was
[
edge
->
to
]
=
true
;
vertices
.
push
(
edge
->
to
);
return
body
;
}
}
}
}
//////////////////////////////////////////////////////////////////////////////
return
body
;
// Some auxiliary math functions
}
static
inline
float
normL2
(
const
cv
::
Point3f
&
a
)
//////////////////////////////////////////////////////////////////////////////
{
// Some auxiliary math functions
return
a
.
x
*
a
.
x
+
a
.
y
*
a
.
y
+
a
.
z
*
a
.
z
;
}
static
inline
float
normL2
(
const
Point3f
&
a
)
{
static
inline
return
a
.
x
*
a
.
x
+
a
.
y
*
a
.
y
+
a
.
z
*
a
.
z
;
float
normL2
(
const
cv
::
Point3f
&
a
,
const
cv
::
Point3f
&
b
)
}
{
return
normL2
(
a
-
b
);
}
static
inline
float
normL2
(
const
Point3f
&
a
,
const
Point3f
&
b
)
{
static
inline
return
normL2
(
a
-
b
);
double
normL2sq
(
const
cv
::
Mat
&
r
)
}
{
return
r
.
dot
(
r
);
}
static
inline
double
normL2sq
(
const
Mat
&
r
)
{
static
inline
int
sqr
(
int
x
)
{
return
x
*
x
;
}
return
r
.
dot
(
r
);
static
inline
float
sqr
(
float
x
)
{
return
x
*
x
;
}
}
static
inline
double
sqr
(
double
x
)
{
return
x
*
x
;
}
#endif // __OPENCV_STITCHING_UTIL_INL_HPP__
static
inline
int
sqr
(
int
x
)
{
return
x
*
x
;
}
static
inline
float
sqr
(
float
x
)
{
return
x
*
x
;
}
static
inline
double
sqr
(
double
x
)
{
return
x
*
x
;
}
}
// namespace cv
#endif // __OPENCV_STITCHING_UTIL_INL_HPP__
modules/stitching/warpers.hpp
→
modules/stitching/
include/opencv2/stitching/
warpers.hpp
View file @
9be4701f
...
@@ -39,29 +39,34 @@
...
@@ -39,29 +39,34 @@
// the use of this software, even if advised of the possibility of such damage.
// the use of this software, even if advised of the possibility of such damage.
//
//
//M*/
//M*/
#ifndef __OPENCV_WARPERS_HPP__
#ifndef __OPENCV_
STITCHING_
WARPERS_HPP__
#define __OPENCV_WARPERS_HPP__
#define __OPENCV_
STITCHING_
WARPERS_HPP__
#include "precomp.hpp"
#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/gpu/gpu.hpp"
namespace
cv
{
class
Warper
class
Warper
{
{
public
:
public
:
enum
{
PLANE
,
CYLINDRICAL
,
SPHERICAL
};
enum
{
PLANE
,
CYLINDRICAL
,
SPHERICAL
};
static
cv
::
Ptr
<
Warper
>
createByCameraFocal
(
float
focal
,
int
type
,
bool
try_gpu
=
false
);
static
Ptr
<
Warper
>
createByCameraFocal
(
float
focal
,
int
type
,
bool
try_gpu
=
false
);
virtual
~
Warper
()
{}
virtual
~
Warper
()
{}
virtual
cv
::
Point
warp
(
const
cv
::
Mat
&
src
,
float
focal
,
const
cv
::
Mat
&
R
,
cv
::
Mat
&
dst
,
virtual
Point
warp
(
const
Mat
&
src
,
float
focal
,
const
Mat
&
R
,
Mat
&
dst
,
int
interp_mode
=
cv
::
INTER_LINEAR
,
int
border_mode
=
cv
::
BORDER_REFLECT
)
=
0
;
int
interp_mode
=
INTER_LINEAR
,
int
border_mode
=
BORDER_REFLECT
)
=
0
;
virtual
cv
::
Rect
warpRoi
(
const
cv
::
Size
&
sz
,
float
focal
,
const
cv
::
Mat
&
R
)
=
0
;
virtual
Rect
warpRoi
(
const
Size
&
sz
,
float
focal
,
const
Mat
&
R
)
=
0
;
};
};
struct
ProjectorBase
struct
ProjectorBase
{
{
void
setTransformation
(
const
cv
::
Mat
&
R
);
void
setTransformation
(
const
Mat
&
R
);
cv
::
Size
size
;
Size
size
;
float
focal
;
float
focal
;
float
r
[
9
];
float
r
[
9
];
float
rinv
[
9
];
float
rinv
[
9
];
...
@@ -73,20 +78,20 @@ template <class P>
...
@@ -73,20 +78,20 @@ template <class P>
class
WarperBase
:
public
Warper
class
WarperBase
:
public
Warper
{
{
public
:
public
:
virtual
cv
::
Point
warp
(
const
cv
::
Mat
&
src
,
float
focal
,
const
cv
::
Mat
&
R
,
cv
::
Mat
&
dst
,
virtual
Point
warp
(
const
Mat
&
src
,
float
focal
,
const
Mat
&
R
,
Mat
&
dst
,
int
interp_mode
,
int
border_mode
);
int
interp_mode
,
int
border_mode
);
virtual
cv
::
Rect
warpRoi
(
const
cv
::
Size
&
sz
,
float
focal
,
const
cv
::
Mat
&
R
);
virtual
Rect
warpRoi
(
const
Size
&
sz
,
float
focal
,
const
Mat
&
R
);
protected
:
protected
:
// Detects ROI of the destination image. It's correct for any projection.
// Detects ROI of the destination image. It's correct for any projection.
virtual
void
detectResultRoi
(
cv
::
Point
&
dst_tl
,
cv
::
Point
&
dst_br
);
virtual
void
detectResultRoi
(
Point
&
dst_tl
,
Point
&
dst_br
);
// Detects ROI of the destination image by walking over image border.
// Detects ROI of the destination image by walking over image border.
// Correctness for any projection isn't guaranteed.
// Correctness for any projection isn't guaranteed.
void
detectResultRoiByBorder
(
cv
::
Point
&
dst_tl
,
cv
::
Point
&
dst_br
);
void
detectResultRoiByBorder
(
Point
&
dst_tl
,
Point
&
dst_br
);
cv
::
Size
src_size_
;
Size
src_size_
;
P
projector_
;
P
projector_
;
};
};
...
@@ -110,7 +115,7 @@ public:
...
@@ -110,7 +115,7 @@ public:
}
}
protected
:
protected
:
void
detectResultRoi
(
cv
::
Point
&
dst_tl
,
cv
::
Point
&
dst_br
);
void
detectResultRoi
(
Point
&
dst_tl
,
Point
&
dst_br
);
};
};
...
@@ -118,11 +123,11 @@ class PlaneWarperGpu : public PlaneWarper
...
@@ -118,11 +123,11 @@ class PlaneWarperGpu : public PlaneWarper
{
{
public
:
public
:
PlaneWarperGpu
(
float
plane_dist
=
1.
f
,
float
scale
=
1.
f
)
:
PlaneWarper
(
plane_dist
,
scale
)
{}
PlaneWarperGpu
(
float
plane_dist
=
1.
f
,
float
scale
=
1.
f
)
:
PlaneWarper
(
plane_dist
,
scale
)
{}
cv
::
Point
warp
(
const
cv
::
Mat
&
src
,
float
focal
,
const
cv
::
Mat
&
R
,
cv
::
Mat
&
dst
,
Point
warp
(
const
Mat
&
src
,
float
focal
,
const
Mat
&
R
,
Mat
&
dst
,
int
interp_mode
,
int
border_mode
);
int
interp_mode
,
int
border_mode
);
private
:
private
:
cv
::
gpu
::
GpuMat
d_xmap_
,
d_ymap_
,
d_dst_
,
d_src_
;
gpu
::
GpuMat
d_xmap_
,
d_ymap_
,
d_dst_
,
d_src_
;
};
};
...
@@ -141,7 +146,7 @@ public:
...
@@ -141,7 +146,7 @@ public:
SphericalWarper
(
float
scale
=
300.
f
)
{
projector_
.
scale
=
scale
;
}
SphericalWarper
(
float
scale
=
300.
f
)
{
projector_
.
scale
=
scale
;
}
protected
:
protected
:
void
detectResultRoi
(
cv
::
Point
&
dst_tl
,
cv
::
Point
&
dst_br
);
void
detectResultRoi
(
Point
&
dst_tl
,
Point
&
dst_br
);
};
};
...
@@ -149,11 +154,11 @@ class SphericalWarperGpu : public SphericalWarper
...
@@ -149,11 +154,11 @@ class SphericalWarperGpu : public SphericalWarper
{
{
public
:
public
:
SphericalWarperGpu
(
float
scale
=
300.
f
)
:
SphericalWarper
(
scale
)
{}
SphericalWarperGpu
(
float
scale
=
300.
f
)
:
SphericalWarper
(
scale
)
{}
cv
::
Point
warp
(
const
cv
::
Mat
&
src
,
float
focal
,
const
cv
::
Mat
&
R
,
cv
::
Mat
&
dst
,
Point
warp
(
const
Mat
&
src
,
float
focal
,
const
Mat
&
R
,
Mat
&
dst
,
int
interp_mode
,
int
border_mode
);
int
interp_mode
,
int
border_mode
);
private
:
private
:
cv
::
gpu
::
GpuMat
d_xmap_
,
d_ymap_
,
d_dst_
,
d_src_
;
gpu
::
GpuMat
d_xmap_
,
d_ymap_
,
d_dst_
,
d_src_
;
};
};
...
@@ -171,7 +176,7 @@ public:
...
@@ -171,7 +176,7 @@ public:
CylindricalWarper
(
float
scale
=
300.
f
)
{
projector_
.
scale
=
scale
;
}
CylindricalWarper
(
float
scale
=
300.
f
)
{
projector_
.
scale
=
scale
;
}
protected
:
protected
:
void
detectResultRoi
(
cv
::
Point
&
dst_tl
,
cv
::
Point
&
dst_br
)
void
detectResultRoi
(
Point
&
dst_tl
,
Point
&
dst_br
)
{
{
WarperBase
<
CylindricalProjector
>::
detectResultRoiByBorder
(
dst_tl
,
dst_br
);
WarperBase
<
CylindricalProjector
>::
detectResultRoiByBorder
(
dst_tl
,
dst_br
);
}
}
...
@@ -182,13 +187,15 @@ class CylindricalWarperGpu : public CylindricalWarper
...
@@ -182,13 +187,15 @@ class CylindricalWarperGpu : public CylindricalWarper
{
{
public
:
public
:
CylindricalWarperGpu
(
float
scale
=
300.
f
)
:
CylindricalWarper
(
scale
)
{}
CylindricalWarperGpu
(
float
scale
=
300.
f
)
:
CylindricalWarper
(
scale
)
{}
cv
::
Point
warp
(
const
cv
::
Mat
&
src
,
float
focal
,
const
cv
::
Mat
&
R
,
cv
::
Mat
&
dst
,
Point
warp
(
const
Mat
&
src
,
float
focal
,
const
Mat
&
R
,
Mat
&
dst
,
int
interp_mode
,
int
border_mode
);
int
interp_mode
,
int
border_mode
);
private
:
private
:
cv
::
gpu
::
GpuMat
d_xmap_
,
d_ymap_
,
d_dst_
,
d_src_
;
gpu
::
GpuMat
d_xmap_
,
d_ymap_
,
d_dst_
,
d_src_
;
};
};
}
// namespace cv
#include "warpers_inl.hpp"
#include "warpers_inl.hpp"
#endif // __OPENCV_WARPERS_HPP__
#endif // __OPENCV_
STITCHING_
WARPERS_HPP__
modules/stitching/warpers_inl.hpp
→
modules/stitching/
include/opencv2/stitching/
warpers_inl.hpp
View file @
9be4701f
...
@@ -39,13 +39,17 @@
...
@@ -39,13 +39,17 @@
// the use of this software, even if advised of the possibility of such damage.
// the use of this software, even if advised of the possibility of such damage.
//
//
//M*/
//M*/
#ifndef __OPENCV_WARPERS_INL_HPP__
#ifndef __OPENCV_
STITCHING_
WARPERS_INL_HPP__
#define __OPENCV_WARPERS_INL_HPP__
#define __OPENCV_
STITCHING_
WARPERS_INL_HPP__
#include "opencv2/core/core.hpp"
#include "warpers.hpp" // Make your IDE see declarations
#include "warpers.hpp" // Make your IDE see declarations
namespace
cv
{
template
<
class
P
>
template
<
class
P
>
cv
::
Point
WarperBase
<
P
>::
warp
(
const
cv
::
Mat
&
src
,
float
focal
,
const
cv
::
Mat
&
R
,
cv
::
Mat
&
dst
,
Point
WarperBase
<
P
>::
warp
(
const
Mat
&
src
,
float
focal
,
const
Mat
&
R
,
Mat
&
dst
,
int
interp_mode
,
int
border_mode
)
int
interp_mode
,
int
border_mode
)
{
{
src_size_
=
src
.
size
();
src_size_
=
src
.
size
();
...
@@ -54,11 +58,11 @@ cv::Point WarperBase<P>::warp(const cv::Mat &src, float focal, const cv::Mat &R,
...
@@ -54,11 +58,11 @@ cv::Point WarperBase<P>::warp(const cv::Mat &src, float focal, const cv::Mat &R,
projector_
.
focal
=
focal
;
projector_
.
focal
=
focal
;
projector_
.
setTransformation
(
R
);
projector_
.
setTransformation
(
R
);
cv
::
Point
dst_tl
,
dst_br
;
Point
dst_tl
,
dst_br
;
detectResultRoi
(
dst_tl
,
dst_br
);
detectResultRoi
(
dst_tl
,
dst_br
);
cv
::
Mat
xmap
(
dst_br
.
y
-
dst_tl
.
y
+
1
,
dst_br
.
x
-
dst_tl
.
x
+
1
,
CV_32F
);
Mat
xmap
(
dst_br
.
y
-
dst_tl
.
y
+
1
,
dst_br
.
x
-
dst_tl
.
x
+
1
,
CV_32F
);
cv
::
Mat
ymap
(
dst_br
.
y
-
dst_tl
.
y
+
1
,
dst_br
.
x
-
dst_tl
.
x
+
1
,
CV_32F
);
Mat
ymap
(
dst_br
.
y
-
dst_tl
.
y
+
1
,
dst_br
.
x
-
dst_tl
.
x
+
1
,
CV_32F
);
float
x
,
y
;
float
x
,
y
;
for
(
int
v
=
dst_tl
.
y
;
v
<=
dst_br
.
y
;
++
v
)
for
(
int
v
=
dst_tl
.
y
;
v
<=
dst_br
.
y
;
++
v
)
...
@@ -79,7 +83,7 @@ cv::Point WarperBase<P>::warp(const cv::Mat &src, float focal, const cv::Mat &R,
...
@@ -79,7 +83,7 @@ cv::Point WarperBase<P>::warp(const cv::Mat &src, float focal, const cv::Mat &R,
template
<
class
P
>
template
<
class
P
>
cv
::
Rect
WarperBase
<
P
>::
warpRoi
(
const
cv
::
Size
&
sz
,
float
focal
,
const
cv
::
Mat
&
R
)
Rect
WarperBase
<
P
>::
warpRoi
(
const
Size
&
sz
,
float
focal
,
const
Mat
&
R
)
{
{
src_size_
=
sz
;
src_size_
=
sz
;
...
@@ -87,15 +91,15 @@ cv::Rect WarperBase<P>::warpRoi(const cv::Size &sz, float focal, const cv::Mat &
...
@@ -87,15 +91,15 @@ cv::Rect WarperBase<P>::warpRoi(const cv::Size &sz, float focal, const cv::Mat &
projector_
.
focal
=
focal
;
projector_
.
focal
=
focal
;
projector_
.
setTransformation
(
R
);
projector_
.
setTransformation
(
R
);
cv
::
Point
dst_tl
,
dst_br
;
Point
dst_tl
,
dst_br
;
detectResultRoi
(
dst_tl
,
dst_br
);
detectResultRoi
(
dst_tl
,
dst_br
);
return
cv
::
Rect
(
dst_tl
,
cv
::
Point
(
dst_br
.
x
+
1
,
dst_br
.
y
+
1
));
return
Rect
(
dst_tl
,
Point
(
dst_br
.
x
+
1
,
dst_br
.
y
+
1
));
}
}
template
<
class
P
>
template
<
class
P
>
void
WarperBase
<
P
>::
detectResultRoi
(
cv
::
Point
&
dst_tl
,
cv
::
Point
&
dst_br
)
void
WarperBase
<
P
>::
detectResultRoi
(
Point
&
dst_tl
,
Point
&
dst_br
)
{
{
float
tl_uf
=
std
::
numeric_limits
<
float
>::
max
();
float
tl_uf
=
std
::
numeric_limits
<
float
>::
max
();
float
tl_vf
=
std
::
numeric_limits
<
float
>::
max
();
float
tl_vf
=
std
::
numeric_limits
<
float
>::
max
();
...
@@ -121,7 +125,7 @@ void WarperBase<P>::detectResultRoi(cv::Point &dst_tl, cv::Point &dst_br)
...
@@ -121,7 +125,7 @@ void WarperBase<P>::detectResultRoi(cv::Point &dst_tl, cv::Point &dst_br)
template
<
class
P
>
template
<
class
P
>
void
WarperBase
<
P
>::
detectResultRoiByBorder
(
cv
::
Point
&
dst_tl
,
cv
::
Point
&
dst_br
)
void
WarperBase
<
P
>::
detectResultRoiByBorder
(
Point
&
dst_tl
,
Point
&
dst_br
)
{
{
float
tl_uf
=
std
::
numeric_limits
<
float
>::
max
();
float
tl_uf
=
std
::
numeric_limits
<
float
>::
max
();
float
tl_vf
=
std
::
numeric_limits
<
float
>::
max
();
float
tl_vf
=
std
::
numeric_limits
<
float
>::
max
();
...
@@ -252,4 +256,6 @@ void CylindricalProjector::mapBackward(float u, float v, float &x, float &y)
...
@@ -252,4 +256,6 @@ void CylindricalProjector::mapBackward(float u, float v, float &x, float &y)
y
=
focal
*
y
/
z
+
size
.
height
*
0.5
f
;
y
=
focal
*
y
/
z
+
size
.
height
*
0.5
f
;
}
}
#endif // __OPENCV_WARPERS_INL_HPP__
}
// namespace cv
#endif // __OPENCV_STITCHING_WARPERS_INL_HPP__
modules/stitching/autocalib.cpp
→
modules/stitching/
src/
autocalib.cpp
View file @
9be4701f
...
@@ -39,11 +39,12 @@
...
@@ -39,11 +39,12 @@
// the use of this software, even if advised of the possibility of such damage.
// the use of this software, even if advised of the possibility of such damage.
//
//
//M*/
//M*/
#include "autocalib.hpp"
#include "precomp.hpp"
#include "util.hpp"
using
namespace
std
;
using
namespace
std
;
using
namespace
cv
;
namespace
cv
{
void
focalsFromHomography
(
const
Mat
&
H
,
double
&
f0
,
double
&
f1
,
bool
&
f0_ok
,
bool
&
f1_ok
)
void
focalsFromHomography
(
const
Mat
&
H
,
double
&
f0
,
double
&
f1
,
bool
&
f0_ok
,
bool
&
f1_ok
)
{
{
...
@@ -59,8 +60,8 @@ void focalsFromHomography(const Mat& H, double &f0, double &f1, bool &f0_ok, boo
...
@@ -59,8 +60,8 @@ void focalsFromHomography(const Mat& H, double &f0, double &f1, bool &f0_ok, boo
d2
=
(
h
[
7
]
-
h
[
6
])
*
(
h
[
7
]
+
h
[
6
]);
d2
=
(
h
[
7
]
-
h
[
6
])
*
(
h
[
7
]
+
h
[
6
]);
v1
=
-
(
h
[
0
]
*
h
[
1
]
+
h
[
3
]
*
h
[
4
])
/
d1
;
v1
=
-
(
h
[
0
]
*
h
[
1
]
+
h
[
3
]
*
h
[
4
])
/
d1
;
v2
=
(
h
[
0
]
*
h
[
0
]
+
h
[
3
]
*
h
[
3
]
-
h
[
1
]
*
h
[
1
]
-
h
[
4
]
*
h
[
4
])
/
d2
;
v2
=
(
h
[
0
]
*
h
[
0
]
+
h
[
3
]
*
h
[
3
]
-
h
[
1
]
*
h
[
1
]
-
h
[
4
]
*
h
[
4
])
/
d2
;
if
(
v1
<
v2
)
swap
(
v1
,
v2
);
if
(
v1
<
v2
)
s
td
::
s
wap
(
v1
,
v2
);
if
(
v1
>
0
&&
v2
>
0
)
f1
=
sqrt
(
abs
(
d1
)
>
abs
(
d2
)
?
v1
:
v2
);
if
(
v1
>
0
&&
v2
>
0
)
f1
=
sqrt
(
std
::
abs
(
d1
)
>
std
::
abs
(
d2
)
?
v1
:
v2
);
else
if
(
v1
>
0
)
f1
=
sqrt
(
v1
);
else
if
(
v1
>
0
)
f1
=
sqrt
(
v1
);
else
f1_ok
=
false
;
else
f1_ok
=
false
;
...
@@ -69,8 +70,8 @@ void focalsFromHomography(const Mat& H, double &f0, double &f1, bool &f0_ok, boo
...
@@ -69,8 +70,8 @@ void focalsFromHomography(const Mat& H, double &f0, double &f1, bool &f0_ok, boo
d2
=
h
[
0
]
*
h
[
0
]
+
h
[
1
]
*
h
[
1
]
-
h
[
3
]
*
h
[
3
]
-
h
[
4
]
*
h
[
4
];
d2
=
h
[
0
]
*
h
[
0
]
+
h
[
1
]
*
h
[
1
]
-
h
[
3
]
*
h
[
3
]
-
h
[
4
]
*
h
[
4
];
v1
=
-
h
[
2
]
*
h
[
5
]
/
d1
;
v1
=
-
h
[
2
]
*
h
[
5
]
/
d1
;
v2
=
(
h
[
5
]
*
h
[
5
]
-
h
[
2
]
*
h
[
2
])
/
d2
;
v2
=
(
h
[
5
]
*
h
[
5
]
-
h
[
2
]
*
h
[
2
])
/
d2
;
if
(
v1
<
v2
)
swap
(
v1
,
v2
);
if
(
v1
<
v2
)
s
td
::
s
wap
(
v1
,
v2
);
if
(
v1
>
0
&&
v2
>
0
)
f0
=
sqrt
(
abs
(
d1
)
>
abs
(
d2
)
?
v1
:
v2
);
if
(
v1
>
0
&&
v2
>
0
)
f0
=
sqrt
(
std
::
abs
(
d1
)
>
std
::
abs
(
d2
)
?
v1
:
v2
);
else
if
(
v1
>
0
)
f0
=
sqrt
(
v1
);
else
if
(
v1
>
0
)
f0
=
sqrt
(
v1
);
else
f0_ok
=
false
;
else
f0_ok
=
false
;
}
}
...
@@ -182,3 +183,5 @@ bool calibrateRotatingCamera(const vector<Mat> &Hs, Mat &K)
...
@@ -182,3 +183,5 @@ bool calibrateRotatingCamera(const vector<Mat> &Hs, Mat &K)
K
=
W
.
t
();
K
=
W
.
t
();
return
true
;
return
true
;
}
}
}
// namespace cv
modules/stitching/blenders.cpp
→
modules/stitching/
src/
blenders.cpp
View file @
9be4701f
...
@@ -39,11 +39,12 @@
...
@@ -39,11 +39,12 @@
// the use of this software, even if advised of the possibility of such damage.
// the use of this software, even if advised of the possibility of such damage.
//
//
//M*/
//M*/
#include "blenders.hpp"
#include "precomp.hpp"
#include "util.hpp"
using
namespace
std
;
using
namespace
std
;
using
namespace
cv
;
namespace
cv
{
static
const
float
WEIGHT_EPS
=
1e-5
f
;
static
const
float
WEIGHT_EPS
=
1e-5
f
;
...
@@ -147,7 +148,7 @@ void FeatherBlender::feed(const Mat &img, const Mat &mask, Point tl)
...
@@ -147,7 +148,7 @@ void FeatherBlender::feed(const Mat &img, const Mat &mask, Point tl)
void
FeatherBlender
::
blend
(
Mat
&
dst
,
Mat
&
dst_mask
)
void
FeatherBlender
::
blend
(
Mat
&
dst
,
Mat
&
dst_mask
)
{
{
normalize
(
dst_weight_map_
,
dst_
);
normalize
UsingWeightMap
(
dst_weight_map_
,
dst_
);
dst_mask_
=
dst_weight_map_
>
WEIGHT_EPS
;
dst_mask_
=
dst_weight_map_
>
WEIGHT_EPS
;
Blender
::
blend
(
dst
,
dst_mask
);
Blender
::
blend
(
dst
,
dst_mask
);
}
}
...
@@ -281,7 +282,7 @@ void MultiBandBlender::feed(const Mat &img, const Mat &mask, Point tl)
...
@@ -281,7 +282,7 @@ void MultiBandBlender::feed(const Mat &img, const Mat &mask, Point tl)
void
MultiBandBlender
::
blend
(
Mat
&
dst
,
Mat
&
dst_mask
)
void
MultiBandBlender
::
blend
(
Mat
&
dst
,
Mat
&
dst_mask
)
{
{
for
(
int
i
=
0
;
i
<=
num_bands_
;
++
i
)
for
(
int
i
=
0
;
i
<=
num_bands_
;
++
i
)
normalize
(
dst_band_weights_
[
i
],
dst_pyr_laplace_
[
i
]);
normalize
UsingWeightMap
(
dst_band_weights_
[
i
],
dst_pyr_laplace_
[
i
]);
restoreImageFromLaplacePyr
(
dst_pyr_laplace_
);
restoreImageFromLaplacePyr
(
dst_pyr_laplace_
);
...
@@ -299,7 +300,7 @@ void MultiBandBlender::blend(Mat &dst, Mat &dst_mask)
...
@@ -299,7 +300,7 @@ void MultiBandBlender::blend(Mat &dst, Mat &dst_mask)
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
// Auxiliary functions
// Auxiliary functions
void
normalize
(
const
Mat
&
weight
,
Mat
&
src
)
void
normalize
UsingWeightMap
(
const
Mat
&
weight
,
Mat
&
src
)
{
{
CV_Assert
(
weight
.
type
()
==
CV_32F
);
CV_Assert
(
weight
.
type
()
==
CV_32F
);
CV_Assert
(
src
.
type
()
==
CV_16SC3
);
CV_Assert
(
src
.
type
()
==
CV_16SC3
);
...
@@ -374,4 +375,4 @@ void restoreImageFromLaplacePyr(vector<Mat> &pyr)
...
@@ -374,4 +375,4 @@ void restoreImageFromLaplacePyr(vector<Mat> &pyr)
}
}
}
}
}
// namespace cv
modules/stitching/camera.cpp
→
modules/stitching/
src/
camera.cpp
View file @
9be4701f
#include <fstream>
#include "precomp.hpp"
#include "camera.hpp"
using
namespace
std
;
using
namespace
std
;
using
namespace
cv
;
namespace
cv
{
CameraParams
::
CameraParams
()
:
focal
(
1
),
R
(
Mat
::
eye
(
3
,
3
,
CV_64F
)),
t
(
Mat
::
zeros
(
3
,
1
,
CV_64F
))
{}
CameraParams
::
CameraParams
()
:
focal
(
1
),
R
(
Mat
::
eye
(
3
,
3
,
CV_64F
)),
t
(
Mat
::
zeros
(
3
,
1
,
CV_64F
))
{}
...
@@ -16,3 +16,5 @@ const CameraParams& CameraParams::operator =(const CameraParams &other)
...
@@ -16,3 +16,5 @@ const CameraParams& CameraParams::operator =(const CameraParams &other)
t
=
other
.
t
.
clone
();
t
=
other
.
t
.
clone
();
return
*
this
;
return
*
this
;
}
}
}
// namespace cv
modules/stitching/exposure_compensate.cpp
→
modules/stitching/
src/
exposure_compensate.cpp
View file @
9be4701f
...
@@ -39,14 +39,13 @@
...
@@ -39,14 +39,13 @@
// the use of this software, even if advised of the possibility of such damage.
// the use of this software, even if advised of the possibility of such damage.
//
//
//M*/
//M*/
#include "precomp.hpp"
#include "exposure_compensate.hpp"
#include "util.hpp"
using
namespace
std
;
using
namespace
std
;
using
namespace
cv
;
using
namespace
cv
::
gpu
;
using
namespace
cv
::
gpu
;
namespace
cv
{
Ptr
<
ExposureCompensator
>
ExposureCompensator
::
createDefault
(
int
type
)
Ptr
<
ExposureCompensator
>
ExposureCompensator
::
createDefault
(
int
type
)
{
{
...
@@ -243,3 +242,5 @@ void BlocksGainCompensator::apply(int index, Point /*corner*/, Mat &image, const
...
@@ -243,3 +242,5 @@ void BlocksGainCompensator::apply(int index, Point /*corner*/, Mat &image, const
}
}
}
}
}
}
}
// namespace cv
modules/stitching/matchers.cpp
→
modules/stitching/
src/
matchers.cpp
View file @
9be4701f
...
@@ -39,17 +39,13 @@
...
@@ -39,17 +39,13 @@
// the use of this software, even if advised of the possibility of such damage.
// the use of this software, even if advised of the possibility of such damage.
//
//
//M*/
//M*/
#include <algorithm>
#include "precomp.hpp"
#include <functional>
#include "matchers.hpp"
#include "util.hpp"
using
namespace
std
;
using
namespace
std
;
using
namespace
cv
;
using
namespace
cv
::
gpu
;
using
namespace
cv
::
gpu
;
namespace
cv
//////////////////////////////////////////////////////////////////////////////
{
void
FeaturesFinder
::
operator
()(
const
Mat
&
image
,
ImageFeatures
&
features
)
void
FeaturesFinder
::
operator
()(
const
Mat
&
image
,
ImageFeatures
&
features
)
{
{
...
@@ -58,10 +54,13 @@ void FeaturesFinder::operator ()(const Mat &image, ImageFeatures &features)
...
@@ -58,10 +54,13 @@ void FeaturesFinder::operator ()(const Mat &image, ImageFeatures &features)
//features.img = image.clone();
//features.img = image.clone();
}
}
//////////////////////////////////////////////////////////////////////////////
}
// namespace cv
namespace
namespace
{
{
using
namespace
cv
;
class
CpuSurfFeaturesFinder
:
public
FeaturesFinder
class
CpuSurfFeaturesFinder
:
public
FeaturesFinder
{
{
public
:
public
:
...
@@ -153,9 +152,12 @@ namespace
...
@@ -153,9 +152,12 @@ namespace
keypoints_
.
release
();
keypoints_
.
release
();
descriptors_
.
release
();
descriptors_
.
release
();
}
}
}
//
anonymous
namespace
}
// namespace
namespace
cv
{
SurfFeaturesFinder
::
SurfFeaturesFinder
(
bool
try_use_gpu
,
double
hess_thresh
,
int
num_octaves
,
int
num_layers
,
SurfFeaturesFinder
::
SurfFeaturesFinder
(
bool
try_use_gpu
,
double
hess_thresh
,
int
num_octaves
,
int
num_layers
,
int
num_octaves_descr
,
int
num_layers_descr
)
int
num_octaves_descr
,
int
num_layers_descr
)
{
{
...
@@ -240,8 +242,8 @@ struct MatchPairsBody
...
@@ -240,8 +242,8 @@ struct MatchPairsBody
pairwise_matches
[
dual_pair_idx
].
H
=
pairwise_matches
[
pair_idx
].
H
.
inv
();
pairwise_matches
[
dual_pair_idx
].
H
=
pairwise_matches
[
pair_idx
].
H
.
inv
();
for
(
size_t
j
=
0
;
j
<
pairwise_matches
[
dual_pair_idx
].
matches
.
size
();
++
j
)
for
(
size_t
j
=
0
;
j
<
pairwise_matches
[
dual_pair_idx
].
matches
.
size
();
++
j
)
swap
(
pairwise_matches
[
dual_pair_idx
].
matches
[
j
].
queryIdx
,
s
td
::
s
wap
(
pairwise_matches
[
dual_pair_idx
].
matches
[
j
].
queryIdx
,
pairwise_matches
[
dual_pair_idx
].
matches
[
j
].
trainIdx
);
pairwise_matches
[
dual_pair_idx
].
matches
[
j
].
trainIdx
);
LOG
(
"."
);
LOG
(
"."
);
}
}
}
}
...
@@ -457,7 +459,7 @@ void BestOf2NearestMatcher::match(const ImageFeatures &features1, const ImageFea
...
@@ -457,7 +459,7 @@ void BestOf2NearestMatcher::match(const ImageFeatures &features1, const ImageFea
// Find pair-wise motion
// Find pair-wise motion
matches_info
.
H
=
findHomography
(
src_points
,
dst_points
,
matches_info
.
inliers_mask
,
CV_RANSAC
);
matches_info
.
H
=
findHomography
(
src_points
,
dst_points
,
matches_info
.
inliers_mask
,
CV_RANSAC
);
if
(
abs
(
determinant
(
matches_info
.
H
))
<
numeric_limits
<
double
>::
epsilon
())
if
(
std
::
abs
(
determinant
(
matches_info
.
H
))
<
numeric_limits
<
double
>::
epsilon
())
return
;
return
;
// Find number of inliers
// Find number of inliers
...
@@ -504,3 +506,5 @@ void BestOf2NearestMatcher::releaseMemory()
...
@@ -504,3 +506,5 @@ void BestOf2NearestMatcher::releaseMemory()
{
{
impl_
->
releaseMemory
();
impl_
->
releaseMemory
();
}
}
}
// namespace cv
modules/stitching/motion_estimators.cpp
→
modules/stitching/
src/
motion_estimators.cpp
View file @
9be4701f
...
@@ -39,17 +39,12 @@
...
@@ -39,17 +39,12 @@
// the use of this software, even if advised of the possibility of such damage.
// the use of this software, even if advised of the possibility of such damage.
//
//
//M*/
//M*/
#include <algorithm>
#include "precomp.hpp"
#include <sstream>
#include "autocalib.hpp"
#include "motion_estimators.hpp"
#include "util.hpp"
using
namespace
std
;
using
namespace
std
;
using
namespace
cv
;
namespace
cv
//////////////////////////////////////////////////////////////////////////////
{
struct
IncDistance
struct
IncDistance
{
{
...
@@ -605,3 +600,5 @@ void findMaxSpanningTree(int num_images, const vector<MatchesInfo> &pairwise_mat
...
@@ -605,3 +600,5 @@ void findMaxSpanningTree(int num_images, const vector<MatchesInfo> &pairwise_mat
centers
.
push_back
(
i
);
centers
.
push_back
(
i
);
CV_Assert
(
centers
.
size
()
>
0
&&
centers
.
size
()
<=
2
);
CV_Assert
(
centers
.
size
()
>
0
&&
centers
.
size
()
<=
2
);
}
}
}
// namespace cv
modules/stitching/precomp.cpp
→
modules/stitching/
src/
precomp.cpp
View file @
9be4701f
File moved
modules/stitching/precomp.hpp
→
modules/stitching/
src/
precomp.hpp
View file @
9be4701f
...
@@ -51,10 +51,19 @@
...
@@ -51,10 +51,19 @@
#include <utility>
#include <utility>
#include <set>
#include <set>
#include <functional>
#include <functional>
#include <sstream>
#include "opencv2/stitching/autocalib.hpp"
#include "opencv2/stitching/blenders.hpp"
#include "opencv2/stitching/camera.hpp"
#include "opencv2/stitching/exposure_compensate.hpp"
#include "opencv2/stitching/matchers.hpp"
#include "opencv2/stitching/motion_estimators.hpp"
#include "opencv2/stitching/seam_finders.hpp"
#include "opencv2/stitching/util.hpp"
#include "opencv2/stitching/warpers.hpp"
#include "opencv2/core/core.hpp"
#include "opencv2/core/core.hpp"
#include "opencv2/core/internal.hpp"
#include "opencv2/core/internal.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/gpu/gpu.hpp"
#include "opencv2/gpu/gpu.hpp"
...
...
modules/stitching/seam_finders.cpp
→
modules/stitching/s
rc/s
eam_finders.cpp
View file @
9be4701f
...
@@ -39,12 +39,12 @@
...
@@ -39,12 +39,12 @@
// the use of this software, even if advised of the possibility of such damage.
// the use of this software, even if advised of the possibility of such damage.
//
//
//M*/
//M*/
#include "seam_finders.hpp"
#include "precomp.hpp"
#include "util.hpp"
using
namespace
std
;
using
namespace
std
;
using
namespace
cv
;
namespace
cv
{
Ptr
<
SeamFinder
>
SeamFinder
::
createDefault
(
int
type
)
Ptr
<
SeamFinder
>
SeamFinder
::
createDefault
(
int
type
)
{
{
...
@@ -405,3 +405,5 @@ void GraphCutSeamFinder::find(const vector<Mat> &src, const vector<Point> &corne
...
@@ -405,3 +405,5 @@ void GraphCutSeamFinder::find(const vector<Mat> &src, const vector<Point> &corne
{
{
impl_
->
find
(
src
,
corners
,
masks
);
impl_
->
find
(
src
,
corners
,
masks
);
}
}
}
// namespace cv
modules/stitching/util.cpp
→
modules/stitching/
src/
util.cpp
View file @
9be4701f
...
@@ -39,10 +39,12 @@
...
@@ -39,10 +39,12 @@
// the use of this software, even if advised of the possibility of such damage.
// the use of this software, even if advised of the possibility of such damage.
//
//
//M*/
//M*/
#include "
util
.hpp"
#include "
precomp
.hpp"
using
namespace
std
;
using
namespace
std
;
using
namespace
cv
;
namespace
cv
{
void
DisjointSets
::
createOneElemSets
(
int
n
)
void
DisjointSets
::
createOneElemSets
(
int
n
)
{
{
...
@@ -161,3 +163,5 @@ void selectRandomSubset(int count, int size, vector<int> &subset)
...
@@ -161,3 +163,5 @@ void selectRandomSubset(int count, int size, vector<int> &subset)
}
}
}
}
}
}
}
// namespace cv
modules/stitching/warpers.cpp
→
modules/stitching/
src/
warpers.cpp
View file @
9be4701f
...
@@ -39,10 +39,12 @@
...
@@ -39,10 +39,12 @@
// the use of this software, even if advised of the possibility of such damage.
// the use of this software, even if advised of the possibility of such damage.
//
//
//M*/
//M*/
#include "
warpers
.hpp"
#include "
precomp
.hpp"
using
namespace
std
;
using
namespace
std
;
using
namespace
cv
;
namespace
cv
{
Ptr
<
Warper
>
Warper
::
createByCameraFocal
(
float
focal
,
int
type
,
bool
try_gpu
)
Ptr
<
Warper
>
Warper
::
createByCameraFocal
(
float
focal
,
int
type
,
bool
try_gpu
)
{
{
...
@@ -227,3 +229,5 @@ Point CylindricalWarperGpu::warp(const Mat &src, float focal, const Mat &R, Mat
...
@@ -227,3 +229,5 @@ Point CylindricalWarperGpu::warp(const Mat &src, float focal, const Mat &R, Mat
return
dst_tl
;
return
dst_tl
;
}
}
}
// namespace cv
samples/cpp/CMakeLists.txt
View file @
9be4701f
...
@@ -18,6 +18,8 @@ if (BUILD_EXAMPLES)
...
@@ -18,6 +18,8 @@ if (BUILD_EXAMPLES)
"
${
CMAKE_SOURCE_DIR
}
/modules/objdetect/include"
"
${
CMAKE_SOURCE_DIR
}
/modules/objdetect/include"
"
${
CMAKE_SOURCE_DIR
}
/modules/legacy/include"
"
${
CMAKE_SOURCE_DIR
}
/modules/legacy/include"
"
${
CMAKE_SOURCE_DIR
}
/modules/contrib/include"
"
${
CMAKE_SOURCE_DIR
}
/modules/contrib/include"
"
${
CMAKE_SOURCE_DIR
}
/modules/stitching/include"
"
${
CMAKE_SOURCE_DIR
}
/modules/gpu/include"
)
)
if
(
CMAKE_COMPILER_IS_GNUCXX
)
if
(
CMAKE_COMPILER_IS_GNUCXX
)
...
@@ -35,10 +37,10 @@ if (BUILD_EXAMPLES)
...
@@ -35,10 +37,10 @@ if (BUILD_EXAMPLES)
PROJECT_LABEL
"(EXAMPLE)
${
name
}
"
)
PROJECT_LABEL
"(EXAMPLE)
${
name
}
"
)
add_dependencies
(
${
the_target
}
opencv_core opencv_flann opencv_imgproc opencv_highgui
add_dependencies
(
${
the_target
}
opencv_core opencv_flann opencv_imgproc opencv_highgui
opencv_ml opencv_video opencv_objdetect opencv_features2d
opencv_ml opencv_video opencv_objdetect opencv_features2d
opencv_calib3d opencv_legacy opencv_contrib
)
opencv_calib3d opencv_legacy opencv_contrib
opencv_stitching opencv_gpu
)
target_link_libraries
(
${
the_target
}
${
OPENCV_LINKER_LIBS
}
opencv_core
target_link_libraries
(
${
the_target
}
${
OPENCV_LINKER_LIBS
}
opencv_core
opencv_flann opencv_imgproc opencv_highgui opencv_ml opencv_video opencv_objdetect
opencv_flann opencv_imgproc opencv_highgui opencv_ml opencv_video opencv_objdetect
opencv_features2d opencv_calib3d opencv_legacy opencv_contrib
)
opencv_features2d opencv_calib3d opencv_legacy opencv_contrib
opencv_stitching opencv_gpu
)
if
(
ENABLE_SOLUTION_FOLDERS
)
if
(
ENABLE_SOLUTION_FOLDERS
)
set_target_properties
(
${
the_target
}
PROPERTIES FOLDER
"samples//cpp"
)
set_target_properties
(
${
the_target
}
PROPERTIES FOLDER
"samples//cpp"
)
...
...
modules/stitching/main
.cpp
→
samples/cpp/stitching
.cpp
View file @
9be4701f
/*M///////////////////////////////////////////////////////////////////////////////////////
/*M///////////////////////////////////////////////////////////////////////////////////////
//
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
//
// By downloading, copying, installing or using the software you agree to this license.
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// If you do not agree to this license, do not download, install,
// copy or use the software.
// copy or use the software.
//
//
//
//
// License Agreement
// License Agreement
// For Open Source Computer Vision Library
// For Open Source Computer Vision Library
//
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
// Third party copyrights are property of their respective owners.
//
//
// Redistribution and use in source and binary forms, with or without modification,
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// are permitted provided that the following conditions are met:
//
//
// * Redistribution's of source code must retain the above copyright notice,
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// this list of conditions and the following disclaimer.
//
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// and/or other materials provided with the distribution.
//
//
// * The name of the copyright holders may not be used to endorse or promote products
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
// derived from this software without specific prior written permission.
//
//
// This software is provided by the copyright holders and contributors "as is" and
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
// the use of this software, even if advised of the possibility of such damage.
//
//
//M*/
//M*/
// We follow to these papers:
// We follow to these papers:
// 1) Construction of panoramic mosaics with global and local alignment.
// 1) Construction of panoramic mosaics with global and local alignment.
// Heung-Yeung Shum and Richard Szeliski. 2000.
// Heung-Yeung Shum and Richard Szeliski. 2000.
// 2) Eliminating Ghosting and Exposure Artifacts in Image Mosaics.
// 2) Eliminating Ghosting and Exposure Artifacts in Image Mosaics.
// Matthew Uyttendaele, Ashley Eden and Richard Szeliski. 2001.
// Matthew Uyttendaele, Ashley Eden and Richard Szeliski. 2001.
// 3) Automatic Panoramic Image Stitching using Invariant Features.
// 3) Automatic Panoramic Image Stitching using Invariant Features.
// Matthew Brown and David G. Lowe. 2007.
// Matthew Brown and David G. Lowe. 2007.
#include <fstream>
#include <fstream>
#include "precomp.hpp"
#include "opencv2/stitching/stitching.hpp"
#include "util.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "warpers.hpp"
#include "blenders.hpp"
using
namespace
std
;
#include "seam_finders.hpp"
using
namespace
cv
;
#include "motion_estimators.hpp"
#include "exposure_compensate.hpp"
void
printUsage
()
#include "camera.hpp"
{
cout
<<
using
namespace
std
;
"Rotation model images stitcher.
\n\n
"
using
namespace
cv
;
"stitching img1 img2 [...imgN] [flags]
\n\n
"
"Flags:
\n
"
void
printUsage
()
" --preview
\n
"
{
" Run stitching in the preview mode. Works faster than usual mode,
\n
"
cout
<<
" but output image will have lower resolution.
\n
"
"Rotation model images stitcher.
\n\n
"
" --try_gpu (yes|no)
\n
"
"opencv_stitching img1 img2 [...imgN] [flags]
\n\n
"
" Try to use GPU. The default value is 'no'. All default values
\n
"
"Flags:
\n
"
" are for CPU mode.
\n
"
" --preview
\n
"
"
\n
Motion Estimation Flags:
\n
"
" Run stitching in the preview mode. Works faster than usual mode,
\n
"
" --work_megapix <float>
\n
"
" but output image will have lower resolution.
\n
"
" Resolution for image registration step. The default is 0.6 Mpx.
\n
"
" --try_gpu (yes|no)
\n
"
" --match_conf <float>
\n
"
" Try to use GPU. The default value is 'no'. All default values
\n
"
" Confidence for feature matching step. The default is 0.65.
\n
"
" are for CPU mode.
\n
"
" --conf_thresh <float>
\n
"
"
\n
Motion Estimation Flags:
\n
"
" Threshold for two images are from the same panorama confidence.
\n
"
" --work_megapix <float>
\n
"
" The default is 1.0.
\n
"
" Resolution for image registration step. The default is 0.6 Mpx.
\n
"
" --ba (no|ray|focal_ray)
\n
"
" --match_conf <float>
\n
"
" Bundle adjustment cost function. The default is 'focal_ray'.
\n
"
" Confidence for feature matching step. The default is 0.65.
\n
"
" --wave_correct (no|yes)
\n
"
" --conf_thresh <float>
\n
"
" Perform wave effect correction. The default is 'yes'.
\n
"
" Threshold for two images are from the same panorama confidence.
\n
"
" --save_graph <file_name>
\n
"
" The default is 1.0.
\n
"
" Save matches graph represented in DOT language to <file_name> file.
\n
"
" --ba (no|ray|focal_ray)
\n
"
" Labels description: Nm is number of matches, Ni is number of inliers,
\n
"
" Bundle adjustment cost function. The default is 'focal_ray'.
\n
"
" C is confidence.
\n
"
" --wave_correct (no|yes)
\n
"
"
\n
Compositing Flags:
\n
"
" Perform wave effect correction. The default is 'yes'.
\n
"
" --warp (plane|cylindrical|spherical)
\n
"
" --save_graph <file_name>
\n
"
" Warp surface type. The default is 'spherical'.
\n
"
" Save matches graph represented in DOT language to <file_name> file.
\n
"
" --seam_megapix <float>
\n
"
" Labels description: Nm is number of matches, Ni is number of inliers,
\n
"
" Resolution for seam estimation step. The default is 0.1 Mpx.
\n
"
" C is confidence.
\n
"
" --seam (no|voronoi|gc_color|gc_colorgrad)
\n
"
"
\n
Compositing Flags:
\n
"
" Seam estimation method. The default is 'gc_color'.
\n
"
" --warp (plane|cylindrical|spherical)
\n
"
" --compose_megapix <float>
\n
"
" Warp surface type. The default is 'spherical'.
\n
"
" Resolution for compositing step. Use -1 for original resolution.
\n
"
" --seam_megapix <float>
\n
"
" The default is -1.
\n
"
" Resolution for seam estimation step. The default is 0.1 Mpx.
\n
"
" --expos_comp (no|gain|gain_blocks)
\n
"
" --seam (no|voronoi|gc_color|gc_colorgrad)
\n
"
" Exposure compensation method. The default is 'gain_blocks'.
\n
"
" Seam estimation method. The default is 'gc_color'.
\n
"
" --blend (no|feather|multiband)
\n
"
" --compose_megapix <float>
\n
"
" Blending method. The default is 'multiband'.
\n
"
" Resolution for compositing step. Use -1 for original resolution.
\n
"
" --blend_strength <float>
\n
"
" The default is -1.
\n
"
" Blending strength from [0,100] range. The default is 5.
\n
"
" --expos_comp (no|gain|gain_blocks)
\n
"
" --output <result_img>
\n
"
" Exposure compensation method. The default is 'gain_blocks'.
\n
"
" The default is 'result.jpg'.
\n
"
;
" --blend (no|feather|multiband)
\n
"
}
" Blending method. The default is 'multiband'.
\n
"
" --blend_strength <float>
\n
"
" Blending strength from [0,100] range. The default is 5.
\n
"
// Default command line args
" --output <result_img>
\n
"
vector
<
string
>
img_names
;
" The default is 'result.jpg'.
\n
"
;
bool
preview
=
false
;
}
bool
try_gpu
=
false
;
double
work_megapix
=
0.6
;
double
seam_megapix
=
0.1
;
// Default command line args
double
compose_megapix
=
-
1
;
vector
<
string
>
img_names
;
int
ba_space
=
BundleAdjuster
::
FOCAL_RAY_SPACE
;
bool
preview
=
false
;
float
conf_thresh
=
1.
f
;
bool
try_gpu
=
false
;
bool
wave_correct
=
true
;
double
work_megapix
=
0.6
;
bool
save_graph
=
false
;
double
seam_megapix
=
0.1
;
std
::
string
save_graph_to
;
double
compose_megapix
=
-
1
;
int
warp_type
=
Warper
::
SPHERICAL
;
int
ba_space
=
BundleAdjuster
::
FOCAL_RAY_SPACE
;
int
expos_comp_type
=
ExposureCompensator
::
GAIN_BLOCKS
;
float
conf_thresh
=
1.
f
;
float
match_conf
=
0.65
f
;
bool
wave_correct
=
true
;
int
seam_find_type
=
SeamFinder
::
GC_COLOR
;
bool
save_graph
=
false
;
int
blend_type
=
Blender
::
MULTI_BAND
;
std
::
string
save_graph_to
;
float
blend_strength
=
5
;
int
warp_type
=
Warper
::
SPHERICAL
;
string
result_name
=
"result.jpg"
;
int
expos_comp_type
=
ExposureCompensator
::
GAIN_BLOCKS
;
float
match_conf
=
0.65
f
;
int
parseCmdArgs
(
int
argc
,
char
**
argv
)
int
seam_find_type
=
SeamFinder
::
GC_COLOR
;
{
int
blend_type
=
Blender
::
MULTI_BAND
;
if
(
argc
==
1
)
float
blend_strength
=
5
;
{
string
result_name
=
"result.jpg"
;
printUsage
();
return
-
1
;
int
parseCmdArgs
(
int
argc
,
char
**
argv
)
}
{
for
(
int
i
=
1
;
i
<
argc
;
++
i
)
if
(
argc
==
1
)
{
{
if
(
string
(
argv
[
i
])
==
"--help"
||
string
(
argv
[
i
])
==
"/?"
)
printUsage
();
{
return
-
1
;
printUsage
();
}
return
-
1
;
for
(
int
i
=
1
;
i
<
argc
;
++
i
)
}
{
else
if
(
string
(
argv
[
i
])
==
"--preview"
)
if
(
string
(
argv
[
i
])
==
"--help"
||
string
(
argv
[
i
])
==
"/?"
)
{
{
preview
=
true
;
printUsage
();
}
return
-
1
;
else
if
(
string
(
argv
[
i
])
==
"--try_gpu"
)
}
{
else
if
(
string
(
argv
[
i
])
==
"--preview"
)
if
(
string
(
argv
[
i
+
1
])
==
"no"
)
{
try_gpu
=
false
;
preview
=
true
;
else
if
(
string
(
argv
[
i
+
1
])
==
"yes"
)
}
try_gpu
=
true
;
else
if
(
string
(
argv
[
i
])
==
"--try_gpu"
)
else
{
{
if
(
string
(
argv
[
i
+
1
])
==
"no"
)
cout
<<
"Bad --try_gpu flag value
\n
"
;
try_gpu
=
false
;
return
-
1
;
else
if
(
string
(
argv
[
i
+
1
])
==
"yes"
)
}
try_gpu
=
true
;
i
++
;
else
}
{
else
if
(
string
(
argv
[
i
])
==
"--work_megapix"
)
cout
<<
"Bad --try_gpu flag value
\n
"
;
{
return
-
1
;
work_megapix
=
atof
(
argv
[
i
+
1
]);
}
i
++
;
i
++
;
}
}
else
if
(
string
(
argv
[
i
])
==
"--seam_megapix"
)
else
if
(
string
(
argv
[
i
])
==
"--work_megapix"
)
{
{
seam_megapix
=
atof
(
argv
[
i
+
1
]);
work_megapix
=
atof
(
argv
[
i
+
1
]);
i
++
;
i
++
;
}
}
else
if
(
string
(
argv
[
i
])
==
"--compose_megapix"
)
else
if
(
string
(
argv
[
i
])
==
"--seam_megapix"
)
{
{
compose_megapix
=
atof
(
argv
[
i
+
1
]);
seam_megapix
=
atof
(
argv
[
i
+
1
]);
i
++
;
i
++
;
}
}
else
if
(
string
(
argv
[
i
])
==
"--result"
)
else
if
(
string
(
argv
[
i
])
==
"--compose_megapix"
)
{
{
result_name
=
argv
[
i
+
1
];
compose_megapix
=
atof
(
argv
[
i
+
1
]);
i
++
;
i
++
;
}
}
else
if
(
string
(
argv
[
i
])
==
"--match_conf"
)
else
if
(
string
(
argv
[
i
])
==
"--result"
)
{
{
match_conf
=
static_cast
<
float
>
(
atof
(
argv
[
i
+
1
]));
result_name
=
argv
[
i
+
1
];
i
++
;
i
++
;
}
}
else
if
(
string
(
argv
[
i
])
==
"--ba"
)
else
if
(
string
(
argv
[
i
])
==
"--match_conf"
)
{
{
if
(
string
(
argv
[
i
+
1
])
==
"no"
)
match_conf
=
static_cast
<
float
>
(
atof
(
argv
[
i
+
1
]));
ba_space
=
BundleAdjuster
::
NO
;
i
++
;
else
if
(
string
(
argv
[
i
+
1
])
==
"ray"
)
}
ba_space
=
BundleAdjuster
::
RAY_SPACE
;
else
if
(
string
(
argv
[
i
])
==
"--ba"
)
else
if
(
string
(
argv
[
i
+
1
])
==
"focal_ray"
)
{
ba_space
=
BundleAdjuster
::
FOCAL_RAY_SPACE
;
if
(
string
(
argv
[
i
+
1
])
==
"no"
)
else
ba_space
=
BundleAdjuster
::
NO
;
{
else
if
(
string
(
argv
[
i
+
1
])
==
"ray"
)
cout
<<
"Bad bundle adjustment space
\n
"
;
ba_space
=
BundleAdjuster
::
RAY_SPACE
;
return
-
1
;
else
if
(
string
(
argv
[
i
+
1
])
==
"focal_ray"
)
}
ba_space
=
BundleAdjuster
::
FOCAL_RAY_SPACE
;
i
++
;
else
}
{
else
if
(
string
(
argv
[
i
])
==
"--conf_thresh"
)
cout
<<
"Bad bundle adjustment space
\n
"
;
{
return
-
1
;
conf_thresh
=
static_cast
<
float
>
(
atof
(
argv
[
i
+
1
]));
}
i
++
;
i
++
;
}
}
else
if
(
string
(
argv
[
i
])
==
"--wave_correct"
)
else
if
(
string
(
argv
[
i
])
==
"--conf_thresh"
)
{
{
if
(
string
(
argv
[
i
+
1
])
==
"no"
)
conf_thresh
=
static_cast
<
float
>
(
atof
(
argv
[
i
+
1
]));
wave_correct
=
false
;
i
++
;
else
if
(
string
(
argv
[
i
+
1
])
==
"yes"
)
}
wave_correct
=
true
;
else
if
(
string
(
argv
[
i
])
==
"--wave_correct"
)
else
{
{
if
(
string
(
argv
[
i
+
1
])
==
"no"
)
cout
<<
"Bad --wave_correct flag value
\n
"
;
wave_correct
=
false
;
return
-
1
;
else
if
(
string
(
argv
[
i
+
1
])
==
"yes"
)
}
wave_correct
=
true
;
i
++
;
else
}
{
else
if
(
string
(
argv
[
i
])
==
"--save_graph"
)
cout
<<
"Bad --wave_correct flag value
\n
"
;
{
return
-
1
;
save_graph
=
true
;
}
save_graph_to
=
argv
[
i
+
1
];
i
++
;
i
++
;
}
}
else
if
(
string
(
argv
[
i
])
==
"--save_graph"
)
else
if
(
string
(
argv
[
i
])
==
"--warp"
)
{
{
save_graph
=
true
;
if
(
string
(
argv
[
i
+
1
])
==
"plane"
)
save_graph_to
=
argv
[
i
+
1
];
warp_type
=
Warper
::
PLANE
;
i
++
;
else
if
(
string
(
argv
[
i
+
1
])
==
"cylindrical"
)
}
warp_type
=
Warper
::
CYLINDRICAL
;
else
if
(
string
(
argv
[
i
])
==
"--warp"
)
else
if
(
string
(
argv
[
i
+
1
])
==
"spherical"
)
{
warp_type
=
Warper
::
SPHERICAL
;
if
(
string
(
argv
[
i
+
1
])
==
"plane"
)
else
warp_type
=
Warper
::
PLANE
;
{
else
if
(
string
(
argv
[
i
+
1
])
==
"cylindrical"
)
cout
<<
"Bad warping method
\n
"
;
warp_type
=
Warper
::
CYLINDRICAL
;
return
-
1
;
else
if
(
string
(
argv
[
i
+
1
])
==
"spherical"
)
}
warp_type
=
Warper
::
SPHERICAL
;
i
++
;
else
}
{
else
if
(
string
(
argv
[
i
])
==
"--expos_comp"
)
cout
<<
"Bad warping method
\n
"
;
{
return
-
1
;
if
(
string
(
argv
[
i
+
1
])
==
"no"
)
}
expos_comp_type
=
ExposureCompensator
::
NO
;
i
++
;
else
if
(
string
(
argv
[
i
+
1
])
==
"gain"
)
}
expos_comp_type
=
ExposureCompensator
::
GAIN
;
else
if
(
string
(
argv
[
i
])
==
"--expos_comp"
)
else
if
(
string
(
argv
[
i
+
1
])
==
"gain_blocks"
)
{
expos_comp_type
=
ExposureCompensator
::
GAIN_BLOCKS
;
if
(
string
(
argv
[
i
+
1
])
==
"no"
)
else
expos_comp_type
=
ExposureCompensator
::
NO
;
{
else
if
(
string
(
argv
[
i
+
1
])
==
"gain"
)
cout
<<
"Bad exposure compensation method
\n
"
;
expos_comp_type
=
ExposureCompensator
::
GAIN
;
return
-
1
;
else
if
(
string
(
argv
[
i
+
1
])
==
"gain_blocks"
)
}
expos_comp_type
=
ExposureCompensator
::
GAIN_BLOCKS
;
i
++
;
else
}
{
else
if
(
string
(
argv
[
i
])
==
"--seam"
)
cout
<<
"Bad exposure compensation method
\n
"
;
{
return
-
1
;
if
(
string
(
argv
[
i
+
1
])
==
"no"
)
}
seam_find_type
=
SeamFinder
::
NO
;
i
++
;
else
if
(
string
(
argv
[
i
+
1
])
==
"voronoi"
)
}
seam_find_type
=
SeamFinder
::
VORONOI
;
else
if
(
string
(
argv
[
i
])
==
"--seam"
)
else
if
(
string
(
argv
[
i
+
1
])
==
"gc_color"
)
{
seam_find_type
=
SeamFinder
::
GC_COLOR
;
if
(
string
(
argv
[
i
+
1
])
==
"no"
)
else
if
(
string
(
argv
[
i
+
1
])
==
"gc_colorgrad"
)
seam_find_type
=
SeamFinder
::
NO
;
seam_find_type
=
SeamFinder
::
GC_COLOR_GRAD
;
else
if
(
string
(
argv
[
i
+
1
])
==
"voronoi"
)
else
seam_find_type
=
SeamFinder
::
VORONOI
;
{
else
if
(
string
(
argv
[
i
+
1
])
==
"gc_color"
)
cout
<<
"Bad seam finding method
\n
"
;
seam_find_type
=
SeamFinder
::
GC_COLOR
;
return
-
1
;
else
if
(
string
(
argv
[
i
+
1
])
==
"gc_colorgrad"
)
}
seam_find_type
=
SeamFinder
::
GC_COLOR_GRAD
;
i
++
;
else
}
{
else
if
(
string
(
argv
[
i
])
==
"--blend"
)
cout
<<
"Bad seam finding method
\n
"
;
{
return
-
1
;
if
(
string
(
argv
[
i
+
1
])
==
"no"
)
}
blend_type
=
Blender
::
NO
;
i
++
;
else
if
(
string
(
argv
[
i
+
1
])
==
"feather"
)
}
blend_type
=
Blender
::
FEATHER
;
else
if
(
string
(
argv
[
i
])
==
"--blend"
)
else
if
(
string
(
argv
[
i
+
1
])
==
"multiband"
)
{
blend_type
=
Blender
::
MULTI_BAND
;
if
(
string
(
argv
[
i
+
1
])
==
"no"
)
else
blend_type
=
Blender
::
NO
;
{
else
if
(
string
(
argv
[
i
+
1
])
==
"feather"
)
cout
<<
"Bad blending method
\n
"
;
blend_type
=
Blender
::
FEATHER
;
return
-
1
;
else
if
(
string
(
argv
[
i
+
1
])
==
"multiband"
)
}
blend_type
=
Blender
::
MULTI_BAND
;
i
++
;
else
}
{
else
if
(
string
(
argv
[
i
])
==
"--blend_strength"
)
cout
<<
"Bad blending method
\n
"
;
{
return
-
1
;
blend_strength
=
static_cast
<
float
>
(
atof
(
argv
[
i
+
1
]));
}
i
++
;
i
++
;
}
}
else
if
(
string
(
argv
[
i
])
==
"--output"
)
else
if
(
string
(
argv
[
i
])
==
"--blend_strength"
)
{
{
result_name
=
argv
[
i
+
1
];
blend_strength
=
static_cast
<
float
>
(
atof
(
argv
[
i
+
1
]));
i
++
;
i
++
;
}
}
else
else
if
(
string
(
argv
[
i
])
==
"--output"
)
img_names
.
push_back
(
argv
[
i
]);
{
}
result_name
=
argv
[
i
+
1
];
if
(
preview
)
i
++
;
{
}
compose_megapix
=
0.6
;
else
}
img_names
.
push_back
(
argv
[
i
]);
return
0
;
}
}
if
(
preview
)
{
compose_megapix
=
0.6
;
int
main
(
int
argc
,
char
*
argv
[])
}
{
return
0
;
int64
app_start_time
=
getTickCount
();
}
cv
::
setBreakOnError
(
true
);
int
retval
=
parseCmdArgs
(
argc
,
argv
);
int
main
(
int
argc
,
char
*
argv
[])
if
(
retval
)
{
return
retval
;
int64
app_start_time
=
getTickCount
();
cv
::
setBreakOnError
(
true
);
// Check if have enough images
int
num_images
=
static_cast
<
int
>
(
img_names
.
size
());
int
retval
=
parseCmdArgs
(
argc
,
argv
);
if
(
num_images
<
2
)
if
(
retval
)
{
return
retval
;
LOGLN
(
"Need more images"
);
return
-
1
;
// Check if have enough images
}
int
num_images
=
static_cast
<
int
>
(
img_names
.
size
());
if
(
num_images
<
2
)
double
work_scale
=
1
,
seam_scale
=
1
,
compose_scale
=
1
;
{
bool
is_work_scale_set
=
false
,
is_seam_scale_set
=
false
,
is_compose_scale_set
=
false
;
LOGLN
(
"Need more images"
);
return
-
1
;
LOGLN
(
"Finding features..."
);
}
int64
t
=
getTickCount
();
double
work_scale
=
1
,
seam_scale
=
1
,
compose_scale
=
1
;
vector
<
ImageFeatures
>
features
(
num_images
);
bool
is_work_scale_set
=
false
,
is_seam_scale_set
=
false
,
is_compose_scale_set
=
false
;
SurfFeaturesFinder
finder
(
try_gpu
);
Mat
full_img
,
img
;
LOGLN
(
"Finding features..."
);
int64
t
=
getTickCount
();
vector
<
Mat
>
images
(
num_images
);
vector
<
Size
>
full_img_sizes
(
num_images
);
vector
<
ImageFeatures
>
features
(
num_images
);
double
seam_work_aspect
=
1
;
SurfFeaturesFinder
finder
(
try_gpu
);
Mat
full_img
,
img
;
for
(
int
i
=
0
;
i
<
num_images
;
++
i
)
{
vector
<
Mat
>
images
(
num_images
);
full_img
=
imread
(
img_names
[
i
]);
vector
<
Size
>
full_img_sizes
(
num_images
);
full_img_sizes
[
i
]
=
full_img
.
size
();
double
seam_work_aspect
=
1
;
if
(
full_img
.
empty
())
for
(
int
i
=
0
;
i
<
num_images
;
++
i
)
{
{
LOGLN
(
"Can't open image "
<<
img_names
[
i
]);
full_img
=
imread
(
img_names
[
i
]);
return
-
1
;
full_img_sizes
[
i
]
=
full_img
.
size
();
}
if
(
work_megapix
<
0
)
if
(
full_img
.
empty
())
{
{
img
=
full_img
;
LOGLN
(
"Can't open image "
<<
img_names
[
i
]);
work_scale
=
1
;
return
-
1
;
is_work_scale_set
=
true
;
}
}
if
(
work_megapix
<
0
)
else
{
{
img
=
full_img
;
if
(
!
is_work_scale_set
)
work_scale
=
1
;
{
is_work_scale_set
=
true
;
work_scale
=
min
(
1.0
,
sqrt
(
work_megapix
*
1e6
/
full_img
.
size
().
area
()));
}
is_work_scale_set
=
true
;
else
}
{
resize
(
full_img
,
img
,
Size
(),
work_scale
,
work_scale
);
if
(
!
is_work_scale_set
)
}
{
if
(
!
is_seam_scale_set
)
work_scale
=
min
(
1.0
,
sqrt
(
work_megapix
*
1e6
/
full_img
.
size
().
area
()));
{
is_work_scale_set
=
true
;
seam_scale
=
min
(
1.0
,
sqrt
(
seam_megapix
*
1e6
/
full_img
.
size
().
area
()));
}
seam_work_aspect
=
seam_scale
/
work_scale
;
resize
(
full_img
,
img
,
Size
(),
work_scale
,
work_scale
);
is_seam_scale_set
=
true
;
}
}
if
(
!
is_seam_scale_set
)
{
finder
(
img
,
features
[
i
]);
seam_scale
=
min
(
1.0
,
sqrt
(
seam_megapix
*
1e6
/
full_img
.
size
().
area
()));
features
[
i
].
img_idx
=
i
;
seam_work_aspect
=
seam_scale
/
work_scale
;
LOGLN
(
"Features in image #"
<<
i
+
1
<<
": "
<<
features
[
i
].
keypoints
.
size
());
is_seam_scale_set
=
true
;
}
resize
(
full_img
,
img
,
Size
(),
seam_scale
,
seam_scale
);
images
[
i
]
=
img
.
clone
();
finder
(
img
,
features
[
i
]);
}
features
[
i
].
img_idx
=
i
;
LOGLN
(
"Features in image #"
<<
i
+
1
<<
": "
<<
features
[
i
].
keypoints
.
size
());
finder
.
releaseMemory
();
resize
(
full_img
,
img
,
Size
(),
seam_scale
,
seam_scale
);
full_img
.
release
();
images
[
i
]
=
img
.
clone
();
img
.
release
();
}
LOGLN
(
"Finding features, time: "
<<
((
getTickCount
()
-
t
)
/
getTickFrequency
())
<<
" sec"
);
finder
.
releaseMemory
();
LOG
(
"Pairwise matching"
);
full_img
.
release
();
t
=
getTickCount
();
img
.
release
();
vector
<
MatchesInfo
>
pairwise_matches
;
BestOf2NearestMatcher
matcher
(
try_gpu
,
match_conf
);
LOGLN
(
"Finding features, time: "
<<
((
getTickCount
()
-
t
)
/
getTickFrequency
())
<<
" sec"
);
matcher
(
features
,
pairwise_matches
);
matcher
.
releaseMemory
();
LOG
(
"Pairwise matching"
);
LOGLN
(
"Pairwise matching, time: "
<<
((
getTickCount
()
-
t
)
/
getTickFrequency
())
<<
" sec"
);
t
=
getTickCount
();
vector
<
MatchesInfo
>
pairwise_matches
;
// Check if we should save matches graph
BestOf2NearestMatcher
matcher
(
try_gpu
,
match_conf
);
if
(
save_graph
)
matcher
(
features
,
pairwise_matches
);
{
matcher
.
releaseMemory
();
LOGLN
(
"Saving matches graph..."
);
LOGLN
(
"Pairwise matching, time: "
<<
((
getTickCount
()
-
t
)
/
getTickFrequency
())
<<
" sec"
);
ofstream
f
(
save_graph_to
.
c_str
());
f
<<
matchesGraphAsString
(
img_names
,
pairwise_matches
,
conf_thresh
);
// Check if we should save matches graph
}
if
(
save_graph
)
{
// Leave only images we are sure are from the same panorama
LOGLN
(
"Saving matches graph..."
);
vector
<
int
>
indices
=
leaveBiggestComponent
(
features
,
pairwise_matches
,
conf_thresh
);
ofstream
f
(
save_graph_to
.
c_str
());
vector
<
Mat
>
img_subset
;
f
<<
matchesGraphAsString
(
img_names
,
pairwise_matches
,
conf_thresh
);
vector
<
string
>
img_names_subset
;
}
vector
<
Size
>
full_img_sizes_subset
;
for
(
size_t
i
=
0
;
i
<
indices
.
size
();
++
i
)
// Leave only images we are sure are from the same panorama
{
vector
<
int
>
indices
=
leaveBiggestComponent
(
features
,
pairwise_matches
,
conf_thresh
);
img_names_subset
.
push_back
(
img_names
[
indices
[
i
]]);
vector
<
Mat
>
img_subset
;
img_subset
.
push_back
(
images
[
indices
[
i
]]);
vector
<
string
>
img_names_subset
;
full_img_sizes_subset
.
push_back
(
full_img_sizes
[
indices
[
i
]]);
vector
<
Size
>
full_img_sizes_subset
;
}
for
(
size_t
i
=
0
;
i
<
indices
.
size
();
++
i
)
{
images
=
img_subset
;
img_names_subset
.
push_back
(
img_names
[
indices
[
i
]]);
img_names
=
img_names_subset
;
img_subset
.
push_back
(
images
[
indices
[
i
]]);
full_img_sizes
=
full_img_sizes_subset
;
full_img_sizes_subset
.
push_back
(
full_img_sizes
[
indices
[
i
]]);
}
// Check if we still have enough images
num_images
=
static_cast
<
int
>
(
img_names
.
size
());
images
=
img_subset
;
if
(
num_images
<
2
)
img_names
=
img_names_subset
;
{
full_img_sizes
=
full_img_sizes_subset
;
LOGLN
(
"Need more images"
);
return
-
1
;
// Check if we still have enough images
}
num_images
=
static_cast
<
int
>
(
img_names
.
size
());
if
(
num_images
<
2
)
HomographyBasedEstimator
estimator
;
{
vector
<
CameraParams
>
cameras
;
LOGLN
(
"Need more images"
);
estimator
(
features
,
pairwise_matches
,
cameras
);
return
-
1
;
}
for
(
size_t
i
=
0
;
i
<
cameras
.
size
();
++
i
)
{
HomographyBasedEstimator
estimator
;
Mat
R
;
vector
<
CameraParams
>
cameras
;
cameras
[
i
].
R
.
convertTo
(
R
,
CV_32F
);
estimator
(
features
,
pairwise_matches
,
cameras
);
cameras
[
i
].
R
=
R
;
LOGLN
(
"Initial focal length #"
<<
indices
[
i
]
+
1
<<
": "
<<
cameras
[
i
].
focal
);
for
(
size_t
i
=
0
;
i
<
cameras
.
size
();
++
i
)
}
{
Mat
R
;
BundleAdjuster
adjuster
(
ba_space
,
conf_thresh
);
cameras
[
i
].
R
.
convertTo
(
R
,
CV_32F
);
adjuster
(
features
,
pairwise_matches
,
cameras
);
cameras
[
i
].
R
=
R
;
LOGLN
(
"Initial focal length #"
<<
indices
[
i
]
+
1
<<
": "
<<
cameras
[
i
].
focal
);
// Find median focal length
}
vector
<
double
>
focals
;
for
(
size_t
i
=
0
;
i
<
cameras
.
size
();
++
i
)
BundleAdjuster
adjuster
(
ba_space
,
conf_thresh
);
{
adjuster
(
features
,
pairwise_matches
,
cameras
);
LOGLN
(
"Camera #"
<<
indices
[
i
]
+
1
<<
" focal length: "
<<
cameras
[
i
].
focal
);
focals
.
push_back
(
cameras
[
i
].
focal
);
// Find median focal length
}
vector
<
double
>
focals
;
nth_element
(
focals
.
begin
(),
focals
.
begin
()
+
focals
.
size
()
/
2
,
focals
.
end
());
for
(
size_t
i
=
0
;
i
<
cameras
.
size
();
++
i
)
float
warped_image_scale
=
static_cast
<
float
>
(
focals
[
focals
.
size
()
/
2
]);
{
LOGLN
(
"Camera #"
<<
indices
[
i
]
+
1
<<
" focal length: "
<<
cameras
[
i
].
focal
);
if
(
wave_correct
)
focals
.
push_back
(
cameras
[
i
].
focal
);
{
}
vector
<
Mat
>
rmats
;
nth_element
(
focals
.
begin
(),
focals
.
begin
()
+
focals
.
size
()
/
2
,
focals
.
end
());
for
(
size_t
i
=
0
;
i
<
cameras
.
size
();
++
i
)
float
warped_image_scale
=
static_cast
<
float
>
(
focals
[
focals
.
size
()
/
2
]);
rmats
.
push_back
(
cameras
[
i
].
R
);
waveCorrect
(
rmats
);
if
(
wave_correct
)
for
(
size_t
i
=
0
;
i
<
cameras
.
size
();
++
i
)
{
cameras
[
i
].
R
=
rmats
[
i
];
vector
<
Mat
>
rmats
;
}
for
(
size_t
i
=
0
;
i
<
cameras
.
size
();
++
i
)
rmats
.
push_back
(
cameras
[
i
].
R
);
LOGLN
(
"Warping images (auxiliary)... "
);
waveCorrect
(
rmats
);
t
=
getTickCount
();
for
(
size_t
i
=
0
;
i
<
cameras
.
size
();
++
i
)
cameras
[
i
].
R
=
rmats
[
i
];
vector
<
Point
>
corners
(
num_images
);
}
vector
<
Mat
>
masks_warped
(
num_images
);
vector
<
Mat
>
images_warped
(
num_images
);
LOGLN
(
"Warping images (auxiliary)... "
);
vector
<
Size
>
sizes
(
num_images
);
t
=
getTickCount
();
vector
<
Mat
>
masks
(
num_images
);
vector
<
Point
>
corners
(
num_images
);
// Preapre images masks
vector
<
Mat
>
masks_warped
(
num_images
);
for
(
int
i
=
0
;
i
<
num_images
;
++
i
)
vector
<
Mat
>
images_warped
(
num_images
);
{
vector
<
Size
>
sizes
(
num_images
);
masks
[
i
].
create
(
images
[
i
].
size
(),
CV_8U
);
vector
<
Mat
>
masks
(
num_images
);
masks
[
i
].
setTo
(
Scalar
::
all
(
255
));
}
// Preapre images masks
for
(
int
i
=
0
;
i
<
num_images
;
++
i
)
// Warp images and their masks
{
Ptr
<
Warper
>
warper
=
Warper
::
createByCameraFocal
(
static_cast
<
float
>
(
warped_image_scale
*
seam_work_aspect
),
masks
[
i
].
create
(
images
[
i
].
size
(),
CV_8U
);
warp_type
,
try_gpu
);
masks
[
i
].
setTo
(
Scalar
::
all
(
255
));
for
(
int
i
=
0
;
i
<
num_images
;
++
i
)
}
{
corners
[
i
]
=
warper
->
warp
(
images
[
i
],
static_cast
<
float
>
(
cameras
[
i
].
focal
*
seam_work_aspect
),
// Warp images and their masks
cameras
[
i
].
R
,
images_warped
[
i
]);
Ptr
<
Warper
>
warper
=
Warper
::
createByCameraFocal
(
static_cast
<
float
>
(
warped_image_scale
*
seam_work_aspect
),
sizes
[
i
]
=
images_warped
[
i
].
size
();
warp_type
,
try_gpu
);
warper
->
warp
(
masks
[
i
],
static_cast
<
float
>
(
cameras
[
i
].
focal
*
seam_work_aspect
),
for
(
int
i
=
0
;
i
<
num_images
;
++
i
)
cameras
[
i
].
R
,
masks_warped
[
i
],
INTER_NEAREST
,
BORDER_CONSTANT
);
{
}
corners
[
i
]
=
warper
->
warp
(
images
[
i
],
static_cast
<
float
>
(
cameras
[
i
].
focal
*
seam_work_aspect
),
cameras
[
i
].
R
,
images_warped
[
i
]);
vector
<
Mat
>
images_warped_f
(
num_images
);
sizes
[
i
]
=
images_warped
[
i
].
size
();
for
(
int
i
=
0
;
i
<
num_images
;
++
i
)
warper
->
warp
(
masks
[
i
],
static_cast
<
float
>
(
cameras
[
i
].
focal
*
seam_work_aspect
),
images_warped
[
i
].
convertTo
(
images_warped_f
[
i
],
CV_32F
);
cameras
[
i
].
R
,
masks_warped
[
i
],
INTER_NEAREST
,
BORDER_CONSTANT
);
}
LOGLN
(
"Warping images, time: "
<<
((
getTickCount
()
-
t
)
/
getTickFrequency
())
<<
" sec"
);
vector
<
Mat
>
images_warped_f
(
num_images
);
Ptr
<
ExposureCompensator
>
compensator
=
ExposureCompensator
::
createDefault
(
expos_comp_type
);
for
(
int
i
=
0
;
i
<
num_images
;
++
i
)
compensator
->
feed
(
corners
,
images_warped
,
masks_warped
);
images_warped
[
i
].
convertTo
(
images_warped_f
[
i
],
CV_32F
);
Ptr
<
SeamFinder
>
seam_finder
=
SeamFinder
::
createDefault
(
seam_find_type
);
LOGLN
(
"Warping images, time: "
<<
((
getTickCount
()
-
t
)
/
getTickFrequency
())
<<
" sec"
);
seam_finder
->
find
(
images_warped_f
,
corners
,
masks_warped
);
Ptr
<
ExposureCompensator
>
compensator
=
ExposureCompensator
::
createDefault
(
expos_comp_type
);
// Release unused memory
compensator
->
feed
(
corners
,
images_warped
,
masks_warped
);
images
.
clear
();
images_warped
.
clear
();
Ptr
<
SeamFinder
>
seam_finder
=
SeamFinder
::
createDefault
(
seam_find_type
);
images_warped_f
.
clear
();
seam_finder
->
find
(
images_warped_f
,
corners
,
masks_warped
);
masks
.
clear
();
// Release unused memory
LOGLN
(
"Compositing..."
);
images
.
clear
();
t
=
getTickCount
();
images_warped
.
clear
();
images_warped_f
.
clear
();
Mat
img_warped
,
img_warped_s
;
masks
.
clear
();
Mat
dilated_mask
,
seam_mask
,
mask
,
mask_warped
;
Ptr
<
Blender
>
blender
;
LOGLN
(
"Compositing..."
);
double
compose_seam_aspect
=
1
;
t
=
getTickCount
();
double
compose_work_aspect
=
1
;
Mat
img_warped
,
img_warped_s
;
for
(
int
img_idx
=
0
;
img_idx
<
num_images
;
++
img_idx
)
Mat
dilated_mask
,
seam_mask
,
mask
,
mask_warped
;
{
Ptr
<
Blender
>
blender
;
LOGLN
(
"Compositing image #"
<<
indices
[
img_idx
]
+
1
);
double
compose_seam_aspect
=
1
;
double
compose_work_aspect
=
1
;
// Read image and resize it if necessary
full_img
=
imread
(
img_names
[
img_idx
]);
for
(
int
img_idx
=
0
;
img_idx
<
num_images
;
++
img_idx
)
if
(
!
is_compose_scale_set
)
{
{
LOGLN
(
"Compositing image #"
<<
indices
[
img_idx
]
+
1
);
if
(
compose_megapix
>
0
)
compose_scale
=
min
(
1.0
,
sqrt
(
compose_megapix
*
1e6
/
full_img
.
size
().
area
()));
// Read image and resize it if necessary
is_compose_scale_set
=
true
;
full_img
=
imread
(
img_names
[
img_idx
]);
if
(
!
is_compose_scale_set
)
// Compute relative scales
{
compose_seam_aspect
=
compose_scale
/
seam_scale
;
if
(
compose_megapix
>
0
)
compose_work_aspect
=
compose_scale
/
work_scale
;
compose_scale
=
min
(
1.0
,
sqrt
(
compose_megapix
*
1e6
/
full_img
.
size
().
area
()));
is_compose_scale_set
=
true
;
// Update warped image scale
warped_image_scale
*=
static_cast
<
float
>
(
compose_work_aspect
);
// Compute relative scales
warper
=
Warper
::
createByCameraFocal
(
warped_image_scale
,
warp_type
,
try_gpu
);
compose_seam_aspect
=
compose_scale
/
seam_scale
;
compose_work_aspect
=
compose_scale
/
work_scale
;
// Update corners and sizes
for
(
int
i
=
0
;
i
<
num_images
;
++
i
)
// Update warped image scale
{
warped_image_scale
*=
static_cast
<
float
>
(
compose_work_aspect
);
// Update camera focal
warper
=
Warper
::
createByCameraFocal
(
warped_image_scale
,
warp_type
,
try_gpu
);
cameras
[
i
].
focal
*=
compose_work_aspect
;
// Update corners and sizes
// Update corner and size
for
(
int
i
=
0
;
i
<
num_images
;
++
i
)
Size
sz
=
full_img_sizes
[
i
];
{
if
(
abs
(
compose_scale
-
1
)
>
1e-1
)
// Update camera focal
{
cameras
[
i
].
focal
*=
compose_work_aspect
;
sz
.
width
=
cvRound
(
full_img_sizes
[
i
].
width
*
compose_scale
);
sz
.
height
=
cvRound
(
full_img_sizes
[
i
].
height
*
compose_scale
);
// Update corner and size
}
Size
sz
=
full_img_sizes
[
i
];
if
(
abs
(
compose_scale
-
1
)
>
1e-1
)
Rect
roi
=
warper
->
warpRoi
(
sz
,
static_cast
<
float
>
(
cameras
[
i
].
focal
),
cameras
[
i
].
R
);
{
corners
[
i
]
=
roi
.
tl
();
sz
.
width
=
cvRound
(
full_img_sizes
[
i
].
width
*
compose_scale
);
sizes
[
i
]
=
roi
.
size
();
sz
.
height
=
cvRound
(
full_img_sizes
[
i
].
height
*
compose_scale
);
}
}
}
if
(
abs
(
compose_scale
-
1
)
>
1e-1
)
Rect
roi
=
warper
->
warpRoi
(
sz
,
static_cast
<
float
>
(
cameras
[
i
].
focal
),
cameras
[
i
].
R
);
resize
(
full_img
,
img
,
Size
(),
compose_scale
,
compose_scale
);
corners
[
i
]
=
roi
.
tl
();
else
sizes
[
i
]
=
roi
.
size
();
img
=
full_img
;
}
full_img
.
release
();
}
Size
img_size
=
img
.
size
();
if
(
abs
(
compose_scale
-
1
)
>
1e-1
)
resize
(
full_img
,
img
,
Size
(),
compose_scale
,
compose_scale
);
// Warp the current image
else
warper
->
warp
(
img
,
static_cast
<
float
>
(
cameras
[
img_idx
].
focal
),
cameras
[
img_idx
].
R
,
img
=
full_img
;
img_warped
);
full_img
.
release
();
Size
img_size
=
img
.
size
();
// Warp the current image mask
mask
.
create
(
img_size
,
CV_8U
);
// Warp the current image
mask
.
setTo
(
Scalar
::
all
(
255
));
warper
->
warp
(
img
,
static_cast
<
float
>
(
cameras
[
img_idx
].
focal
),
cameras
[
img_idx
].
R
,
warper
->
warp
(
mask
,
static_cast
<
float
>
(
cameras
[
img_idx
].
focal
),
cameras
[
img_idx
].
R
,
mask_warped
,
img_warped
);
INTER_NEAREST
,
BORDER_CONSTANT
);
// Warp the current image mask
// Compensate exposure
mask
.
create
(
img_size
,
CV_8U
);
compensator
->
apply
(
img_idx
,
corners
[
img_idx
],
img_warped
,
mask_warped
);
mask
.
setTo
(
Scalar
::
all
(
255
));
warper
->
warp
(
mask
,
static_cast
<
float
>
(
cameras
[
img_idx
].
focal
),
cameras
[
img_idx
].
R
,
mask_warped
,
img_warped
.
convertTo
(
img_warped_s
,
CV_16S
);
INTER_NEAREST
,
BORDER_CONSTANT
);
img_warped
.
release
();
img
.
release
();
// Compensate exposure
mask
.
release
();
compensator
->
apply
(
img_idx
,
corners
[
img_idx
],
img_warped
,
mask_warped
);
dilate
(
masks_warped
[
img_idx
],
dilated_mask
,
Mat
());
img_warped
.
convertTo
(
img_warped_s
,
CV_16S
);
resize
(
dilated_mask
,
seam_mask
,
mask_warped
.
size
());
img_warped
.
release
();
mask_warped
=
seam_mask
&
mask_warped
;
img
.
release
();
mask
.
release
();
if
(
blender
.
empty
())
{
dilate
(
masks_warped
[
img_idx
],
dilated_mask
,
Mat
());
blender
=
Blender
::
createDefault
(
blend_type
,
try_gpu
);
resize
(
dilated_mask
,
seam_mask
,
mask_warped
.
size
());
Size
dst_sz
=
resultRoi
(
corners
,
sizes
).
size
();
mask_warped
=
seam_mask
&
mask_warped
;
float
blend_width
=
sqrt
(
static_cast
<
float
>
(
dst_sz
.
area
()))
*
blend_strength
/
100.
f
;
if
(
blend_width
<
1.
f
)
if
(
blender
.
empty
())
blender
=
Blender
::
createDefault
(
Blender
::
NO
,
try_gpu
);
{
else
if
(
blend_type
==
Blender
::
MULTI_BAND
)
blender
=
Blender
::
createDefault
(
blend_type
,
try_gpu
);
{
Size
dst_sz
=
resultRoi
(
corners
,
sizes
).
size
();
MultiBandBlender
*
mb
=
dynamic_cast
<
MultiBandBlender
*>
(
static_cast
<
Blender
*>
(
blender
));
float
blend_width
=
sqrt
(
static_cast
<
float
>
(
dst_sz
.
area
()))
*
blend_strength
/
100.
f
;
mb
->
setNumBands
(
static_cast
<
int
>
(
ceil
(
log
(
blend_width
)
/
log
(
2.
))
-
1.
));
if
(
blend_width
<
1.
f
)
LOGLN
(
"Multi-band blender, number of bands: "
<<
mb
->
numBands
());
blender
=
Blender
::
createDefault
(
Blender
::
NO
,
try_gpu
);
}
else
if
(
blend_type
==
Blender
::
MULTI_BAND
)
else
if
(
blend_type
==
Blender
::
FEATHER
)
{
{
MultiBandBlender
*
mb
=
dynamic_cast
<
MultiBandBlender
*>
(
static_cast
<
Blender
*>
(
blender
));
FeatherBlender
*
fb
=
dynamic_cast
<
FeatherBlender
*>
(
static_cast
<
Blender
*>
(
blender
));
mb
->
setNumBands
(
static_cast
<
int
>
(
ceil
(
log
(
blend_width
)
/
log
(
2.
))
-
1.
));
fb
->
setSharpness
(
1.
f
/
blend_width
);
LOGLN
(
"Multi-band blender, number of bands: "
<<
mb
->
numBands
());
LOGLN
(
"Feather blender, sharpness: "
<<
fb
->
sharpness
());
}
}
else
if
(
blend_type
==
Blender
::
FEATHER
)
blender
->
prepare
(
corners
,
sizes
);
{
}
FeatherBlender
*
fb
=
dynamic_cast
<
FeatherBlender
*>
(
static_cast
<
Blender
*>
(
blender
));
fb
->
setSharpness
(
1.
f
/
blend_width
);
// Blend the current image
LOGLN
(
"Feather blender, sharpness: "
<<
fb
->
sharpness
());
blender
->
feed
(
img_warped_s
,
mask_warped
,
corners
[
img_idx
]);
}
}
blender
->
prepare
(
corners
,
sizes
);
}
Mat
result
,
result_mask
;
blender
->
blend
(
result
,
result_mask
);
// Blend the current image
blender
->
feed
(
img_warped_s
,
mask_warped
,
corners
[
img_idx
]);
LOGLN
(
"Compositing, time: "
<<
((
getTickCount
()
-
t
)
/
getTickFrequency
())
<<
" sec"
);
}
imwrite
(
result_name
,
result
);
Mat
result
,
result_mask
;
blender
->
blend
(
result
,
result_mask
);
LOGLN
(
"Finished, total time: "
<<
((
getTickCount
()
-
app_start_time
)
/
getTickFrequency
())
<<
" sec"
);
return
0
;
LOGLN
(
"Compositing, time: "
<<
((
getTickCount
()
-
t
)
/
getTickFrequency
())
<<
" sec"
);
}
imwrite
(
result_name
,
result
);
LOGLN
(
"Finished, total time: "
<<
((
getTickCount
()
-
app_start_time
)
/
getTickFrequency
())
<<
" sec"
);
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