1、Keypoint类中有pt——坐标,size——半径,angle——角度,octave——提取时所在金字塔层,response——是关键点的响应程度,class_id物体识别用。
https://blog.csdn.net/suntingsheng123/article/details/79218441
#define ORB_PATCH_SIZE 35
Ptr<ORB> orb = ORB::create(ORB_N_FEATURE);
orb->setPatchSize(ORB_PATCH_SIZE);
std::vector<KeyPoint> keypoints1;
cout<<keypoints1[0].size<<endl;
当定义orb->setPatchSize(ORB_PATCH_SIZE)时,如果keypoints1[0]在最底层,即第0层,keypoints1[0].size为ORB_PATCH_SIZE,即35。在第1层,keypoints1[0].size为42,层数越高,size值越高。
response的解释:
https://stackoverflow.com/questions/24699495/opencv-keypoints-response-greater-or-less?lq=1
size和response的解释:
https://stackoverflow.com/questions/10328298/what-does-size-and-response-exactly-represent-in-a-surf-keypoint
Keypoint中的pt是指相对于原图的坐标。(初步实验验证)
drawKeypoints()画的是原图中的坐标;line()画的是Keypoint类中的坐标。
#include <iostream>
#include "opencv2/core.hpp"
#include "opencv2/features2d.hpp"
#include "opencv2/xfeatures2d.hpp"
#include "opencv2/highgui.hpp"
#include <opencv2/imgproc.hpp>
using namespace std;
using namespace cv;
using namespace cv::xfeatures2d;
using cv::xfeatures2d::SiftFeatureDetector;
int main( int argc, char* argv[])
{
Mat img1 = imread("./img1.ppm", CV_LOAD_IMAGE_GRAYSCALE);
int n1=0,n0=0,n2=0,n3=0;
int minHessian = 1000;
cv::Ptr<SiftFeatureDetector> siftdtc = SiftFeatureDetector::create(minHessian);
std::vector<KeyPoint> keyPoint1;
// 检测特征点
siftdtc->detect(img1,keyPoint1);
Mat img_keyPoint1;
drawKeypoints(img1, keyPoint1, img_keyPoint1, Scalar::all(-1), DrawMatchesFlags::DEFAULT);
cout<<keyPoint1.size()<<endl;
for(int i=0;i<keyPoint1.size();i++){ line(img_keyPoint1,Point(keyPoint1[i].pt.x,keyPoint1[i].pt.y),Point(keyPoint1[i].pt.x,keyPoint1[i].pt.y+100),Scalar(0,0,255),2,LINE_8);
imshow("keyPoint1 SURF", img_keyPoint1);
waitKey(0);
return 0;
}
2、DMatch类
class CV_EXPORTS_W_SIMPLE DMatch
{
public:
CV_WRAP DMatch();
CV_WRAP DMatch(int _queryIdx, int _trainIdx, float _distance);
CV_WRAP DMatch(int _queryIdx, int _trainIdx, int _imgIdx, float _distance);
CV_PROP_RW int queryIdx; //!< query descriptor index
CV_PROP_RW int trainIdx; //!< train descriptor index
CV_PROP_RW int imgIdx; //!< train image index
CV_PROP_RW float distance;
// less is better
bool operator<(const DMatch &m) const;
};
imgIdx,例如已知一幅图像的sift描述子,与其他十幅图像的描述子进行匹配,找最相似的图像,则imgIdx此时就有用了。
queryIdx是匹配特征点的描述子,trainIdx是被匹配特征点的描述子
Mat descriptors1, descriptors2;
Ptr<DescriptorMatcher> matcher=DescriptorMatcher::create("BruteForce-Hamming");
vector<DMatch> matches;
matcher->match(descriptors1,descriptors2,matches);
for(int i=0;i<5;i++){//输出特征点信息
cout<<matches[i].queryIdx<<endl;
cout<<matches[i].trainIdx<<endl;
cout<<matches[i].distance<<endl;
cout<<"----"<<endl;
}
输出:
0和6分别是descriptors1的第0行和descriptors2的第6行,96是两行比较的汉明距离。可以用这个代码检测:
int k=0;//统计两个描述子中有多少不同位
for(int i=0;i<32;i++){//每个descriptors1和descriptors2的一行是32个整数,每个整数8位,共256位
int kk=0;//用于计算每个整数8位的比较结果
for(int j=0;j<8;j++)//移动8次
{
if(((int)descriptors2.at<uchar>(44,i)^(int)descriptors1.at<uchar>(3,i))&(1<<j))//每个整数异或,然后通过1的移位统计有多少位不同
{
k++;
kk++;
}
}
cout<<bitset<sizeof(int)*2>((int)descriptors2.at<uchar>(6,i)^(int)descriptors1.at<uchar>(0,i))<<" "<<kk<<endl;//输出每个整数的比较结果,需要引入#include <bitset>用于将整数变成二进制
}
cout<<k<<endl;
输出:
3、Size类
/** @brief Template class for specifying the size of an image or rectangle.
The class includes two members called width and height. The structure can be converted to and from
the old OpenCV structures CvSize and CvSize2D32f . The same set of arithmetic and comparison
operations as for Point_ is available.
OpenCV defines the following Size_\<\> aliases:
@code
typedef Size_<int> Size2i;
typedef Size2i Size;
typedef Size_<float> Size2f;
@endcode
*/
template<typename _Tp> class Size_
{
public:
typedef _Tp value_type;
//! default constructor
Size_();
Size_(_Tp _width, _Tp _height);
Size_(const Size_& sz);
Size_(const Point_<_Tp>& pt);
Size_& operator = (const Size_& sz);
//! the area (width*height)
_Tp area() const;
//! true if empty
bool empty() const;
//! conversion of another data type.
template<typename _Tp2> operator Size_<_Tp2>() const;
_Tp width; //!< the width
_Tp height; //!< the height
};
typedef Size_<int> Size2i;
typedef Size_<int64> Size2l;
typedef Size_<float> Size2f;
typedef Size_<double> Size2d;
typedef Size2i Size;
定义一个size:
Size a(1,5);
cout<<a.width<<" "<<a.height<<endl;
输出:
4、Point类
https://blog.csdn.net/weicao1990/article/details/53517751/