OpenCV Error: Assertion failed (!outImage.empty()) in drawKeypoints, file /build/opencv-L2vuMj/openc

运行特征提取和匹配时报错:

OpenCV Error: Assertion failed (!outImage.empty()) in drawKeypoints, file /build/opencv-L2vuMj/opencv-3.2.0+dfsg/modules/features2d/src/draw.cpp, line 115
terminate called after throwing an instance of 'cv::Exception'
  what():  /build/opencv-L2vuMj/opencv-3.2.0+dfsg/modules/features2d/src/draw.cpp:115: error: (-215) !outImage.empty() in function drawKeypoints

源代码:

#include <iostream>
#include <vector>
#include "vfc.h"
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

// 定义ORB特征参数
#define ORB_N_FEATURE				1000	// 需要提取的特征点数目
#define ORB_N_OCTAVE_LAYERS			8		// 8, default value
#define ORB_FAST_THRESHOLD			20		// 20, default value
#define ORB_EDGE_THRESHOLD			31		// 31, default value
#define ORB_PATCH_SIZE				31		// 31, default value
#define ORB_SCALE					1.2		// the default value 1.2 seems not so good, for only features locate on the corners always leads to a weak tracking

int main()
{

    // 读取两张待匹配图片
    Mat image1 = imread( "./image/tsukuba_1.png");
    Mat image2 = imread( "./image/tsukuba_2.png");

    // 提取ORB特征点
    std::vector<KeyPoint> keypoints1, keypoints2;
    Mat descriptors1, descriptors2;

    Ptr<ORB> orb = ORB::create(ORB_N_FEATURE);
    orb->setFastThreshold(ORB_FAST_THRESHOLD);
    orb->setEdgeThreshold(ORB_EDGE_THRESHOLD);
    orb->setPatchSize(ORB_PATCH_SIZE);
    orb->setNLevels(ORB_N_OCTAVE_LAYERS);
    orb->setScaleFactor(ORB_SCALE);
    orb->setMaxFeatures(ORB_N_FEATURE);
    orb->setWTA_K(2);
    orb->setScoreType(ORB::HARRIS_SCORE); // HARRIS_SCORE, also has FAST_SCORE
    orb->detectAndCompute(image1, Mat(), keypoints1, descriptors1);
    orb->detectAndCompute(image2, Mat(), keypoints2, descriptors2);

    //绘制提取到的特征点
    Mat featureImgAll, featureImg1,featureImg2;
    cout << "# orb keypoints number: " << keypoints1.size()  << endl;
    image1.copyTo(featureImg1);
    image2.copyTo(featureImg2);
    drawKeypoints(image1, keypoints1, featureImg1, Scalar::all(-1));
    drawKeypoints(image2, keypoints2, featureImg2, Scalar::all(-1));
    hconcat(featureImg1, featureImg2, featureImgAll);
    putText(featureImgAll, "ORB keypoints", Point(20, 20), FONT_HERSHEY_SIMPLEX, 0.8, Scalar(0, 0, 255), 2);
    imshow("ORB keypoints", featureImgAll);



    // ---------------  特征点匹配方法暴力匹配(Brute Force)  --------------------------
    // 暴力匹配法,直接找距离最近的点
    double t = (double)getTickCount();
    BFMatcher matcher_bf(NORM_HAMMING, true); //使用汉明距离度量二进制描述子,允许交叉验证
    vector<DMatch> Matches_bf;
    matcher_bf.match(descriptors1, descriptors2, Matches_bf);
    t = 1000 * ((double)getTickCount() - t) / getTickFrequency();

    assert(Matches_bf.size() > 0);
    cout << "# Brute Force Matches: " << Matches_bf.size() << "/" << keypoints1.size() << ", Times ="<<t<<" ms " << endl;
    Mat BF_img;
    drawMatches(image1, keypoints1, image2, keypoints2, Matches_bf, BF_img);
    resize(BF_img, BF_img, Size(2*image1.cols, image1.rows));
    putText(BF_img, "Brute Force Matches", Point(20, 20), FONT_HERSHEY_SIMPLEX, 0.8, Scalar(0, 0, 255), 2);
    imshow("Brute Force Matches", BF_img);



    // ---------------  矢量场一致性(VFC)筛选特征点匹配对 ----------------------------
    // 参考:Robust Point Matching via Vector Field Consensus", IEEE Transactions on Image Processing, 2014

    // 数据格式预处理
    vector<Point2f> X;
    vector<Point2f> Y;
    X.clear();
    Y.clear();

 	// -------------开始代码-------------
    // 将Matches_bf里的匹配点对分别放到X,Y 向量里,约5行代码,参考OpenCV DMatch类
    vector<int> queryIdxs(Matches_bf.size()), trainIdxs(Matches_bf.size());
    for (size_t i = 0;i<Matches_bf.size();i++)
    {
        queryIdxs[i] = Matches_bf[i].queryIdx;
        trainIdxs[i] = Matches_bf[i].trainIdx;
    }
    KeyPoint::convert(keypoints1, X, queryIdxs);
    KeyPoint::convert(keypoints2, Y, trainIdxs);
    // -------------结束代码-------------

    // 调用VFC主函数
    t = (double)getTickCount();
    VFC myvfc;
    myvfc.setData(X, Y);
    myvfc.optimize();
    vector<int> matchIdx = myvfc.obtainCorrectMatch();
    t = 1000 * ((double)getTickCount() - t) / getTickFrequency();

    // 筛选正确的匹配
    std::vector< DMatch > Matches_VFC;
    for (unsigned int i = 0; i < matchIdx.size(); i++) {
        int idx = matchIdx[i];
        Matches_VFC.push_back(Matches_bf[idx]);
    }

    cout << "# Refine Matches (after VFC): " << Matches_VFC.size() << "/" << Matches_bf.size() << ", Times ="<<t<<" ms " << endl;

    // 绘制筛选结果
    Mat imageVFC;
    drawMatches(image1, keypoints1, image2, keypoints2, Matches_VFC, imageVFC);
    resize(imageVFC, imageVFC, Size(2*image1.cols, image1.rows));
    putText(imageVFC, "VFC Matches", Point(20, 20), FONT_HERSHEY_SIMPLEX, 0.8, Scalar(0, 0, 255), 2);
    imshow("VFC Matches", imageVFC);


    waitKey(0);

    destroyAllWindows();
    return 0;
}

 图片文件位置:

解决方案:

执行文件是在build里面,

因此要么把image文件夹拖进build去,

要么读取文件地址开头的.换成..跳转到上一个文件夹找image文件夹

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值