图像拼接(九):双摄像头实时视频拼接(单应变换模型)
来源:互联网 发布:淘宝手机市场 编辑:程序博客网 时间:2024/05/18 01:58
单应变换相比平移变换,具有更广泛的场景适应性,但同时稳定性会有一定程度下降。
设计到的技术细节有:
- 特征检测与描述
- 特征匹配与单应矩阵估计
- 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″。
0 0
- 图像拼接(九):双摄像头实时视频拼接(单应变换模型)
- 图像拼接(六):OpenCV单应变换模型拼接两幅图像
- 图像拼接(七):OpenCV单应变换模型拼接多幅图像
- 图像拼接(四):双摄像头实时视频拼接(平移模型)
- 图像拼接(五):双摄像头实时视频拼接(平移模型+多线程)
- 图像拼接(十一):双摄像头实时拼接+stitching_detailed
- 图像(视频)拼接(一)
- 全景视频拼接(二):双摄像头获取视频
- 图像拼接(三):OpenCV同时打开两个摄像头捕获视频
- 基于opencv的图像拼接(三): 基于stitch类的实时图像拼接
- 全景视频拼接(四):循环将两幅图像拼接为全景图片
- 图像拼接(类stitcher 用于图像拼接)
- OpenCV18(图像拼接stitcher_detail)
- opencv图像拼接(粗暴)
- OpenCV18(图像拼接stitcher_detail)
- OpenCV编程->四路摄像头拼接实时显示
- 全景图像&拼接(一)关于全景拼接论文推荐
- opencv调用电脑摄像头+视频拼接
- android中延迟的问题
- 使用MongoDB和JSP实现一个简单的购物车系统
- 【3.7 女生节】
- docker 相关操作
- [LPE]Windows Local Privilege Escalation MS16-135
- 图像拼接(九):双摄像头实时视频拼接(单应变换模型)
- Asp.Net 常用工具类之加密——非对称加密RSA算法
- repo&git&gerrit联系和使用
- 浅谈二路归并排序
- Android EventBus实战
- 如何实现大数据价值最大化?且听这位委员的建议
- 利用Blob, a.download, URL.createObjectURL模拟下载文件
- Dmaven.multiModuleProjectDirectory system propery is not set.
- oracle函数命令