surf-1_E3什么意思
是加速版的SIFT。
surf算法 surf算法数据集
surf-1_E3是对DavidLowe在1999年提出的Sift算法的改进,提升了算法的执行效率,为算法在实时计算机视觉系统中应用提供了可能。与surf-1_E3算法一样,surf-1_E3算法的基本路程可以分为三大部分:局部特征点的提取、特征点的描述、特征点的匹配。
基于opencv-算法设计
这个问题基于模式识别做,至于楼上的给出了很详细的图像识别方法。模式识别的过程就是需要对特征的提取,特征筛选,训练和测试。一般来说给出了具体的分类用监督性学习的方法比自动分类器来的好。特征提取基于图像表面的特有特征,我记得opencv里面有一个descriptor的方法函数可以提取图像特征点,但并不完全可行。特征值的选择决定了分类识别的效率。至于surf算法我记得opencv里面应该是有的。楼主有空可以看看模式识别的书,对你会有帮助
图像处理的形态学算法可以用上
OpenCV+Python特征提取算法与图像描述符之SIFT / SURF / ORB
算法效果比较博文
用于表示和量化图像的数字列表,简单理解成将图片转化为一个数字列表表示。特征向量中用来描述图片的各种属性的向量称为特征矢量。
参考
是一种算法和方法,输入1个图像,返回多个特征向量(主要用来处理图像的局部,往往会把多个特征向量组成一个一维的向量)。主要用于图像匹配(视觉检测),匹配图像中的物品。
SIFT论文
原理
opencv官网解释
实质是在不同的尺度空间上查找关键点(特征点),并计算出关键点的方向。SIFT所查找到的关键点是一些十分突出,不会因光照,仿射变换和噪音等因素而变化的点,如角点、边缘点、暗区的亮点及亮区的暗点等。
尺度不变特征转换(Scale-invariant feature transform或SIFT)是一种电脑视觉的算法用来侦测与描述影像中的局部性特征,它在空间尺度中寻找极值点,并提取出其位置、尺度、旋转不变量。
其应用范围包含物体辨识、机器人地图感知与导航、影像缝合、3D模型建立、手势辨识、影像追踪和动作比对。
对现实中物体的描述一定要在一个十分重要的前提下进行,这个前提就是对自然界建模时的尺度。当用一个机器视觉系统分析未知场景时,计算机没有办法预先知道图像中物体的尺度,因此我们需要同时考虑图像在多尺度下的描述,获知感兴趣物体的最佳尺度。图像的尺度空间表达指的是图像的所有尺度下的描述。
KeyPoint数据结构解析
SURF论文
原理
opencv官网解释
SURF是SIFT的加速版,它善于处理具有模糊和旋转的图像,但是不善于处理视角变化和光照变化。在SIFT中使用DoG对LoG进行近似,而在SURF中使用盒子滤波器对LoG进行近似,这样就可以使用积分图像了(计算图像中某个窗口内所有像素和时,计算量的大小与窗口大小无关)。总之,SURF最大的特点在于采用了Haar特征以及积分图像的概念,大大加快了程序的运行效率。
因为专利原因,OpenCV3.3开始不再免费开放SIFT\SURF,需要免费的请使用ORB算法
ORB算法综合了FAST角点检测算法和BRIEFF描述符。
算法原理
opencv官方文档
FAST只是一种特征点检测算法,并不涉及特征点的特征描述。
论文
opencv官方文档
中文版
Brief是Binary Robust Independent Elementary Features的缩写。这个特征描述子是由EPFL的Calonder在ECCV2010上提出的。主要思路就是在特征点附近随机选取若干点对,将这些点对的灰度值的大小,组合成一个二进制串,并将这个二进制串作为该特征点的特征描述子。文章同样提到,在此之前,需要选取合适的gaussian kernel对图像做平滑处理。
1:不具备旋转不变性。
2:对噪声敏感
3:不具备尺度不变性。
ORB论文
OpenCV官方文档
ORB采用了FAST作为特征点检测算子,特征点的主方向是通过矩(moment)计算而来解决了BRIEF不具备旋转不变性的问题。
ORB还做了这样的改进,不再使用pixel-pair,而是使用9×9的patch-pair,也就是说,对比patch的像素值之和,解决了BRIEF对噪声敏感的问题。
关于计算速度:
ORB是sift的100倍,是surf的10倍。
对图片数据、特征分布的一种统计
对数据空间(bin)进行量化
Kmeans
边缘:尺度问题->不同的标准差 捕捉到不同尺度的边缘
斑点 Blob:二阶高斯导数滤波LoG
关键点(keypoint):不同视角图片之间的映射,图片配准、拼接、运动跟踪、物体识别、机器人导航、3D重建
SIFT\SURF
opencv surf算法连线颜色怎么设置一样
/**
* @file SURF_Homography
* @brief SURF detector + descriptor + FLANN Matcher + FindHomography
* @author A. Huaman
*/
#include
#include
#include
#include "opencv2/core/core.hpp"
#include
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/nonfree/features2d.hpp"
#include
#include
using namespace cv;
using namespace std;
#ifdef _DEBUG
#pragma comment (lib, "opencv_calib3d246d.lib")
#pragma comment (lib, "opencv_contrib246d.lib")
#pragma comment (lib,"opencv_imgproc246d.lib")
#pragma comment (lib, "opencv_core246d.lib")
#pragma comment (lib, "opencv_features2d246d.lib")
#pragma comment (lib, "opencv_flann246d.lib")
#pragma comment (lib, "opencv_gpu246d.lib")
#pragma comment (lib, "opencv_highgui246d.lib")
#pragma comment (lib, "opencv_legacy246d.lib")
#pragma comment (lib, "opencv_ml246d.lib")
#pragma comment (lib, "opencv_objdetect246d.lib")
#pragma comment (lib, "opencv_ts246d.lib")
#pragma comment (lib, "opencv_video246d.lib")
#pragma comment (lib, "opencv_nonfree246d.lib")
#else
#pragma comment (lib, "opencv_calib3d246.lib")
#pragma comment (lib, "opencv_contrib246.lib")
#pragma comment (lib, "opencv_imgproc246.lib")
#pragma comment (lib, "opencv_core246.lib")
#pragma comment (lib, "opencv_features2d246.lib")
#pragma comment (lib, "opencv_flann246.lib")
#pragma comment (lib, "opencv_gpu246.lib")
#pragma comment (lib, "opencv_highgui246.lib")
#pragma comment (lib, "opencv_legacy246.lib")
#pragma comment (lib, "opencv_ml246.lib")
#pragma comment (lib, "opencv_objdetect246.lib")
#pragma comment (lib, "opencv_ts246.lib")
#pragma comment (lib, "opencv_video246.lib")
#pragma comment (lib, "opencv_nonfree246.lib")
#endif
int main()
{initModule_nonfree();//初始化模块,使用SIFT或SURF时用到
Ptr
Ptr
Ptr
if( detector.empty() || descriptor_extractor.empty() )
cout<<"fail to create detector!";
//读入图像
Mat img1 = imread("1.jpg");
Mat img2 = imread("2.jpg");
//特征点检测
double t = getTickCount();//当前滴答数
vector
detector->detect( img1, m_LeftKey );//检测img1中的SIFT特征点,存储到m_LeftKey中
detector->detect( img2, m_RightKey );
cout<<"图像1特征点个数:"< cout<<"图像2特征点个数:"< //根据特征点计算特征描述子矩阵,即特征向量矩阵 Mat descriptors1,descriptors2; descriptor_extractor->compute( img1, m_LeftKey, descriptors1 ); descriptor_extractor->compute( img2, m_RightKey, descriptors2 ); t = ((double)getTickCount() - t)/getTickFrequency(); cout<<"SIFT算法用时:"< cout<<"图像1特征描述矩阵大小:"< <<",特征向量个数:"< cout<<"图像2特征描述矩阵大小:"< <<",特征向量个数:"< //画出特征点 Mat img_m_LeftKey,img_m_RightKey; drawKeypoints(img1,m_LeftKey,img_m_LeftKey,Scalar::all(-1),0); drawKeypoints(img2,m_RightKey,img_m_RightKey,Scalar::all(-1),0); //imshow("Src1",img_m_LeftKey); //imshow("Src2",img_m_RightKey); //特征匹配 vector descriptor_matcher->match( descriptors1, descriptors2, matches );//匹配两个图像的特征矩阵 cout<<"Match个数:"< //计算匹配结果中距离的最大和最小值 //距离是指两个特征向量间的欧式距离,表明两个特征的差异,值越小表明两个特征点越接近 double max_dist = 0; double min_dist = 100; for(int i=0; i {double dist = matches[i].distance; if(dist < min_dist) min_dist = dist; if(dist > max_dist) max_dist = dist; }cout<<"最大距离:"< cout<<"最小距离:"< //筛选出较好的匹配点 vector for(int i=0; i {if(matches[i].distance < 0.2 * max_dist) {goodMatches.push_back(matches[i]); }} cout<<"goodMatch个数:"< //画出匹配结果 Mat img_matches; //红色连接的是匹配的特征点对,绿色是未匹配的特征点 drawMatches(img1,m_LeftKey,img2,m_RightKey,goodMatches,img_matches, Scalar::all(-1)/*CV_RGB(255,0,0)*/,CV_RGB(0,255,0),Mat(),2); imshow("MatchSIFT",img_matches); IplImage result=img_matches; waitKey(0); //RANSAC匹配过程 vector // 分配空间 int ptCount = (int)m_Matches.size(); Mat p1(ptCount, 2, CV_32F); Mat p2(ptCount, 2, CV_32F); // 把Keypoint转换为Mat Point2f pt; for (int i=0; i {pt = m_LeftKey[m_Matches[i].queryIdx].pt; p1.at p1.at pt = m_RightKey[m_Matches[i].trainIdx].pt; p2.at p2.at }// 用RANSAC方法计算F Mat m_Fundamental; vector findFundamentalMat(p1, p2, m_RANSACStatus, FM_RANSAC); // 计算野点个数 int OutlinerCount = 0; for (int i=0; i {if (m_RANSACStatus[i] == 0) // 状态为0表示野点 {OutlinerCount++; }} int InlinerCount = ptCount - OutlinerCount; // 计算内点 cout<<"内点数为:"< // 这三个变量用于保存内点和匹配关系 vector vector vector m_InlierMatches.resize(InlinerCount); m_LeftInlier.resize(InlinerCount); m_RightInlier.resize(InlinerCount); InlinerCount=0; float inlier_minRx=img1.cols; //用于存储内点中右图最小横坐标,以便后续融合 for (int i=0; i {if (m_RANSACStatus[i] != 0) {m_LeftInlier[InlinerCount].x = p1.at m_LeftInlier[InlinerCount].y = p1.at m_RightInlier[InlinerCount].x = p2.at m_RightInlier[InlinerCount].y = p2.at m_InlierMatches[InlinerCount].queryIdx = InlinerCount; m_InlierMatches[InlinerCount].trainIdx = InlinerCount; if(m_RightInlier[InlinerCount].x InlinerCount++; }} // 把内点转换为drawMatches可以使用的格式 vector vector KeyPoint::convert(m_LeftInlier, key1); KeyPoint::convert(m_RightInlier, key2); // 显示计算F过后的内点匹配 Mat OutImage; drawMatches(img1, key1, img2, key2, m_InlierMatches, OutImage); cvNamedWindow( "Match features", 1); cvShowImage("Match features", &IplImage(OutImage)); waitKey(0); cvDestroyAllWindows(); //矩阵H用以存储RANSAC得到的单应矩阵 Mat H = findHomography( m_LeftInlier, m_RightInlier, RANSAC ); //存储左图四角,及其变换到右图位置 std::vector obj_corners[0] = Point(0,0); obj_corners[1] = Point( img1.cols, 0 ); obj_corners[2] = Point( img1.cols, img1.rows ); obj_corners[3] = Point( 0, img1.rows ); std::vector perspectiveTransform( obj_corners, scene_corners, H); //画出变换后图像位置 Point2f offset( (float)img1.cols, 0); line( OutImage, scene_corners[0]+offset, scene_corners[1]+offset, Scalar( 0, 255, 0), 4 ); line( OutImage, scene_corners[1]+offset, scene_corners[2]+offset, Scalar( 0, 255, 0), 4 ); line( OutImage, scene_corners[2]+offset, scene_corners[3]+offset, Scalar( 0, 255, 0), 4 ); line( OutImage, scene_corners[3]+offset, scene_corners[0]+offset, Scalar( 0, 255, 0), 4 ); imshow( "Good Matches & Object detection", OutImage ); waitKey(0); imwrite("warp_position.jpg",OutImage); int drift = scene_corners[1].x; //储存偏移量 版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至836084111@qq.com 举报,一经查实,本站将立刻删除。