尝试在 opencv 4.5.1 中使用 SIFT 提取特征时出现问题

Posted

技术标签:

【中文标题】尝试在 opencv 4.5.1 中使用 SIFT 提取特征时出现问题【英文标题】:Problems while trying to extract features using SIFT in opencv 4.5.1 【发布时间】:2021-08-18 07:37:58 【问题描述】:

我试图在 opencv 4.5.1 中使用 SIFT 提取图像的特征,但是当我尝试使用 drawKeypoints() 检查结果时,我不断收到这个神秘的错误:

OpenCV(4.5.1) Error: Assertion failed (!fixedType() || ((Mat*)obj)->type() == mtype) in cv::debug_build_guard::_OutputArray::create, file C:\build\master_winpack-build-win64-vc14\opencv\modules\core\src\matrix_wrap.cpp, line 1147

D:\School\IP2\OpenCVApplication-VS2019_OCV451_basic\x64\Debug\OpenCVApplication.exe (process 6140) exited with code -1.
To automatically close the console when debugging stops, enable Tools->Options->Debugging->Automatically close the console when debugging stops.

问题似乎出在 drawKeypoints() 函数上,但我不确定是什么导致了问题。

功能:

vector<KeyPoint> extractFeatures(String path) 

    Mat_<uchar> source = imread(path, 0);

    Mat_<uchar> output(source.rows, source.cols); 
    vector<KeyPoint> keypoints;

    Ptr<SIFT> sift = SIFT::create();
    sift->detect(source, keypoints);

    drawKeypoints(source, keypoints, output);
    imshow("sift_result", output);

    return keypoints;

【问题讨论】:

您是否检查过您是否从 SIFT 获得任何分数? 【参考方案1】:

您遇到了异常,因为 drawKeypointsoutput 参数必须是 3 通道彩色图像,并且您正在将 output 初始化为 1 通道(灰度)图像。

当使用:Mat output(source.rows, source.cols);Mat output; 时,drawKeypoints 函数会自动创建一个新的彩色矩阵。 使用派生模板矩阵类Mat_&lt;uchar&gt;时,函数drawKeypoints引发异常!

您可以将:Mat_&lt;uchar&gt; output(source.rows, source.cols); 替换为:

Mat_<Vec3b> output(source.rows, source.cols); //Create 3 color channels image (matrix).

注意: 你也可以用Mat代替Mat_

Mat output; //The matrix is going to be dynamically allocated inside drawKeypoints function.  

注意:

我当前的 OpenCV 版本 (4.2.0) 不支持 SIFT,因此我使用 ORB 代替(用于测试)。

这是用于测试的代码示例:

#include "opencv2/opencv.hpp"

using namespace cv;
using namespace std;

int main()
   
    Mat_<uchar> source = imread("graf.png", 0);

    Mat_<Vec3b> output(source.rows, source.cols); //Create 3 color channels image (matrix).
    vector<KeyPoint> keypoints;

    Ptr<ORB> orb = ORB::create();
    orb->detect(source, keypoints);

    drawKeypoints(source, keypoints, output);
    imshow("orb_result", output);

    waitKey(0);
    destroyAllWindows();

    return 0;


结果:

【讨论】:

以上是关于尝试在 opencv 4.5.1 中使用 SIFT 提取特征时出现问题的主要内容,如果未能解决你的问题,请参考以下文章

OpenCV 3 中 SIFT 的示例代码?

使用openCV在图像中实现SIFT

如何使用 C++ 在 OpenCV 4.2.0 中使用 SIFT? [关闭]

不能在 Python OpenCV v4.20 中使用 SIFT

使用 OpenCV 丢弃细胞图像中的异常 SIFT 关键点

OpenCV SIFT特征算法详解与使用