图像拼接
来源:互联网 发布:java 生产表单创建表 编辑:程序博客网 时间:2024/05/20 02:22
室友做磨粒切削的研究,其中需要用到图像拼接的技术,然后找上了我。虽然不是研究这一块的,但是总不能见死不救。抱着试一试的心态,没想到进展还挺顺的。
代码如下:
#include "stdafx.h"#include <iostream>#include <fstream>#include <opencv2/core/core.hpp>#include "opencv2/highgui/highgui.hpp"#include "opencv2/stitching.hpp"#include<Windows.h>using namespace std;using namespace cv;bool try_use_gpu = false;vector<Mat> imgs;string result_name = "result.jpg";int main(){Mat img1 = imread("1.jpg");Mat img2 = imread("2.jpg");imgs.push_back(img1);imgs.push_back(img2);Mat pano;Stitcher stitcher = Stitcher::createDefault(try_use_gpu);Stitcher::Status status = stitcher.stitch(imgs, pano);if (status != Stitcher::OK){cout << "Can't stitch images, error code = " << status << endl;return -1;}namedWindow(result_name);imshow(result_name, pano);imwrite(result_name, pano);waitKey();return 0;}
效果图如下:
可见,关键的代码还是这两句:
Stitcher stitcher = Stitcher::createDefault(try_use_gpu);Stitcher::Status status = stitcher.stitch(imgs, pano);
Stitcher 是Opencv的一个类,下面看一看这个类的源代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
class
CV_EXPORTS Stitcher
{
public
:
enum
{ ORIG_RESOL = -1 };
enum
Status { OK, ERR_NEED_MORE_IMGS };
// Creates stitcher with default parameters
static
Stitcher createDefault(
bool
try_use_gpu =
false
);
Status estimateTransform(InputArray images);
Status estimateTransform(InputArray images,
const
std::vector<std::vector<Rect> > &rois);
Status composePanorama(OutputArray pano);
Status composePanorama(InputArray images, OutputArray pano);
Status stitch(InputArray images, OutputArray pano);
Status stitch(InputArray images,
const
std::vector<std::vector<Rect> > &rois, OutputArray pano);
double
registrationResol()
const
{
return
registr_resol_; }
void
setRegistrationResol(
double
resol_mpx) { registr_resol_ = resol_mpx; }
double
seamEstimationResol()
const
{
return
seam_est_resol_; }
void
setSeamEstimationResol(
double
resol_mpx) { seam_est_resol_ = resol_mpx; }
double
compositingResol()
const
{
return
compose_resol_; }
void
setCompositingResol(
double
resol_mpx) { compose_resol_ = resol_mpx; }
double
panoConfidenceThresh()
const
{
return
conf_thresh_; }
void
setPanoConfidenceThresh(
double
conf_thresh) { conf_thresh_ = conf_thresh; }
bool
waveCorrection()
const
{
return
do_wave_correct_; }
void
setWaveCorrection(
bool
flag) { do_wave_correct_ = flag; }
detail::WaveCorrectKind waveCorrectKind()
const
{
return
wave_correct_kind_; }
void
setWaveCorrectKind(detail::WaveCorrectKind kind) { wave_correct_kind_ = kind; }
Ptr<detail::FeaturesFinder> featuresFinder() {
return
features_finder_; }
const
Ptr<detail::FeaturesFinder> featuresFinder()
const
{
return
features_finder_; }
void
setFeaturesFinder(Ptr<detail::FeaturesFinder> features_finder)
{ features_finder_ = features_finder; }
Ptr<detail::FeaturesMatcher> featuresMatcher() {
return
features_matcher_; }
const
Ptr<detail::FeaturesMatcher> featuresMatcher()
const
{
return
features_matcher_; }
void
setFeaturesMatcher(Ptr<detail::FeaturesMatcher> features_matcher)
{ features_matcher_ = features_matcher; }
const
cv::Mat& matchingMask()
const
{
return
matching_mask_; }
void
setMatchingMask(
const
cv::Mat &mask)
{
CV_Assert(mask.type() == CV_8U && mask.cols == mask.rows);
matching_mask_ = mask.clone();
}
Ptr<detail::BundleAdjusterBase> bundleAdjuster() {
return
bundle_adjuster_; }
const
Ptr<detail::BundleAdjusterBase> bundleAdjuster()
const
{
return
bundle_adjuster_; }
void
setBundleAdjuster(Ptr<detail::BundleAdjusterBase> bundle_adjuster)
{ bundle_adjuster_ = bundle_adjuster; }
Ptr<WarperCreator> warper() {
return
warper_; }
const
Ptr<WarperCreator> warper()
const
{
return
warper_; }
void
setWarper(Ptr<WarperCreator> warper) { warper_ = warper; }
Ptr<detail::ExposureCompensator> exposureCompensator() {
return
exposure_comp_; }
const
Ptr<detail::ExposureCompensator> exposureCompensator()
const
{
return
exposure_comp_; }
void
setExposureCompensator(Ptr<detail::ExposureCompensator> exposure_comp)
{ exposure_comp_ = exposure_comp; }
Ptr<detail::SeamFinder> seamFinder() {
return
seam_finder_; }
const
Ptr<detail::SeamFinder> seamFinder()
const
{
return
seam_finder_; }
void
setSeamFinder(Ptr<detail::SeamFinder> seam_finder) { seam_finder_ = seam_finder; }
Ptr<detail::Blender> blender() {
return
blender_; }
const
Ptr<detail::Blender> blender()
const
{
return
blender_; }
void
setBlender(Ptr<detail::Blender> blender) { blender_ = blender; }
private
:
/* hidden */
};
1
Stitcher stitcher = Stitcher::createDefault(try_use_gpu);这句话表示使用默认参数创建Stitcher类的对象stitcher,try_use_gpu表示是否打开GPU,默认不打开,即try_use_gpu=
false
;下面是这个函数的原型:
1
2
3
C++: Stitcher Stitcher::createDefault(
bool
try_use_gpu=
false
)
参数:Flag indicating whether GPU should be used whenever it’s possible.
return
:Stitcher
class
instance.(即创建了一个对象)
1
Stitcher::Status status = stitcher.stitch(imgs, pano);这句话表示:
try
to stitch the given images
1
2
3
4
5
6
C++: Status Stitcher::stitch(InputArray images, OutputArray pano)
C++: Status Stitcher::stitch(InputArray images,
const
std::vector<std::vector<Rect>>& rois, OutputArray pano)
参数:images – Input images.
rois – Region of interest rectangles.(感兴趣区)
pano – Final pano.
return
:Status code.(数据成员中枚举数组的一项)
Stitcher::estimateTransform和Stitcher::composePanorama的使用为高级使用,需要清楚Stitching pipeline的过程。
下面贴出pipeline:
可以看出这个过程很复杂,需要涉及到很多的算法,比如:特征点的提取、特征点匹配、图像融合等等。这些过程OpenCV都为我们封装在Stitcher类中,不在此细述。
总结
虽然用OpenCV中的Stitcher类实现了基本的拼接,但是有一个最大的问题是,运行的效率是极低的,就这个代码中,拼接3张图片差不多用了一分钟,这在需要做实时拼接的时候是根本不可能使用的,所以后面需要做的工作任然是弄清楚Stitching pipeline的详细过程,进一步优化代码,提高拼接运行效率
1 0
- 图像拼接-硬拼接
- 图像拼接
- 图像拼接
- 图像拼接
- 图像拼接
- 图像拼接
- 图像拼接
- 图像拼接
- 图像拼接
- 图像拼接
- 图像拼接
- 图像拼接
- 图像拼接
- 图像拼接
- 图像拼接
- 图像拼接
- 图像拼接
- 图像拼接
- BZOJ 4519: [Cqoi2016]不同的最小割
- IDEA UL 14如何编译打包maven工程
- Android6.0运行时权限处理详解
- 流形学习-高维数据的降维与可视化
- 13.4 获得验证码
- 图像拼接
- Oracle 创建带时间戳的表
- <button> 和 input button的对比(实实在在的被坑了一把!)
- JRE与JVM
- Algorithm JAVA写算法 验证哥德巴赫猜想
- linux密码生成
- 表情符号过滤
- Cocos的动作系统以及自定义Action
- 13.5 自定义线程