




已阅读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. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025临时工作人员劳动合同
- 2025煤炭购销合同范本模板
- 2025年中国台面堆肥箱行业市场前景预测及投资价值评估分析报告
- 2025届高考物理大一轮复习课件 第十四章 第76课时 实验十七:测量玻璃的折射率 实验十八:用双缝干涉实验测量光的波长
- 2025届高考物理大一轮复习课件 第十一章 第57课时 磁场及其对电流的作用
- 2025超市供货合同范本
- 2025店面租赁合同与经营权质押协议范本
- 2025年土地转让协议合同范本
- 2025关于购买小麦的合同
- DNA-卟啉两亲杂化体的合成、组装及其光动力治疗研究
- 矿山合同转让协议书
- 绝经后无症状子宫内膜增厚诊疗中国专家共识(2024年版)解读课件
- 设备委托服务合同协议
- 2025湖北省武汉市中考语文模拟检测试卷(一模)(含答案)
- 初级保健按摩师(脊柱按摩师)资格理论必背考试题(附答案)
- 2025届新高考历史押题模拟试卷 3套(含答案解析)
- 2025年银行从业资格证考试题库获取试题及答案
- 2025年中考时事政治100题(附答案解析)
- 4-02-02-01 国家职业标准客运车辆驾驶员 (2025年版)
- 2024北京西城区四年级(下)期末语文试题及答案
- 【航线补贴绩效评估实证研究-以华夏航空公司为例19000字(论文)】
评论
0/150
提交评论