opencv3/C++ 平面对象识别&透视变换方式
findHomography()
函数findHomography()找到两个平面之间的透视变换H。
参数说明:
MatfindHomography( InputArraysrcPoints,//原始平面中点的坐标 InputArraydstPoints,//目标平面中点的坐标 intmethod=0,//用于计算单应性矩阵的方法 doubleransacReprojThreshold=3, OutputArraymask=noArray(),//通过鲁棒法(RANSAC或LMEDS)设置的可选输出掩码 constintmaxIters=2000,//RANSAC迭代的最大次数,2000是它可以达到的最大值 constdoubleconfidence=0.995//置信度 );
用于计算单应性矩阵的方法有:
0:使用所有点的常规方法;
RANSAC:基于RANSAC的鲁棒法;
LMEDS:最小中值鲁棒法;
RHO:基于PROSAC的鲁棒法;
被最小化。如果参数方法被设置为默认值0,则函数使用所有的点对以简单的最小二乘方案计算初始单应性估计。
然而,如果不是所有的点对
不管方法是否鲁棒,计算的单应性矩阵都用Levenberg-Marquardt方法进一步细化(仅在鲁棒法的情况下使用inlier)以更多地减少再投影误差。
RANSAC和RHO方法几乎可以处理任何异常值的比率,但需要一个阈值来区分异常值和异常值。LMeDS方法不需要任何阈值,但只有在超过50%的内部值时才能正常工作。最后,如果没有异常值且噪声相当小,则使用默认方法(method=0)。
perspectiveTransform()
函数perspectiveTransform()执行矢量的透视矩阵变换。
参数说明:
voidperspectiveTransform( InputArraysrc,//输入双通道或三通道浮点数组/图像 OutputArraydst,//输出与src相同大小和类型的数组/图像 InputArraym//3x3或4x4浮点转换矩阵 );
平面对象识别:
#include#include usingnamespacecv; usingnamespacecv::xfeatures2d; intmain() { Matsrc1,src2; src1=imread("E:/image/image/card.jpg"); src2=imread("E:/image/image/cards.jpg"); if(src1.empty()||src2.empty()) { printf("canontloadimages....\n"); return-1; } imshow("image1",src1); imshow("image2",src2); intminHessian=400; //选择SURF特征 Ptr detector=SURF::create(minHessian); std::vector keypoints1; std::vector keypoints2; Matdescriptor1,descriptor2; //检测关键点并计算描述符 detector->detectAndCompute(src1,Mat(),keypoints1,descriptor1); detector->detectAndCompute(src2,Mat(),keypoints2,descriptor2); //基于Flann的描述符匹配器 FlannBasedMatchermatcher; std::vector matches; //从查询集中查找每个描述符的最佳匹配 matcher.match(descriptor1,descriptor2,matches); doubleminDist=1000; doublemaxDist=0; for(inti=0;i maxDist) { maxDist=dist; } if(dist goodMatches; for(inti=0;i (),DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS); std::vector point1,point2; for(inti=0;i cornerPoints1(4); std::vector cornerPoints2(4); cornerPoints1[0]=Point(0,0); cornerPoints1[1]=Point(src1.cols,0); cornerPoints1[2]=Point(src1.cols,src1.rows); cornerPoints1[3]=Point(0,src1.rows); perspectiveTransform(cornerPoints1,cornerPoints2,H); //绘制出变换后的目标轮廓,由于左侧为图像src2故坐标点整体右移src1.cols line(matchesImg,cornerPoints2[0]+Point2f(src1.cols,0),cornerPoints2[1]+Point2f(src1.cols,0),Scalar(0,255,255),4,8,0); line(matchesImg,cornerPoints2[1]+Point2f(src1.cols,0),cornerPoints2[2]+Point2f(src1.cols,0),Scalar(0,255,255),4,8,0); line(matchesImg,cornerPoints2[2]+Point2f(src1.cols,0),cornerPoints2[3]+Point2f(src1.cols,0),Scalar(0,255,255),4,8,0); line(matchesImg,cornerPoints2[3]+Point2f(src1.cols,0),cornerPoints2[0]+Point2f(src1.cols,0),Scalar(0,255,255),4,8,0); //在原图上绘制出变换后的目标轮廓 line(src2,cornerPoints2[0],cornerPoints2[1],Scalar(0,255,255),4,8,0); line(src2,cornerPoints2[1],cornerPoints2[2],Scalar(0,255,255),4,8,0); line(src2,cornerPoints2[2],cornerPoints2[3],Scalar(0,255,255),4,8,0); line(src2,cornerPoints2[3],cornerPoints2[0],Scalar(0,255,255),4,8,0); imshow("output",matchesImg); imshow("output2",src2); waitKey(); return0; }
以上这篇opencv3/C++平面对象识别&透视变换方式就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。