如何在OpenCV 3.1上使用SIFT特征绘制检测对象

How to draw detected object with SIFT features on OpenCV 3.1?

本文关键字:SIFT 特征 绘制 对象 检测 OpenCV      更新时间:2023-10-16

使用以下代码查找图像之间的匹配:

#include <opencv2/highgui/highgui.hpp>
#include <opencv2/xfeatures2d/nonfree.hpp>
#include <opencv2/xfeatures2d.hpp>
#include <vector>
using namespace std;
using namespace cv;
int main(int argc, char *argv[]) {
    //cv::initModule_nonfree();
    //initModule_features2d();
    Mat img_1 = imread("C:/Users/Dan/Desktop/0.jpg", 1);
    Mat img_2 = imread("C:/Users/Dan/Desktop/0.jpg", 1);
    cv::Ptr<Feature2D> f2d = xfeatures2d::SIFT::create();
    //-- Step 1: Detect the keypoints:
    std::vector<KeyPoint> keypoints_1, keypoints_2;
    f2d->detect(img_1, keypoints_1);
    f2d->detect(img_2, keypoints_2);
    //-- Step 2: Calculate descriptors (feature vectors)    
    Mat descriptors_1, descriptors_2;
    f2d->compute(img_1, keypoints_1, descriptors_1);
    f2d->compute(img_2, keypoints_2, descriptors_2);
    Mat out0;
    drawKeypoints(img_1, keypoints_1, out0);
    imshow("KeyPoint0.jpg", out0);
    //-- Step 3: Matching descriptor vectors using BFMatcher :
    BFMatcher matcher;
    std::vector< DMatch > matches;
    matcher.match(descriptors_1, descriptors_2, matches);
    Mat img_matches = Mat::zeros( img_1.size(), CV_8UC3 );
    drawMatches(img_1,keypoints_1,img_2,keypoints_2,matches,img_matches);
    imshow("matches", img_matches);
    waitKey(0);  // Keep window there until user presses 'q' to quit.
    return 0;
}

由于OpenCV 3.1函数被更改,我使用SURFSIFT寻找示例代码,但找不到任何。

如何修改此代码,使其将绘制轮廓周围检测到的对象类似于OpenCV version ?

您将需要使用findHomography来获得将您的训练图像(img_1)与待检测图像(img_2)相关的转换

然后你可以简单地使用获得的单应性对训练图像的边界框(原点)进行perspectiveTransform,将正确的边界框放置在检测到的图像上

ORB检测示例中的相关代码

Mat inlier_mask, homography;
vector<KeyPoint> inliers1, inliers2;
vector<DMatch> inlier_matches;
if(matched1.size() >= 4) {
    homography = findHomography(Points(matched1), Points(matched2),
                                RANSAC, ransac_thresh, inlier_mask);
}
for(unsigned i = 0; i < matched1.size(); i++) {
    if(inlier_mask.at<uchar>(i)) {
        int new_i = static_cast<int>(inliers1.size());
        inliers1.push_back(matched1[i]);
        inliers2.push_back(matched2[i]);
        inlier_matches.push_back(DMatch(new_i, new_i, 0));
    }
}
stats.inliers = (int)inliers1.size();
stats.ratio = stats.inliers * 1.0 / stats.matches;
vector<Point2f> new_bb;
perspectiveTransform(object_bb, new_bb, homography);
Mat frame_with_bb = frame.clone();
if(stats.inliers >= bb_min_inliers) {
    drawBoundingBox(frame_with_bb, new_bb);
}
Mat res;
drawMatches(first_frame, inliers1, frame_with_bb, inliers2,
            inlier_matches, res,
            Scalar(255, 0, 0), Scalar(255, 0, 0));