技术笔记:openCV特征点识别与findHomography算法过滤

简介: 技术笔记:openCV特征点识别与findHomography算法过滤

一,首先我们对函数先进行分析


findHomography:


计算多个二维点对之间的最优单映射变换矩阵 H(3行x3列) (就是对图片的矫正),使用最小均方误差或者RANSAC方法


函数功能:找到两个平面之间的转换矩阵。


这里涉及到映射变换的知识,


下面介绍下什么是映射变换:


1,如下图所示:


如果平面上点场的点建立了一个一一对应,并且满足:


(1)任何共线三点的象仍是共线三点;


(2)共线四点的交比不变。


则这个一一对应叫做点场的射影变换,简称射影变换


交比:


一维射影变换:


二维的图像是这样的


射影变换也叫做单应(Homography)


图1通过H矩阵变换变成图2,就是这个函数的公式


X′=HX


X′代表图2


其操作过程


在“大”图像(目标图像)上选择4个点和“小”图像(被合并图像)的四角做对应,然后根据这4对对应的点计算两幅图像的单应矩阵。


得到单应矩阵H后,利用函数warpPerspective将H应用到“小”图像上,得到图像M


将图像M合并到目标图像中选择的四个点的位置


Mat cv::findHomography ( InputArray srcPoints,


InputArray dstPoints,


int method = 0,


double ransacReprojThreshold = 3,


OutputArray mask = noArray(),


const int maxIters = 2000,


const double confidence = 0.995


)


参数详解:


srcPoints 源平面中点的坐标矩阵,可以是CV_32FC2类型,也可以是vector


类型


dstPoints 目标平面中点的坐标矩阵,可以是CV_32FC2类型,也可以是vector


类型


method 计算单应矩阵所使用的方法。不同的方法对应不同的参数,具体如下:


0 - 利用所有点的常规方法


RANSAC - RANSAC-基于RANSAC的鲁棒算法


LMEDS - 最小中值鲁棒算法


RHO - PROSAC-基于PROSAC的鲁棒算法


ransacReprojThreshold


将点对视为内点的最大允许重投影错误阈值(仅用于RANSAC和RHO方法)。如果


则点被认为是个外点(即错误匹配点对)。若srcPoints和dstPoints是以像素为单位的,则该参数通常设置在1到10的范围内。


mask


可选输出掩码矩阵,通常由鲁棒算法(RANSAC或LMEDS)设置。 请注意,输入掩码矩阵是不需要设置的。


maxIters RANSAC 算法的最大迭代次数,默认值为2000。


confidence 可信度值,取值范围为0到1.


首先定义两个vector保存对应的4对点


//图片映射矩阵把不同角度的图片矫正


void findHomographyText(){


// Read source image.


Mat src = imread("F:\视觉\opencv\pic\1.png");


// Four corners of the book in source image


vector


pts_src;


pts_src.push_back(Point2f(0, 0));


pts_src.push_back(Point2f(src.cols, 0));


pts_src.push_back(Point2f(src.cols, src.rows));


pts_src.push_back(Point2f(0, src.rows));


// Four corners of the book in destination image.


vector


pts_dst;


pts_dst.push_back(Point2f(0, 0));


pts_dst.push_back(Point2f(src.cols/4, 0));


pts_dst.push_back(Point2f(src.cols/3, src.rows));


pts_dst.push_back(Point2f(0, src.rows/2));


// Calculate Homography


Mat h = findHomography(pts_src, pts_dst);


// Output image


Mat im_out;


// Warp source image to destination based on homography


warpPerspective(src, im_out, h, src.size());


// Display images


imshow("Source Image", src);


imshow("Warped Source Image", im_out);


waitKey(0);


}


结果如下图所示对图像进行拉伸


步骤如下


1,相求H


vector


pts_src;


pts_src.push_back(Point2f(0, 0));


pts_src.push_back(Point2f(src.cols, 0));


pts_src.push_back(Point2f(src.cols, src.rows));


pts_src.push_back(Point2f(0, src.rows));


// Four corners of the book in destination image.


vector


pts_dst;


pts_dst.push_back(Point2f(0, 0));


pts_dst.push_back(Point2f(src.cols/4, 0));


pts_dst.push_back(Point2f(src.cols/3, src.rows));


pts_dst.push_back(Point2f(0, src.rows/2));


// Calculate Homography


Mat h = findHomography(pts_src, pts_dst);


通过H求对应的图像(映射到输出图片上)


