Search code examples
c++opencvimage-processingsift

Problems while trying to extract features using SIFT in opencv 4.5.1


I am trying to extract features of an image using SIFT in opencv 4.5.1, but when I try to check the result by using drawKeypoints() I keep getting this cryptic error:

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.

The problem seems to be with the drawKeypoints() function but I'm not sure what causes the problem.

The function:

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;
}

Solution

  • You are getting a exception because output argument of drawKeypoints must be 3 channels colored image, and you are initializing output to 1 channel (grayscale) image.

    When using: Mat output(source.rows, source.cols); or Mat output;, the drawKeypoints function creates a new colored matrix automatically.
    When using the derived template matrix class Mat_<uchar>, the function drawKeypoints raises an exception!

    You may replace: Mat_<uchar> output(source.rows, source.cols); with:

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

    Note:
    You may also use Mat instead of Mat_:

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

    Note:

    • My current OpenCV version (4.2.0) has no SIFT support, so I used ORB instead (for testing).

    Here is the code sample used for testing:

    #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;
    }
    

    Result:
    enter image description here