图像拼接(九):双摄像头实时视频拼接(单应变换模型)

By | 03月07日
Advertisement

单应变换相比平移变换,具有更广泛的场景适应性,但同时稳定性会有一定程度下降。

设计到的技术细节有:

  • 特征检测与描述
  • 特征匹配与单应矩阵估计
  • opencv采集视频
  • 渐入渐出图像融合

这个解决方案的硬件条件包括:有两个USB接口的计算机,两个合理放置的USB摄像头。

合理放置是指:两个摄像头分隔一定夹角,相机中心相距接近,所拍摄场景有足够的重叠部分。以上保证了单应变换的可用性。

代码实现:

#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
# include "opencv2/features2d/features2d.hpp"
#include"opencv2/nonfree/nonfree.hpp"
#include"opencv2/calib3d/calib3d.hpp"
#include<iostream>

using namespace cv;
using namespace std;

int main()
{
    VideoCapture cap1(0);
    VideoCapture cap2(1);

    double rate = 60;
    int delay = 1000 / rate;
    bool stop(false);
    Mat img1;
    Mat img2;
    Mat result;
    int d = 200;//渐入渐出融合宽度
    Mat homography;
    int k = 0;

    namedWindow("cam1", CV_WINDOW_AUTOSIZE);
    namedWindow("cam2", CV_WINDOW_AUTOSIZE);
    namedWindow("stitch", CV_WINDOW_AUTOSIZE);

    if (cap1.isOpened() && cap2.isOpened())
    {
        cout << "*** ***" << endl;
        cout << "摄像头已启动!" << endl;
    }
    else
    {
        cout << "*** ***" << endl;
        cout << "警告:请检查摄像头是否安装好!" << endl;
        cout << "程序结束!" << endl << "*** ***" << endl;
        return -1;
    }

    cap1.set(CV_CAP_PROP_FOCUS, 0);
    cap2.set(CV_CAP_PROP_FOCUS, 0);

    while (!stop)
    {
        if (cap1.read(img1) && cap2.read(img2))
        {
            imshow("cam1", img1);
            imshow("cam2", img2);

            //彩色帧转灰度
            //cvtColor(img1, img1, CV_RGB2GRAY);
            //cvtColor(img2, img2, CV_RGB2GRAY);

            //计算单应矩阵
            if (k < 1 || waitKey(delay) == 13)
            {
                cout << "正在匹配..." << endl;
                ////////////////////////////////
                vector<KeyPoint> keypoints1, keypoints2;
                //构造检测器
                //Ptr<FeatureDetector> detector = new ORB(120);
                Ptr<FeatureDetector> detector = new SIFT(80);
                detector->detect(img1, keypoints1);
                detector->detect(img2, keypoints2);
                //构造描述子提取器
                Ptr<DescriptorExtractor> descriptor = detector;
                //提取描述子
                Mat descriptors1, descriptors2;

                descriptor->compute(img1, keypoints1, descriptors1);
                descriptor->compute(img2, keypoints2, descriptors2);
                //构造匹配器
                BFMatcher matcher(NORM_L2, true);
                //匹配描述子
                vector<DMatch> matches;
                matcher.match(descriptors1, descriptors2, matches);

                vector<Point2f> selPoints1, selPoints2;
                vector<int> pointIndexes1, pointIndexes2;
                for (vector<DMatch>::const_iterator it = matches.begin(); it != matches.end(); ++it)
                {
                    selPoints1.push_back(keypoints1.at(it->queryIdx).pt);
                    selPoints2.push_back(keypoints2.at(it->trainIdx).pt);
                }

                vector<uchar> inliers(selPoints1.size(), 0);
                homography = findHomography(selPoints1, selPoints2, inliers, CV_FM_RANSAC, 1.0);

                //根据RANSAC重新筛选匹配
                vector<DMatch> outMatches;
                vector<uchar>::const_iterator itIn = inliers.begin();
                vector<DMatch>::const_iterator itM = matches.begin();
                for (; itIn != inliers.end(); ++itIn, ++itM)
                {
                    if (*itIn)
                    {
                        outMatches.push_back(*itM);
                    }

                }
                k++;

                //画出匹配结果
                //Mat matchImage;
                //drawMatches(img1, keypoints1, img2, keypoints2, outMatches, matchImage, 255, 255);
                //imshow("match", matchImage);
                ///////////////////////////////////////////////////////////////////////

            }
            //拼接
            double t = getTickCount();
            warpPerspective(img1, result, homography, Size(2 * img1.cols-d, img1.rows));//Size设置结果图像宽度,宽度裁去一部分,d可调

            Mat half(result, Rect(0, 0, img2.cols - d, img2.rows));
            img2(Range::all(), Range(0, img2.cols - d)).copyTo(half);
            for (int i = 0; i < d; i++)
            {
                result.col(img2.cols - d + i) = (d - i) / (float)d*img2.col(img2.cols - d + i) + i / (float)d*result.col(img2.cols - d + i);
            }

            imshow("stitch", result);
            t = ((double)getTickCount() - t) / getTickFrequency();
            //cout << t << endl;

        }
        else
        {
            cout << "----------------------" << endl;
            cout << "waitting..." << endl;
        }

        if (waitKey(1) == 27)
        {
            stop = true;
            cout << "程序结束!" << endl;
            cout << "*** ***" << endl;
        }
    }
    return 0;
}

