OpenCV SIFT关键点提取问题

时间:2014-07-25 17:18:43

标签: c++ opencv image-processing feature-detection sift

我试图提取SIFT关键点。它适用于我下载的示例图像(height 400px width 247px horizontal and vertical resolutions 300dpi)。下图显示了提取的点。

enter image description here

然后我尝试将相同的代码应用于由我(height 443px width 541px horizontal and vertical resolutions 72dpi)拍摄和编辑的图像。

enter image description here

为了创建上面的图像,我旋转了原始图像,然后删除了它的背景,并使用Photoshop调整了它的大小,但我的代码,对于该图像,并没有像第一张图像那样提取特征。

查看结果:

enter image description here

它只提取了很少的几点。我希望结果与第一种情况一样。 对于第二种情况,当我使用原始图像而不进行任何编辑时,程序会将点作为第一种情况。 这是我使用的简单代码

#include<opencv\cv.h>
#include<opencv\highgui.h>
#include<opencv2\nonfree\nonfree.hpp>

using namespace cv;

int main(){

Mat src, descriptors,dest;
vector<KeyPoint> keypoints;

src = imread(". . .");


cvtColor(src, src, CV_BGR2GRAY);

SIFT sift;
sift(src, src, keypoints, descriptors, false);
drawKeypoints(src, keypoints, dest);
imshow("Sift", dest);
cvWaitKey(0);
return 0;
}

我在这里做错了什么?在调整大小后,我需要做什么才能将第一种情况下的结果发送到我自己的图像?

谢谢!

1 个答案:

答案 0 :(得分:5)

在SIFT构造函数中尝试设置nfeatures参数(可能还需要调整其他参数)。

以下是参考文献中的构造函数定义:

SIFT::SIFT(int nfeatures=0, int nOctaveLayers=3, double contrastThreshold=0.04, double edgeThreshold=10, double sigma=1.6)

您的代码将是:

#include<opencv\cv.h>
#include<opencv\highgui.h>
#include<opencv2\nonfree\nonfree.hpp>

using namespace cv;
using namespace std;
int main(){

Mat src, descriptors,dest;
vector<KeyPoint> keypoints;

src = imread("D:\\ImagesForTest\\leaf.jpg");


cvtColor(src, src, CV_BGR2GRAY);

SIFT sift(2000,3,0.004);
sift(src, src, keypoints, descriptors, false);
drawKeypoints(src, keypoints, dest);
imshow("Sift", dest);
cvWaitKey(0);
return 0;
}

结果:

enter image description here

密集采样示例:

#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/features2d/features2d.hpp>
#include "opencv2/nonfree/nonfree.hpp"

int main(int argc, char* argv[])
{
    cv::initModule_nonfree();
    cv::namedWindow("result");
    cv::Mat bgr_img = cv::imread("D:\\ImagesForTest\\lena.jpg");
    if (bgr_img.empty()) 
    {
        exit(EXIT_FAILURE);
    }
    cv::Mat gray_img;
    cv::cvtColor(bgr_img, gray_img, cv::COLOR_BGR2GRAY);
    cv::normalize(gray_img, gray_img, 0, 255, cv::NORM_MINMAX);
    cv::DenseFeatureDetector detector(12.0f, 1, 0.1f, 10);
    std::vector<cv::KeyPoint> keypoints;
    detector.detect(gray_img, keypoints);
    std::vector<cv::KeyPoint>::iterator itk;
    for (itk = keypoints.begin(); itk != keypoints.end(); ++itk) 
    {
        std::cout << itk->pt << std::endl;
        cv::circle(bgr_img, itk->pt, itk->size, cv::Scalar(0,255,255), 1, CV_AA);
        cv::circle(bgr_img, itk->pt, 1, cv::Scalar(0,255,0), -1);
    }
    cv::Ptr<cv::DescriptorExtractor> descriptorExtractor = cv::DescriptorExtractor::create("SURF");
    cv::Mat descriptors;
    descriptorExtractor->compute( gray_img, keypoints, descriptors);
    // SIFT returns large negative values when it goes off the edge of the image.
    descriptors.setTo(0, descriptors<0);
    imshow("result",bgr_img);
    cv::waitKey();
    return 0;
}

结果:

enter image description here