warpPerspective(src, im_out, h, src.size());


warpPerspective:通过H求取


im_out输出值介绍完两个主要的函数下面开始对图像进行识别和标记


2,SURF对图像的识别和标记


1,开发思路


(1)使用SIFT或者SURF进行角点检测,获取两个图像的的角点集合


(2)根据两个集合,使用特征点匹配,匹配类似的点 FlannBasedMatcher


(3)过滤特征点对。


(4)通过特征点对,求出H值


(5)画出特征区域


代码实现:


1,使用SIFT或者SURF进行角点检测,获取两个图像的的角点集合


src = imread("F:\视觉\opencv\pic\11.png");//读图片


src3 = imread("F:\视觉\opencv\pic\5.png");//读图片


int minHessian = 400;


cvtColor(src, src, COLOR_BGR2GRAY);


cvtColor(src3, src3, COLOR_BGR2GRAY);


Ptr detector = SIFT::create(minHessian);


vector keypoints_obj;//图片1特征点


vector keypoints_scene;//图片2特征点


Mat descriptor_obj, descriptor_scene;


//找出特征点存到keypoints_obj与keypoints_scene点集中


detector->detectAndCompute(src, Mat(), keypoints_obj, descriptor_obj);


detector->detectAndCompute(src3, Mat(), keypoints_scene, descriptor_scene);


// matching 找到特征集合


FlannBasedMatcher matcher;


vector matches;


matcher.match(descriptor_obj, descriptor_scene, matches);


2,过滤相似度高的图像


// find good matched points


double minDist = 1000;


//代码效果参考:http://www.jhylw.com.cn/383329613.html

double maxDist = 0;

