OpenCV中的SURF特征匹配

刚开始自学OpenCV不久,也是第一次写博客,所以请各位大神多多指点!

最近初涉OpenCV的仿射变换、SURF特征描述子、鼠标回调、进度条回调等功能,于是写了这个可以观察SURF的特征匹配效果的小程序,其实也是for fun,希望能搏君一玩^_^

PS:由于非CS科班出身,不足之处请各位多指教!


先上程序效果截图:

这里写图片描述

这里写图片描述


程序功能简介:
程序退出:在图像窗口敲击回车键即可;
旋转图像:鼠标拖动Video窗口的Angle轴即可;
缩放图像:鼠标拖动Video窗口的Scale轴即可;
平移图像:在Video窗口,鼠标左键拖拽图像即可;
平移图像复原:在Video窗口,单击鼠标右键即可;
调整特征匹配量:鼠标拖动Macher窗口的Hessian阈值即可。

程序实现环境:VS2010 + OpenCV 2.4.11


#include <iostream>
#include <opencv.hpp>
#include <nonfree/nonfree.hpp>
#include <legacy/legacy.hpp>

using namespace cv;
using namespace std;

static Mat onAffine(Mat* im, Point2f dif);
static Mat onRot(int pos, int rat, Mat* im);
static Mat onSurf(int hes, Mat& im1, Mat& im2);
static void onMouse(int Event, int x, int y, int drag, Mat* im);

void main(int argc, char* argv[])
{
    Mat Cam = imread("Girl.jpg"), dst;
    int pos = 36, rat = 10, hes = 40; //initial value
    namedWindow("Video");   namedWindow("Matcher");
    createTrackbar("Angle","Video", &pos,72); //rotate the image
    createTrackbar("Scale","Video", &rat,20); //scale the image
    createTrackbar("Hessian","Matcher", &hes,80); //minHessian threshold
    setMouseCallback("Video", (MouseCallback)onMouse, &Cam); //drag image

    while((waitKey(50)&255)!=13)
    {//press the Enter key to exit the programe
        dst = onRot(pos, rat, &Cam);    imshow("Video", dst);
        dst = onSurf(hes, Cam, dst);    imshow("Matcher", dst);
    }//end while
}//end main

static Mat onSurf(int hes, Mat& im1, Mat& im2)
{
    SURF Extractor, Detector(20*hes); //HessianThreshold
    //SURF = SurfDescriptorExtractor & SurfFeatureDetector
    vector<KeyPoint> kp1, kp2;  Mat descriptor1, descriptor2, dst;

    Detector.detect(im1, kp1);  Detector.detect(im2, kp2);
    //drawKeypoints(im1, kp1, dst); return dst; //no match

    Extractor.compute(im1, kp1, descriptor1);
    Extractor.compute(im2, kp2, descriptor2);

    vector< DMatch > matches; //DMatch: distance match
    BruteForceMatcher< L2<float> > Matcher; //L2-Distance
    Matcher.match(descriptor1, descriptor2, matches);

    drawMatches(im1, kp1, im2, kp2, matches, dst);  return dst;
}//end onSurf

static void onMouse(int Event, int x, int y, int drag, Mat* im)
{
    static Mat res = im->clone();   static const Point ini(0,0);
    static Point seed(ini), tdf(ini);   Point now(x,y);

    switch(Event)
    {
    case CV_EVENT_LBUTTONDOWN:  seed = now; break;
    case CV_EVENT_LBUTTONUP:    tdf += (now-seed);  break;
    case CV_EVENT_RBUTTONUP:    res.copyTo(*im);    tdf = ini;  break;
    }//end switch

    if(drag==CV_EVENT_FLAG_LBUTTON) //drag the mouse to move the image
        *im = onAffine(&res, tdf+(now-seed)); //use Affine transformation
}//end onMouse

static Mat onAffine(Mat* im, Point2f dif)
{
    Point2f org[3],tri[3];  org[1] = Point2f(im->cols/2, 0);
    org[0] = Point2f(0,0);  org[2] = Point2f(0, im->rows/2);
    for(int i=0; i<3; ++i)  tri[i] = org[i] + dif;

    Mat warp = getAffineTransform(org, tri), dst;
    warpAffine(*im, dst, warp, im->size()); return dst;
}//end onAffine

static Mat onRot(int pos, int rat, Mat* im)
{
    Point center(im->cols/2.0 + 0.5, im->rows/2.0 + 0.5);
    double angle = 5*pos-180, scale = 0.1*rat;
    Mat rot = getRotationMatrix2D(center, angle, scale), dst;
    warpAffine(*im, dst, rot, im->size());  return dst;
}//end onRot

调整旋转角度后的效果图:

这里写图片描述

这里写图片描述


旋转+缩放后的效果图:

这里写图片描述

这里写图片描述


鼠标拖动图像后的效果图:

这里写图片描述

这里写图片描述

猜你喜欢

转载自blog.csdn.net/cosmoshua/article/details/54097576
今日推荐