已阅读5页,还剩1页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
OpenMP并行编程应用加速OpenCV图像拼接算法OpenMP是一种应用于多处理器程序设计的并行编程处理方案,它提供了对于并行编程的高层抽象,只需要在程序中添加简单的指令,就可以编写高效的并行程序,而不用关心具体的并行实现细节,降低了并行编程的难度和复杂度。也正因为OpenMP的简单易用性,它并不适合于需要复杂的线程间同步和互斥的场合。OpenCV中使用Sift或者Surf特征进行图像拼接的算法,需要分别对两幅或多幅图像进行特征提取和特征描述,之后再进行图像特征点的配对,图像变换等操作。不同图像的特征提取和描述的工作是整个过程中最耗费时间的,也是独立 运行的,可以使用OpenMP进行加速。以下是不使用OpenMP加速的Sift图像拼接原程序:cpp view plain copy print?在CODE上查看代码片派生到我的代码片#include highgui/highgui.hpp #include opencv2/nonfree/nonfree.hpp #include opencv2/legacy/legacy.hpp #include omp.h using namespace cv; /计算原始图像点位在经过矩阵变换后在目标图像上对应位置 Point2f getTransformPoint(const Point2f originalPoint, const Mat &transformMaxtri); int main(int argc, char *argv) float startTime = omp_get_wtime(); Mat image01 = imread(Test01.jpg); Mat image02 = imread(Test02.jpg); imshow(拼接图像1, image01); imshow(拼接图像2, image02); /灰度图转换 Mat image1, image2; cvtColor(image01, image1, CV_RGB2GRAY); cvtColor(image02, image2, CV_RGB2GRAY); /提取特征点 SiftFeatureDetector siftDetector(800); / 海塞矩阵阈值 vector keyPoint1, keyPoint2; siftDetector.detect(image1, keyPoint1); siftDetector.detect(image2, keyPoint2); /特征点描述,为下边的特征点匹配做准备 SiftDescriptorExtractor siftDescriptor; Mat imageDesc1, imageDesc2; siftDpute(image1, keyPoint1, imageDesc1); siftDpute(image2, keyPoint2, imageDesc2); float endTime = omp_get_wtime(); std:cout 不使用OpenMP加速消耗时间: endTime - startTime std:endl; /获得匹配特征点,并提取最优配对 FlannBasedMatcher matcher; vector matchePoints; matcher.match(imageDesc1, imageDesc2, matchePoints, Mat(); sort(matchePoints.begin(), matchePoints.end(); /特征点排序 /获取排在前N个的最优匹配特征点 vector imagePoints1, imagePoints2; for (int i = 0; i 10; i+) imagePoints1.push_back(keyPoint1matchePointsi.queryIdx.pt); imagePoints2.push_back(keyPoint2matchePointsi.trainIdx.pt); /获取图像1到图像2的投影映射矩阵,尺寸为3*3 Mat homo = findHomography(imagePoints1, imagePoints2, CV_RANSAC); Mat adjustMat = (Mat_(3, 3) 1.0, 0, image01.cols, 0, 1.0, 0, 0, 0, 1.0); Mat adjustHomo = adjustMat*homo; /获取最强配对点在原始图像和矩阵变换后图像上的对应位置,用于图像拼接点的定位 Point2f originalLinkPoint, targetLinkPoint, basedImagePoint; originalLinkPoint = keyPoint1matchePoints0.queryIdx.pt; targetLinkPoint = getTransformPoint(originalLinkPoint, adjustHomo); basedImagePoint = keyPoint2matchePoints0.trainIdx.pt; /图像配准 Mat imageTransform1; warpPerspective(image01, imageTransform1, adjustMat*homo, Size(image02.cols + image01.cols + 110, image02.rows); /在最强匹配点左侧的重叠区域进行累加,是衔接稳定过渡,消除突变 Mat image1Overlap, image2Overlap; /图1和图2的重叠部分 image1Overlap = imageTransform1(Rect(Point(targetLinkPoint.x - basedImagePoint.x, 0), Point(targetLinkPoint.x, image02.rows); image2Overlap = image02(Rect(0, 0, image1Overlap.cols, image1Overlap.rows); Mat image1ROICopy = image1Overlap.clone(); /复制一份图1的重叠部分 for (int i = 0; i image1Overlap.rows; i+) for (int j = 0; j image1Overlap.cols; j+) double weight; weight = (double)j / image1Overlap.cols; /随距离改变而改变的叠加系数 image1Overlap.at(i, j)0 = (1 - weight)*image1ROICopy.at(i, j)0 + weight*image2Overlap.at(i, j)0; image1Overlap.at(i, j)1 = (1 - weight)*image1ROICopy.at(i, j)1 + weight*image2Overlap.at(i, j)1; image1Overlap.at(i, j)2 = (1 - weight)*image1ROICopy.at(i, j)2 + weight*image2Overlap.at(i, j)2; Mat ROIMat = image02(Rect(Point(image1Overlap.cols, 0), Point(image02.cols, image02.rows); /图2中不重合的部分 ROIMat.copyTo(Mat(imageTransform1, Rect(targetLinkPoint.x, 0, ROIMat.cols, image02.rows); /不重合的部分直接衔接上去 namedWindow(拼接结果, 0); imshow(拼接结果, imageTransform1); imwrite(D:拼接结果.jpg, imageTransform1); waitKey(); return 0; /计算原始图像点位在经过矩阵变换后在目标图像上对应位置 Point2f getTransformPoint(const Point2f originalPoint, const Mat &transformMaxtri) Mat originelP, targetP; originelP = (Mat_(3, 1) originalPoint.x, originalPoint.y, 1.0); targetP = transformMaxtri*originelP; float x = targetP.at(0, 0) / targetP.at(2, 0); float y = targetP.at(1, 0) / targetP.at(2, 0); return Point2f(x, y); 之后在程序中加入OpenMP的头文件“omp.h”就可以了:cpp view plain copy print?在CODE上查看代码片派生到我的代码片#include highgui/highgui.hpp #include opencv2/nonfree/nonfree.hpp #include opencv2/legacy/legacy.hpp #include omp.h using namespace cv; /计算原始图像点位在经过矩阵变换后在目标图像上对应位置 Point2f getTransformPoint(const Point2f originalPoint, const Mat &transformMaxtri); int main(int argc, char *argv) float startTime = omp_get_wtime(); Mat image01, image02; Mat image1, image2; vector keyPoint1, keyPoint2; Mat imageDesc1, imageDesc2; SiftFeatureDetector siftDetector(800); / 海塞矩阵阈值 SiftDescriptorEactor siftDescriptor; /使用OpenMP的sections制导指令开启多线程 #pragma omp parallel sections #pragma omp section image01 = imread(Test01.jpg); imshow(拼接图像1, image01); /灰度图转换 cvtColor(image01, image1, CV_RGB2GRAY); /提取特征点 siftDetector.detect(image1, keyPoint1); /特征点描述,为下边的特征点匹配做准备 siftDpute(image1, keyPoint1, imageDesc1); #pragma omp section image02 = imread(Test02.jpg); imshow(拼接图像2, image02); cvtColor(image02, image2, CV_RGB2GRAY); siftDetector.detect(image2, keyPoint2); siftDpute(image2, keyPoint2, imageDesc2); float endTime = omp_get_wtime(); std:cout 使用OpenMP加速消耗时间: endTime - startTime std:endl; /获得匹配特征点,并提取最优配对 FlannBasedMatcher matcher; vector matchePoints; matcher.match(imageDesc1, imageDesc2, matchePoints, Mat(); sort(matchePoints.begin(), matchePoints.end(); /特征点排序 /获取排在前N个的最优匹配特征点 vector imagePoints1, imagePoints2; for (int i = 0; i 10; i+) imagePoints1.push_back(keyPoint1matchePointsi.queryIdx.pt); imagePoints2.push_back(keyPoint2matchePointsi.trainIdx.pt); /获取图像1到图像2的投影映射矩阵,尺寸为3*3 Mat homo = findHomography(imagePoints1, imagePoints2, CV_RANSAC); Mat adjustMat = (Mat_(3, 3) 1.0, 0, image01.cols, 0, 1.0, 0, 0, 0, 1.0); Mat adjustHomo = adjustMat*homo; /获取最强配对点在原始图像和矩阵变换后图像上的对应位置,用于图像拼接点的定位 Point2f originalLinkPoint, targetLinkPoint, basedImagePoint; originalLinkPoint = keyPoint1matchePoints0.queryIdx.pt; targetLinkPoint = getTransformPoint(originalLinkPoint, adjustHomo); basedImagePoint = keyPoint2matchePoints0.trainIdx.pt; /图像配准 Mat imageTransform1; warpPerspective(image01, imageTransform1, adjustMat*homo, Size(image02.cols + image01.cols + 110, image02.rows); /在最强匹配点左侧的重叠区域进行累加,是衔接稳定过渡,消除突变 Mat image1Overlap, image2Overlap; /图1和图2的重叠部分 image1Overlap = imageTransform1(Rect(Point(targetLinkPoint.x - basedImagePoint.x, 0), Point(targetLinkPoint.x, image02.rows); image2Overlap = image02(Rect(0, 0, image1Overlap.cols, image1Overlap.rows); Mat image1ROICopy = image1Overlap.clone(); /复制一份图1的重叠部分 for (int i = 0; i image1Overlap.rows; i+) for (int j = 0; j image1Overlap.cols; j+) double weight; weight = (double)j / image1Overlap.cols; /随距离改变而改变的叠加系数 image1Overlap.at(i, j)0 = (1 - weight)*image1ROICopy.at(i, j)0 + weight*image2Overlap.at(i, j)0; image1Overlap.at(i, j)1 = (1 - weight)*image1ROICopy.at(i, j)1 + weight*image2Overlap.at(i, j)1; image1Overlap.at(i, j)2 = (1 - weight)*image1ROICopy.at(i, j)2 + weight*image2Overlap.at(i, j)2; Mat ROIMat = image02(Rect(Point(image1Overlap.cols, 0), Point(image02.cols,
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 立式加工中心高精度铣削技术创新总结报告
- 建筑废弃物运输车辆电子化密闭化改造项目技术创新总结报告
- 心肺复苏试题及答案完整版
- CBD项目有砟轨道施工方案
- 2026年人教版新八年级道法上册复习 专题08 践行中华传统美德
- 2026年皮下注射培训试题及答案
- 2026年秋人教版新八年级英语上册 专题01 动词时态(暑假复习讲义)
- 园林绿化企业车工检修维修安全操作规程
- 非煤矿山企业安全教育培训制度
- 金属粉尘企业主要负责人检修维修安全操作规程
- DB32T 3939-2020公路钢结构桥梁质量检验评定规程
- 中国艾滋病诊疗指南(2024版)解读课件
- 2021辅助生殖技术中异常子宫内膜诊疗的中国专家共识(全文)
- 2025陕西延长石油(集团)有限责任公司科技人才招聘116人笔试备考试题及答案解析
- 快递物流运输服务规范
- 人防工程(防护密闭套管∕管道)隐蔽检查验收记录
- 中华人民共和国标准设计施工总承包招标文件(2012年版)
- 08SG115-1 钢结构施工图参数表示方法制图规则和构造详图
- 港口码头安全生产目标管理制度
- 河南中烟工业有限责任公司考试题库2024
- 007 预制舱吊装安装方案
评论
0/150
提交评论