实验效果:

图像拼接(九):双摄像头实时视频拼接(单应变换模型)

上述视频是用录屏软件录制的,分辨率会有下降。实际测试中,直接观察显示良好。两幅输入的源图像均为640*480分辨率,能够做到实时的实现。在我的具有i3处理器配置的笔记本上运行,拼接图像显示间隔为0.10″~0.12″。

Similar Posts:

  • 双摄像头三维重建

    双摄像头三维重建报告 写在前面:文章中公式不全的或其他有错误的的地方还请大家给予意见更改,转载请注明出处,版权所有,翻版必究! 一.摄像机成像模型 1.1 针孔摄像机模型 在此模型中,光线是从很远的物体发射过来,通过一个很小的针孔点(或摄像机镜头),投影到成像表面,其结果是在投影平面图像被聚焦. 如图所示,AO为物距,CO为焦距f,另X为物体长度,x为图像长度,则由三角形相似可得: 1.2改进后的成像模型 此模型使成像为正像,实际上是把投影屏幕放到针孔(摄像头)前面,方便分析,如下: 空间点由通

  • iPhone7为什么用双摄像头 iPhone7双摄像头好处详细说明

    iphone7双摄像头有什么用?随着智能手机的兴起,人们对手机的要求也变得越来越高,经历了"核"战.屏幕大战,各大厂商在手机市场中的较量终于进入到了用户体验的较量环节,而在系统优化外,拍照水平的较量渐渐变为了重头戏,于是越来越多的厂商加入到了PK摄像头的小战场中,可谓是使出了浑身解数,而双摄像头这一名称,也随之诞生了.下文带来iphone7双摄像头好处介绍,一起和本站小编来了解下吧! iphone7白色版是什么样子的 苹果iphone7白色版真机图赏 面对着众多关于双摄像头的宣传口号以

  • 华为P9真机高清图赏 1200万双摄像头逼格爆表!

    刚刚,华为正式正式发布了新一代旗舰机P9,包括标准版P9.高配版P9 Plus两个版本.这是他们携手徕卡后,双方共同打造的一款拍照强机,其最大的卖点莫过于1200万双摄像头. P9.P9 Plus采用金属加玻璃一体化机身,极简主义曲线,1.7毫米极窄边框,机身厚度仅仅6.95毫米.6.98毫米. 外观色调提供陶瓷白.琥珀金.玫瑰金.泰坦灰.神秘银等多种风格,其中陶瓷白采用5层镀层工艺,让金属手机表面呈现出陶瓷般质感和晶莹光泽,琥珀金则采用雕刻纹理工艺,让金属表面呈现的玉石质感兼具温润的手感. P

  • 传二代iPad新增双摄像头等五大功能

    疑似iPad 2外壳 疑似iPad 2外壳 苹果第二代iPad将在明年第一季度问世,业界盛传将会新增双摄像头.视频电话等五大功能.组装仍交给鸿海,零组件供应新增大立光.玉晶光.全新.宏捷科与健鼎等公司. 苹果对相关传闻没有正面回应.第一代iPad零组件供货商则透露,“目前尚未接到苹果要为二代iPad备料的消息”,由于一.二代产品大同小异,供货商仅需花很少的时间微调,就能供货.以触控面板为例,调整产品线的时间约在二周内. 业内人士表示,因为零组件调整期短,苹果为求保密,可能会到“最后一刻”才启动零

  • 基于改进SURF算法的实时视频拼接

    Journal of Image and Signal Processing Vol.04 No.04(2015), Article ID:16229,9 pages 10.12677/JISP.2015.44015 Real-Time Video Stitching Based on Improved SURF Zhi'ang Chen, Xiaogang Xu, Guanlei Xu ●Abstract ●Full-Text PDF ●Full-Text HTML ●Linked Refer

  • OpenCV仿射变换+投射变换+单应性矩阵

    本来想用单应性求解小规模运动的物体的位移,但是后来发现即使是很微小的位移也会带来超级大的误差甚至错误求解,看起来这个方法各种行不通,还是要匹配知道深度了以后才能从三维仿射变换来入手了,纠结~ estimateRigidTransform():计算多个二维点对或者图像之间的最优仿射变换矩阵 (2行x3列),H可以是部分自由度,比如各向一致的切变. getAffineTransform():计算3个二维点对之间的仿射变换矩阵H(2行x3列),自由度为6. warpAffine():对输入图像进行仿射

  • OpenCV双摄像头摄像头定标与立体匹配遇到的问题

    进过我的不懈努力,OpenCV双摄像头摄像头定标与立体匹配这个程序算是完成了,下面介绍下过程中遇到的问题. 1.OpenCV棋盘格的定标问题.奇了怪了,每次重新定标,结果都是差异很大,网上查资料,说是MatLab标定箱效果比较好,这是下载地址:http://www.vision.caltech.edu/bouguetj/calib_doc/,使用方法参见此帖子;http://blog.lehu.shu.edu.cn/byman/A263366.html.得到的结果保存为xml,参见我的帖子:ht

  • 别具特色的双摄像头 中兴 AXON 天机拍摄评测

    中兴 AXON 天机使用了别具特色的双摄像头设计,主摄像头为 IMX214 F/1.8,1300 万像素摄像头,上面主要负责景深检测的是另一家摄像头元件大厂 OV 家的摄像头,AXON 天机的两个摄像头的拍摄效果如何呢?我们一起来看看. 相机应用 AXON 天机的拍摄界面往右滑就是进入到背景虚化模式最大可以模拟 1.0 的光圈,最小为 F8.0,这个背景虚化可以模拟光圈大小突出景深虚化效果.左滑进入更多拍摄模式,分别有全景.多重曝光.手动.运动.慢动作和间隔拍摄(延时拍摄).在自动拍摄模式下中央

  • iPhone Pro五个配色谍照渲染图曝光:提供双摄像头

    近日,中国联通香港分公司送出了一张有意思的海报,其暗示了即将推出的iPhone 7将有新配色,同时还会提供双摄像头.下面我们一起来看看想起吧! 现在,有网友送出了iPhone 7五个配色的谍照渲染图,它们分别是玫瑰金.土豪金.灰色.深空灰已经蓝色,从效果图看,后两者的背部最和谐. 至于之前传闻的黑色,应该就是图中的深空会,至于有多黑,还要看实物的色彩表现. 此外,送出渲染图的消息人士还强调,双摄像头版本的iPhone 7 Plus真是名称将被冠以iPhone Pro,这会是苹果的全新产品线,外形

  • 华为P9真机白色版双摄像头曝光 3月9日发布起售价2888元起

    3月2日消息,近日华为P9新旗舰不断曝光,看来离发布不远了.现在国外网友放出了该机的真机图,从图片来看,华为P9的确采用了后置双摄像头设计. 网友给出的图片是白色版华为P9,从图片来看,华为P9提供了两颗后置摄像头,并配以双色温闪光灯,同时还支持激光对焦功能. 该机指纹识别功能依然位于机身背部,背部采用三段式设计,同时采用金属材质的边框和背壳. 除此之外,华为P9还取消了底部对称式双扬声器设计,而是将左侧替换成了耳机孔,同时该机的接口为USB Type-C接口,据悉该机还支持红外功能. 外媒称华

Tags: