BFMatcher类
暴力匹配BFMatcher类:
对于第一个集合中的每个描述符,这个匹配器通过尝试每个描述符找到第二个集合中最接近的描述符。
class CV_EXPORTS_W BFMatcher : public DescriptorMatcher
{
public:
//暴力匹配器构造函数
CV_WRAP BFMatcher(
int normType=NORM_L2, //NORM_L1,NORM_L2,NORM_HAMMING,NORM_HAMMING2之一
bool crossCheck=false );//为每个描述符找到k个最近的邻居,true时只返回一致的对
virtual ~BFMatcher() {}
virtual bool isMaskSupported() const { return true; }
virtual Ptr<DescriptorMatcher> clone( bool emptyTrainData=false ) const;
protected:
virtual void knnMatchImpl( InputArray queryDescriptors, std::vector<std::vector<DMatch> >& matches, int k,
InputArrayOfArrays masks=noArray(), bool compactResult=false );
virtual void radiusMatchImpl( InputArray queryDescriptors, std::vector<std::vector<DMatch> >& matches, float maxDistance,
InputArrayOfArrays masks=noArray(), bool compactResult=false );
int normType;
bool crossCheck;
};
关于normType:
对于SIFT和SURF描述符,选择L1和L2较好;
ORB、BRISK、BRIEF,选择NORM_HAMMING;
对于ORB,当WTA_K == 3或4时,使用NORM_HAMMING2。
函数drawMatches():
从两个图像中用一条线连接两个关键点(圈)绘制找到的关键点匹配。
函数drawMatches()参数说明:
void drawMatches(
InputArray img1, //第一个源图像
const std::vector<KeyPoint>& keypoints1, //第一个源图像的关键点
InputArray img2, //第二个源图像
const std::vector<KeyPoint>& keypoints2, //第二个源图像的关键点
const std::vector<DMatch>& matches1to2, //从第一个图像到第二个图像匹配
InputOutputArray outImg, //输出图像
const Scalar& matchColor=Scalar::all(-1), //匹配到的关键点的颜色(线条和连接的关键点)
const Scalar& singlePointColor=Scalar::all(-1), //未匹配到的关键点的颜色(圆圈)
const std::vector<char>& matchesMask=std::vector<char>(), //确定绘制哪些匹配的掩模。如果掩模为空,则绘制所有匹配
int flags=DrawMatchesFlags::DEFAULT ); //设置绘图功能的标志
BFMatcher示例:
#include<opencv2/opencv.hpp>
#include<opencv2/xfeatures2d.hpp>
using namespace cv;
using namespace cv::xfeatures2d;
int main()
{
Mat src1, src2, dst;
src1 = imread("E:/image/image/card2.jpg");
src2 = imread("E:/image/image/cards.jpg");
if (src1.empty()||src2.empty())
{
printf("could not load image \n");
return -1;
}
namedWindow("input", CV_WINDOW_AUTOSIZE);
imshow("input", src1);
Ptr<SURF>dector = SURF::create(700);
std::vector<KeyPoint> keypoints1,keypoints2;
Mat descriptor1, descriptor2;
dector->detectAndCompute(src1, Mat(), keypoints1, descriptor1);
dector->detectAndCompute(src2, Mat(), keypoints2, descriptor2);
//指定L1或L2距离
BFMatcher matcher(NORM_L2);
std::vector<DMatch> matchers;
matcher.match(descriptor1, descriptor2, matchers);
Mat result;
//从两个图像中绘制找到的关键点匹配
drawMatches(src1, keypoints1, src2, keypoints2, matchers, result, Scalar::all(-1), Scalar(0,255,0));
namedWindow("output", CV_WINDOW_AUTOSIZE);
imshow("output", result);
waitKey(0);
return 0;
}