关闭

图像拼接(十三):OpenCV拼接多幅图像(以中间图像为参考)

标签: opencv图像拼接
9149人阅读 评论(8) 收藏 举报
分类:

图像拼接(七):OpenCV单应变换模型拼接多幅图像 这篇博客中实现了用单应变换模型拼接多幅图像,图像拼接使用的OpenCV库函数warpPerspective()

因为这个函数只有在右侧图像变换到左侧图像时才能完整显示,所以拼接过程选择了以最左侧图像为参考帧。由于累加误差,最右侧的图像出现严重的变形。如下所示:

这里写图片描述

在这篇博客中,我们以中间幅图像为参考图像,实现多幅拼接。图像数量为4张,从左到右分别为img4img3img2img1。以左侧第2幅图像,即img3为参考图像。

从右到左,img2img1的单应变形仍可直接使用warpPerspective(),那么从左到右,img4img3怎么办呢?

解决的办法是对img3添加一个向右距离为img3.width的平移变换。这样变形后的img4即可显示在画布中了。

这个平移变换矩阵为:

Tx=100010img3.cols01

img3 点坐标设为Ximg4点坐标设为X,则他们之间的关系为:

TxX=TxH43X

所以img4img3变换后的图像如下,注意img3的原点向右位移至中间。在之后的拼接中要考虑这一点。

img4->img3
这里写图片描述

其它图像之间的变换:

img2->img3
这里写图片描述

img1->img3
这里写图片描述

所有的4幅图像的拼接结果为:

这里写图片描述

整体观感相比图像拼接(七):OpenCV单应变换模型拼接多幅图像的结果提升不少,最右侧图像变形失真减轻。

代码

#include"Homography.h"

int main()
{
    //从右向左升序
    string imgPath1 = "trees_003.jpg";
    string imgPath2 = "trees_002.jpg";
    string imgPath3 = "trees_001.jpg";
    string imgPath4 = "trees_000.jpg";

    Mat img1 = imread(imgPath1, CV_LOAD_IMAGE_GRAYSCALE);
    Mat img2 = imread(imgPath2, CV_LOAD_IMAGE_GRAYSCALE);
    Mat img3 = imread(imgPath3, CV_LOAD_IMAGE_GRAYSCALE);
    Mat img4 = imread(imgPath4, CV_LOAD_IMAGE_GRAYSCALE);

    Mat img1_color = imread(imgPath1, CV_LOAD_IMAGE_COLOR);
    Mat img2_color = imread(imgPath2, CV_LOAD_IMAGE_COLOR);
    Mat img3_color = imread(imgPath3, CV_LOAD_IMAGE_COLOR);
    Mat img4_color = imread(imgPath4, CV_LOAD_IMAGE_COLOR);

    Homography homo12(img1, img2);
    Homography homo23(img2, img3);
    Homography homo34(img3, img4);

    Mat h12 = homo12.getHomography();
    Mat h23 = homo23.getHomography();
    Mat h34 = homo34.getHomography();

    /*homo12.drawMatches();
    homo23.drawMatches();
    homo34.drawMatches();*/

    //以从左至右第2幅图像为参考,即img3
    Mat h13 = h23*h12;
    Mat h43 = h34.inv(DECOMP_LU);

    double scale_h13 = h13.at<double>(2, 2);
    h13 = h13 / scale_h13;
    double scale_h43 = h43.at<double>(2, 2);
    h43 = h43 / scale_h43;

    Mat warp1;
    warpPerspective(img1_color, warp1, h13, Size(img3.cols * 4, img3.rows));
    Mat warp2;
    warpPerspective(img2_color, warp2, h23, Size(img3.cols * 4, img3.rows));
    Mat warp4;
    Mat Tx = (Mat_<double>(3, 3) << 1, 0, img3.cols, 0, 1, 0, 0, 0, 1);
    warpPerspective(img4_color, warp4, Tx*h43, Size(img3.cols * 2, img3.rows));

    imshow("warp1", warp1);
    imshow("warp2", warp2);
    imshow("warp4", warp4);

    imwrite("warp1.jpg", warp1);
    imwrite("warp2.jpg", warp2);
    imwrite("warp4.jpg", warp4);

    int d = img3.cols * 2 / 5;
    int x2 = h23.at<double>(0, 2) + d;
    int x1 = x2 + h12.at<double>(0, 2);

    Mat canvas(img3.rows, img3.cols * 4, CV_8UC3);
    img3_color.copyTo(canvas(Range::all(), Range(img3.cols, img3.cols*2)));
    warp2(Range::all(), Range(x2, x1)).copyTo(canvas(Range::all(), Range(x2 + img3.cols, x1 + img3.cols)));
    warp1(Range::all(), Range(x1, x1+img3.cols)).copyTo(canvas(Range::all(), Range(x1 + img3.cols, x1+img3.cols*2)));
    warp4(Range::all(), Range(0, img3.cols)).copyTo(canvas(Range::all(), Range(0, img3.cols)));

    canvas(Range::all(), Range(x1 + img3.cols * 2, img3.cols * 4)) = Scalar::all(0);

    imwrite("canvas.jpg", canvas);
    imshow("canvas", canvas);

    waitKey(0);
    return 0;
}
2
0
查看评论
发表评论
* 以上用户言论只代表其个人钱柜娱乐开户,不代表CSDN网站的钱柜娱乐开户或立场

