2

我正在尝试构建brief_match_test.cppOpenCV 附带的示例程序,但是当我运行程序时,我不断从 cv::findHomography() 函数中收到此错误:

OpenCV Error: Assertion failed (mtype == type0 || (CV_MAT_CN(mtype) == CV_MAT_CN(type0) && ((1 << type0) & fixedDepthMask) != 0)) in create, file /opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_graphics_opencv/opencv/work/OpenCV-2.4.3/modules/core/src/matrix.cpp, line 1421
libc++abi.dylib: terminate called throwing an exception
findHomography ... Abort trap: 6

我正在像这样编译它:

g++ `pkg-config --cflags opencv` `pkg-config --libs opencv` brief_match_test.cpp -o brief_match_test

我在程序中添加了一些东西来显示 FAST 算法找到的关键点,但没有触及处理单应性的部分。我将包含我修改后的示例,以防万一我搞砸了:

/*
 * matching_test.cpp
 *
 *  Created on: Oct 17, 2010
 *      Author: ethan
 */
#include "opencv2/core/core.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <vector>
#include <iostream>

using namespace cv;
using namespace std;

//Copy (x,y) location of descriptor matches found from KeyPoint data structures into Point2f vectors
static void matches2points(const vector<DMatch>& matches, const vector<KeyPoint>& kpts_train,
                    const vector<KeyPoint>& kpts_query, vector<Point2f>& pts_train, vector<Point2f>& pts_query)
{
  pts_train.clear();
  pts_query.clear();
  pts_train.reserve(matches.size());
  pts_query.reserve(matches.size());
  for (size_t i = 0; i < matches.size(); i++)
  {
    const DMatch& match = matches[i];
    pts_query.push_back(kpts_query[match.queryIdx].pt);
    pts_train.push_back(kpts_train[match.trainIdx].pt);
  }

}

static double match(const vector<KeyPoint>& /*kpts_train*/, const vector<KeyPoint>& /*kpts_query*/, DescriptorMatcher& matcher,
            const Mat& train, const Mat& query, vector<DMatch>& matches)
{

  double t = (double)getTickCount();
  matcher.match(query, train, matches); //Using features2d
  return ((double)getTickCount() - t) / getTickFrequency();
}

static void help()
{
       cout << "This program shows how to use BRIEF descriptor to match points in features2d" << endl <<
               "It takes in two images, finds keypoints and matches them displaying matches and final homography warped results" << endl <<
                "Usage: " << endl <<
                    "image1 image2 " << endl <<
                "Example: " << endl <<
                    "box.png box_in_scene.png " << endl;
}

const char* keys =
{
    "{1|  |box.png               |the first image}"
    "{2|  |box_in_scene.png|the second image}"
};

int main(int argc, const char ** argv)
{
    Mat outimg;
    help();
    CommandLineParser parser(argc, argv, keys);
    string im1_name = parser.get<string>("1");
    string im2_name = parser.get<string>("2");

    Mat im1 = imread(im1_name, CV_LOAD_IMAGE_GRAYSCALE);
    Mat im2 = imread(im2_name, CV_LOAD_IMAGE_GRAYSCALE);

    if (im1.empty() || im2.empty())
    {
      cout << "could not open one of the images..." << endl;
      cout << "the cmd parameters have next current value: " << endl;
      parser.printParams();
      return 1;
    }

    double t = (double)getTickCount();

    FastFeatureDetector detector(15);
    BriefDescriptorExtractor extractor(32); //this is really 32 x 8 matches since they are binary matches packed into bytes

    vector<KeyPoint> kpts_1, kpts_2;
    detector.detect(im1, kpts_1);
    detector.detect(im2, kpts_2);

    t = ((double)getTickCount() - t) / getTickFrequency();

    cout << "found " << kpts_1.size() << " keypoints in " << im1_name << endl << "fount " << kpts_2.size()
        << " keypoints in " << im2_name << endl << "took " << t << " seconds." << endl;

    drawKeypoints(im1, kpts_1, outimg, 200);
    imshow("Keypoints - Image1", outimg);
    drawKeypoints(im2, kpts_2, outimg, 200);
    imshow("Keypoints - Image2", outimg);

    Mat desc_1, desc_2;

    cout << "computing descriptors..." << endl;

    t = (double)getTickCount();

    extractor.compute(im1, kpts_1, desc_1);
    extractor.compute(im2, kpts_2, desc_2);

    t = ((double)getTickCount() - t) / getTickFrequency();

    cout << "done computing descriptors... took " << t << " seconds" << endl;

    //Do matching using features2d
    cout << "matching with BruteForceMatcher<Hamming>" << endl;
    BFMatcher matcher_popcount(NORM_HAMMING);
    vector<DMatch> matches_popcount;
    double pop_time = match(kpts_1, kpts_2, matcher_popcount, desc_1, desc_2, matches_popcount);
    cout << "done BruteForceMatcher<Hamming> matching. took " << pop_time << " seconds" << endl;

    vector<Point2f> mpts_1, mpts_2;
    cout << "matches2points ... ";
    matches2points(matches_popcount, kpts_1, kpts_2, mpts_1, mpts_2); //Extract a list of the (x,y) location of the matches
    cout << "done" << endl;

    vector<char> outlier_mask;
    cout << "findHomography ... ";
    Mat H = findHomography(mpts_2, mpts_1, RANSAC, 1, outlier_mask);
    cout << "done" << endl;

    cout << "drawMatches ... ";
    drawMatches(im2, kpts_2, im1, kpts_1, matches_popcount, outimg, Scalar::all(-1), Scalar::all(-1), outlier_mask);
    cout << "done" << endl;
    imshow("matches - popcount - outliers removed", outimg);

    Mat warped;
    Mat diff;
    warpPerspective(im2, warped, H, im1.size());
    imshow("warped", warped);
    absdiff(im1,warped,diff);
    imshow("diff", diff);
    waitKey();
    return 0;
}
4

4 回答 4

1

我不确定,所以我真的要回答这个问题,因为到目前为止还没有其他人知道,而且你问这个问题已经 10 个小时了。

我的第一个想法是你没有足够的点对。单应性至少需要 4 对,否则无法找到唯一解。您可能希望确保仅在匹配数至少为 4 时才调用 findHomography。

或者,这里这里的问题是关于同一个失败的断言(尽管调用了与你不同的函数)。我猜 OpenCV 会进行某种形式的动态类型检查或模板化,因此应该在编译时发生的类型不匹配错误最终会以断言失败的形式出现运行时错误。说了这么多,也许你应该在传入 findHomography 之前将 mpts_1 和 mpts_2 转换为 cv::Mat。

于 2013-04-14T06:36:22.583 回答
1

这是内部 OpenCV 类型问题。findHomography() 想要 vector < unsigned char > 作为最后一个参数。但是 drawMatches() 需要 vector < char > 作为最后一个。

于 2013-09-09T14:01:51.753 回答
0

我认为在这个页面上解释了很多关于brief_match_test.cpp 以及纠正它的方法。

于 2014-04-22T22:19:47.563 回答
0

你可以这样做:

vector<char> outlier_mask; Mat outlier(outlier_mask); Mat H = findHomography(mpts_2, mpts_1, RANSAC, 1, outlier);

于 2019-08-27T03:12:23.493 回答