C++ OpenCV SIFT关键点提取isuue

C++ OpenCV SIFT关键点提取isuue,c++,opencv,image-processing,feature-detection,sift,C++,Opencv,Image Processing,Feature Detection,Sift,我试图提取筛选关键点。对于我下载的示例图像(高度400px宽度247px水平和垂直分辨率300dpi),它工作正常。下图显示了提取的点 然后我尝试将相同的代码应用于我拍摄和编辑的图像(高度443px宽度541px水平和垂直分辨率72dpi) 为了创建上面的图像,我旋转了原始图像,然后移除了它的背景,并使用Photoshop调整了它的大小,但是我的代码,对于该图像,没有像第一幅图像那样提取特征 见结果: 它只提取很少的点。我期待第一个案例的结果。 对于第二种情况,当我使用原始图像而不进行任何

我试图提取筛选关键点。对于我下载的示例图像(高度400px宽度247px水平和垂直分辨率300dpi),它工作正常。下图显示了提取的点

然后我尝试将相同的代码应用于我拍摄和编辑的图像(
高度443px宽度541px水平和垂直分辨率72dpi

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

见结果:

它只提取很少的点。我期待第一个案例的结果。 对于第二种情况,当我使用原始图像而不进行任何编辑时,程序会给出第一种情况的分数。 下面是我使用的简单代码

#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;
}
#包括
#包括
#包括
使用名称空间cv;
int main(){
材料src、描述符、目的地;
矢量关键点;
src=imread(“…”);
CVT颜色(src、src、CV_bgr2灰色);
筛选;
筛选(src、src、关键点、描述符、假);
图纸关键点(src、关键点、目的地);
imshow(“筛选”,目的地);
cvWaitKey(0);
返回0;
}
我做错了什么?在调整大小后,我需要做什么才能得到第一种情况下的结果


谢谢大家!

在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;
}
#包括
#包括
#包括
使用名称空间cv;
使用名称空间std;
int main(){
材料src、描述符、目的地;
矢量关键点;
src=imread(“D:\\ImagesForTest\\leaf.jpg”);
CVT颜色(src、src、CV_bgr2灰色);
筛分筛分(2000,3,0.004);
筛选(src、src、关键点、描述符、假);
图纸关键点(src、关键点、目的地);
imshow(“筛选”,目的地);
cvWaitKey(0);
返回0;
}
结果是:

密集抽样示例:

#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;
}
#包括
#包括
#包括
#包括
#包括
#包括“opencv2/nonfree/nonfree.hpp”
int main(int argc,char*argv[])
{
cv::initModule_nonfree();
cv::namedWindow(“结果”);
cv::Mat bgr_img=cv::imread(“D:\\ImagesForTest\\lena.jpg”);
if(bgr_img.empty())
{
退出(退出失败);
}
cv::Mat gray_img;
cv::CVT颜色(bgr\U img、灰色\U img、cv::颜色\U bgr灰色);
cv::normalize(gray\u img,gray\u img,0,255,cv::NORM\u MINMAX);
cv::密度特性探测器(12.0f、1、0.1f、10);
向量关键点;
检测器。检测(灰度图像、关键点);
std::vector::迭代器itk;
对于(itk=keypoints.begin();itk!=keypoints.end();+itk)
{
std::cout pt pt,itk->size,cv::Scalar(0255255),1,cv_AA);
cv::circle(bgr_img,itk->pt,1,cv::Scalar(0255,0),-1);
}
cv::Ptr描述符牵引器=cv::描述符牵引器::创建(“SURF”);
cv::Mat描述符;
描述符->计算(灰色、关键点、描述符);
//SIFT在离开图像边缘时返回较大的负值。

descriptors.setTo(0,descriptors在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;
}
#包括
#包括
#包括
使用名称空间cv;
使用名称空间std;
int main(){
材料src、描述符、目的地;
矢量关键点;
src=imread(“D:\\ImagesForTest\\leaf.jpg”);
CVT颜色(src、src、CV_bgr2灰色);
筛分筛分(2000,3,0.004);
筛选(src、src、关键点、描述符、假);
图纸关键点(src、关键点、目的地);
imshow(“筛选”,目的地);
cvWaitKey(0);
返回0;
}
结果是:

密集抽样示例:

#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;
}
#包括
#包括
#包括
#包括
#包括
#包括“opencv2/nonfree/nonfree.hpp”
int main(int argc,char*argv[])
{
cv::initModule_nonfree();
cv::namedWindow(“结果”);
cv::Mat bgr_img=cv::imread(“D:\\ImagesForTest\\lena.jpg”);
if(bgr_img.empty())
{
退出(退出失败);
}
cv::Mat gray_img;
cv::CVT颜色(bgr\U img、灰色\U img、cv::颜色\U bgr灰色);
cv::normalize(gray\u img,gray\u img,0,255,cv::NORM\u MINMAX);
cv::密度特性探测器(12.0f、1、0.1f、10);
向量关键点;
检测器。检测(灰度图像、关键点);
std::vector::迭代器itk;
对于(itk=keypoints.begin();itk!=keypoints.end();+itk)
{
std::cout pt pt,itk->size,cv::Scalar(0255255),1,cv_AA);
cv::circle(bgr_img,itk->pt,1,cv::Scalar(0255,0),-1);
}
cv::Ptr描述符牵引器=cv::描述符牵引器::创建(“SURF”);
cv::Mat描述符;
描述符->计算(灰色、关键点、描述符);
//SIFT在离开图像边缘时返回较大的负值。

描述符。设置为(0,描述符我尝试使用这个,但结果与前一个相同。尝试降低对比度阈值。也可以尝试使用其他检测器,即FAST或Harris\Hessian,并留下SIFT进行描述。感谢您的支持,它现在可以正常工作。正如旧ufo所说,我使用快速角点检测算法测试图像,然后我可以提取更多关键点我想知道,使用快速算法给出的关键点可以准确地对对象进行分类吗?我想你可以,但我认为使用密集特征采样会更好。我已经在我的答案中添加了代码。这是关键点。中心是小绿圈。关键点大小(计算出特征内的面积)是大的黄色圆圈。特征重叠通常会给出更好的结果。关于冲浪大小,你可以在这里阅读:我尝试使用这个,但结果与前一个相同。尝试降低对比度阈值。你也可以尝试使用其他检测器,即FAST或Harris\Hessian,并留下SIFT进行描述。感谢你的支持,现在一切正常.正如老ufo所说,我用快速角点检测算法测试了图像,然后我可以提取比sift更多的关键点。我想知道使用关键点p