OpenCv实现两幅图像的拼接

直接贴上源码 来源:http://www.myexception.cn/image/1498389.html 实验效果 Left.jpg             ...
  • adong76
  • adong76
  • 2014-09-23 13:56
  • 14435

opencv 基于sift的多张图片全景图拼接

这里是基于sift来寻找特征点经行图像的匹配的原理来进行图像拼接的,具体步骤如下: 1、利用sift特征探测器来检测出两幅图片的sift特征点 2、根据上一步提取到的特征点来提取特...
  • qq_26340121
  • qq_26340121
  • 2016-05-01 21:35
  • 17918

opencv实现几幅图像拼接成一整幅大图

考虑采用遍历的方式拼接图像,但不好实现。 开始尝试merge函数,具体如下: 定义四个矩阵A,B,C,D。得到矩阵combine。 #include #include #include #...
  • yang6464158
  • yang6464158
  • 2013-10-22 12:05
  • 15838

opencv 开源图像拼接

用opencv开源包实现了下图像拼接 网上搜的都是一行代码Stitcher::Status status = stitcher.stitch(imgs, pano);就出来的傻瓜拼接,连op...
  • manji_lee
  • manji_lee
  • 2013-05-31 19:23
  • 27441

特征点匹配应用——图像拼接的原理与基于OpenCV的实现

最初我看特征点匹配的东西源于三维重建,由于特征点匹配的不准确,导致两幅图像之间的位置关系计算不准确,从而使得最后生成的三维点云中有很多的噪声。看特征点匹配大概看了一个半月,把已有的除了最新的基于深度学...
  • lhanchao
  • lhanchao
  • 2016-10-30 20:47
  • 5671

opencv图像拼接,即把两个矩阵合并为一个(vconcat和hconcat)、Mat成员函数size()

Mat类的成员函数 size()当我们用size()获取一个矩阵的行数和列数时,要注意这个函数返回的结果行和列是相反的。 如Mat ab(30,15,Cv_32fC1); ab.rows;返回的结果将...
  • mikedadong
  • mikedadong
  • 2016-05-03 16:20
  • 10228

图像拼接(十二):OpenCV SeamFinder+GraphCut+最佳拼接缝寻找

很多情况下,使用一个全局单应变换并不能准确对齐图像,需要一些后处理来削弱拼接的痕迹,比如寻找最佳拼接缝。使用全局单应变换的对齐结果,实现代码参考图像拼接(六):OpenCV单应变换模型拼接两幅图像:仔...
  • czl389
  • czl389
  • 2017-03-24 00:01
  • 3414

图像拼接(十):OPenCV stitching和stitching_detailed

Stitcher类与detail类OpenCV提供了高级别的函数封装在Stitcher类中,使用很方便,不用考虑太多的细节。低级别函数封装在detail命名空间中,展示了OpenCV算法实现的很多步骤...
  • czl389
  • czl389
  • 2017-03-07 16:25
  • 4744

基于OpenCV的图像拼接

这个程序是本人用于OpenCV项目学习而写的,其中很多代码都是从网上或cook book 中借鉴而来的。由于本人还是菜鸟,程序中难免会出现很多不合理的地方,希望各位高手能赐教或交流。     这个程序...
  • pangwenfeng
  • pangwenfeng
  • 2014-03-11 00:11
  • 2281

图像拼接(六):OpenCV单应变换模型拼接两幅图像

图像拼接首要步骤就是对齐。对齐就要找到两幅图像相对的位置关系。为了描述位置之间的变换关系,研究者引人了诸如平移,仿射,单应等变换模型。每个模型无所谓好坏,各有特定的适用范围。在其次坐标系下,图像位置之...
  • czl389
  • czl389
  • 2017-03-04 14:25
  • 3481
    个人资料
    • 访问:111768次
    • 积分:1837
    • 等级:
    • 排名:千里之外
    • 原创:73篇
    • 转载:0篇
    • 译文:2篇
    • 评论:84条
    About Me
    钱柜娱乐开户
    最新评论