for (int i = 0; i < descriptor_obj.rows; i++) {


double dist = matches【i】.distance;


if (dist > maxDist) {


maxDist = dist;


}


if (dist [span style="color: rgba(0, 0, 0, 1)"> minDist) {


minDist = dist;


}


}


printf("max distance : %f\n", maxDist);


printf("min distance : %f\n", minDist);


vector goodMatches;


//过滤相同的点


for (int i = 0; i < descriptor_obj.rows; i++) {


double dist = matches【i】.distance;//相识度


printf("distance : %f\n", dist);


if (dist < max(3 minDist, 0.2)) {


goodMatches.push_back(matches【i】);


}


}


3,求出H


vector


obj;


vector


objInScene;


for (size_t t = 0; t < goodMatches.size(); t++) {


//把DMatch转成坐标 Point2f


obj.push_back(keypoints_obj【goodMatches【t】.queryIdx】.pt);


objInScene.push_back(keypoints_scene【goodMatches【t】.trainIdx】.pt);


}


//用来求取“射影变换”的H转制矩阵函数 X'=H X ,并使用RANSAC消除一些出错的点


Mat H = findHomography(obj, objInScene, RANSAC);


4,使用H求出映射到大图的点


vector


obj_corners(4);


vector


scene_corners(4);


obj_corners【0】 = Point(0, 0);


obj_corners【1】 = Point(src.cols, 0);


obj_corners【2】 = Point(src.cols, src.rows);


obj_corners【3】 = Point(0, src.rows);


//透视变换(把斜的图片扶正)


cout [ H [ endl;


perspectiveTransform(obj_corners, scene_corners, H);


5,在原图上画线段


?123456789Mat dst; cvtColor(src3, dst, COLOR_GRAY2BGR); line(dst, scene_corners【0】, scene_corners【1】, Scalar(0, 0, 255), 2, 8, 0); line(dst, scene_corners【1】, scene_corners【2】, Scalar(0, 0, 255), 2, 8, 0); line(dst, scene_corners【2】, scene_corners【3】, Scalar(0, 0, 255), 2, 8, 0); line(dst, scene_corners【3】, scene_corners【0】, Scalar(0, 0, 255), 2, 8, 0); imshow("Draw object", dst);


  相似效果


谢谢,如果觉得可以请点个赞!转发请付链接。。。。


原文链接:



// find good matched pointsdouble minDist = 1000;double maxDist = 0;


for (int i = 0; i maxDist) {maxDist = dist;}if (dist < minDist) {minDist = dist;}}printf("max distance : %f\n", maxDist);printf("min distance : %f\n", minDist);


vector goodMatches;//过滤相同的点for (int i = 0; i < descriptor_obj.rows; i++) {double dist = matches【i】.distance;//相识度printf("distance : %f\n", dist);if (dist < max(3 minDist, 0.2)) {goodMatches.push_back(matches【i】);}}

相关文章
|
3月前
|
机器学习/深度学习 传感器 数据采集
【23年新算法】基于鱼鹰算法OOA-Transformer-BiLSTM多特征分类预测附Matlab代码 (多输入单输出)(Matlab代码实现)
【23年新算法】基于鱼鹰算法OOA-Transformer-BiLSTM多特征分类预测附Matlab代码 (多输入单输出)(Matlab代码实现)
260 0
|
3月前
|
运维 监控 算法
基于 Java 滑动窗口算法的局域网内部监控软件流量异常检测技术研究
本文探讨了滑动窗口算法在局域网流量监控中的应用,分析其在实时性、资源控制和多维分析等方面的优势,并提出优化策略,结合Java编程实现高效流量异常检测。
116 0
|
4月前
|
监控 算法 安全
基于 C# 基数树算法的网络屏幕监控敏感词检测技术研究
随着数字化办公和网络交互迅猛发展,网络屏幕监控成为信息安全的关键。基数树(Trie Tree)凭借高效的字符串处理能力,在敏感词检测中表现出色。结合C#语言,可构建高时效、高准确率的敏感词识别模块,提升网络安全防护能力。
116 2
|
6月前
|
机器学习/深度学习 存储 监控
上网管理监控软件的 Go 语言流量特征识别算法实现与优化
本文探讨基于Go语言的流量特征识别算法,用于上网管理监控软件。核心内容涵盖AC自动机算法原理、实现及优化,通过路径压缩、哈希表存储和节点合并策略提升性能。实验表明,优化后算法内存占用降低30%,匹配速度提升20%。在1000Mbps流量下,CPU利用率低于10%,内存占用约50MB,检测准确率达99.8%。未来可进一步优化高速网络处理能力和融合机器学习技术。
179 10
|
6月前
|
监控 算法 JavaScript
基于 JavaScript 图算法的局域网网络访问控制模型构建及局域网禁止上网软件的技术实现路径研究
本文探讨局域网网络访问控制软件的技术框架,将其核心功能映射为图论模型,通过节点与边表示终端设备及访问关系。以JavaScript实现DFS算法,模拟访问权限判断,优化动态策略更新与多层级访问控制。结合流量监控数据,提升网络安全响应能力,为企业自主研发提供理论支持,推动智能化演进,助力数字化管理。
158 4
|
6月前
|
存储 监控 算法
内网监控桌面与 PHP 哈希算法:从数据追踪到行为审计的技术解析
本文探讨了内网监控桌面系统的技术需求与数据结构选型,重点分析了哈希算法在企业内网安全管理中的应用。通过PHP语言实现的SHA-256算法,可有效支持软件准入控制、数据传输审计及操作日志存证等功能。文章还介绍了性能优化策略(如分块哈希计算和并行处理)与安全增强措施(如盐值强化和动态更新),并展望了哈希算法在图像处理、网络流量分析等领域的扩展应用。最终强调了构建完整内网安全闭环的重要性,为企业数字资产保护提供技术支撑。
171 2
|
7月前
|
存储 算法 物联网
解析局域网内控制电脑机制:基于 Go 语言链表算法的隐秘通信技术探究
数字化办公与物联网蓬勃发展的时代背景下,局域网内计算机控制已成为提升工作效率、达成设备协同管理的重要途径。无论是企业远程办公时的设备统一调度,还是智能家居系统中多设备间的联动控制,高效的数据传输与管理机制均构成实现局域网内计算机控制功能的核心要素。本文将深入探究 Go 语言中的链表数据结构,剖析其在局域网内计算机控制过程中,如何达成数据的有序存储与高效传输,并通过完整的 Go 语言代码示例展示其应用流程。
137 0
|
计算机视觉
Opencv学习笔记(三):图像二值化函数cv2.threshold函数详解
这篇文章详细介绍了OpenCV库中的图像二值化函数`cv2.threshold`,包括二值化的概念、常见的阈值类型、函数的参数说明以及通过代码实例展示了如何应用该函数进行图像二值化处理,并展示了运行结果。
3423 0
Opencv学习笔记(三):图像二值化函数cv2.threshold函数详解
|
算法 计算机视觉
opencv图像形态学
图像形态学是一种基于数学形态学的图像处理技术,它主要用于分析和修改图像的形状和结构。
202 4

热门文章

最新文章