如何使用带有ORB的OpenCV对齐2张图像? (无法编译)

时间:2018-10-09 16:37:14

标签: c++ opencv orb

首先,这是我第一次使用C ++。我使用的是C ++,因为OpenCV在C语言中非常有限。

OpenCV文档不是我见过的最详尽的

我试图重写此ORB example以便在我的项目中使用。

代码是:

img_orb.cpp

/******************************************************************************
 ******* headers **************************************************************
 ******************************************************************************/
/* Standard (C++) ------------------------------------------------------------*/
        /* std::vector */
    #include <vector>

/* Packages ------------------------------------------------------------------*/
        /* opencv */
    #include <opencv2/opencv.hpp>
    #include <opencv2/features2d/features2d.hpp>

/* Project -------------------------------------------------------------------*/
    #include "img_orb.hpp"


/******************************************************************************
 ******* macros ***************************************************************
 ******************************************************************************/
    # define    MAX_FEATURES    (500)
    # define    GOOD_MATCH_P    (0.15)


/******************************************************************************
 ******* main *****************************************************************
 ******************************************************************************/
void    img_orb_align   (struct _IplImage  *pattern,
                struct _IplImage  *imgptr)
{
    /* Transform (struct _IplImage *) to (class cv::Mat) */
    /* Make a copy so that they aren't modified */
    class cv::Mat   img_0;
    class cv::Mat   img_1;
    img_0   = cv::cvarrToMat(pattern, true);
    img_1   = cv::cvarrToMat(imgptr, true);

    /* Variables to store keypoints & descriptors */
    std::vector <class cv::KeyPoint>    keypoints_0;
    std::vector <class cv::KeyPoint>    keypoints_1;
    class cv::Mat               descriptors_0;
    class cv::Mat               descriptors_1;

    /* Detect ORB features & compute descriptors */
    class cv::Ptr <class cv::Feature2D> orb;
    orb = cv::ORB::create(MAX_FEATURES);
    orb->detectAndCompute(img_0, cv::Mat(), keypoints_0, descriptors_0);
    orb->detectAndCompute(img_1, cv::Mat(), keypoints_1, descriptors_1);

    /* Match structures */
    std::vector <struct cv::DMatch>     matches;
    cv::Ptr <class cv::DescriptorMatcher>   matcher;
    matcher = cv::DescriptorMatcher::create("BruteForce-Hamming");
    matcher->match(descriptors_1, descriptors_0, matches, cv::Mat());

    /* Sort matches by score */
    std::sort(matches.begin(), matches.end());

    /* Remove not so good matches */
    int good_matches;
    good_matches    = GOOD_MATCH_P * matches.size();
    matches.erase(matches.begin() + good_matches, matches.end());

    /* Draw top matches */
    class cv::Mat   img_matches;
    cv::drawMatches(img_1, keypoints_1, img_0, keypoints_0, matches,
                                img_matches);
    cv::imwrite("matches.jpg", img_matches);

    /* Extract location of good matches */
    std::vector <class cv::Point_ <float>>  points_0;
    std::vector <class cv::Point_ <float>>  points_1;
    int i;  
    for (i = 0; i < matches.size(); i++) {
        points_1.push_back(keypoints_1[matches[i].queryIdx].pt);
        points_0.push_back(keypoints_0[matches[i].trainIdx].pt);
    }

    /* Find homography */
    class cv::Mat   img_hg;
    img_hg  = cv::findHomography(points_1, points_0, CV_RANSAC);

    /* Use homography to warp image */
    class cv::Mat   img_align;
    cv::warpPerspective(img_1, img_align, img_hg, img_0.size());

    /* Write img_align into imgptr */
    *imgptr = img_align;
}


/******************************************************************************
 ******* end of file **********************************************************
 ******************************************************************************/

注意:当我写C时,我总是尝试遵循Linux内核编码风格。这就是我回避typedefnamespace和写class以及所有东西的原因。我希望一切都非常明确。

第一件事是我必须删除#include "opencv2/xfeatures2d.hpp",因为该标头在我的系统上不存在(Debian Stretch)。但是,我读到了标题here,它似乎没有包含解决我的问题的方法。

编译该文件时,出现以下错误:

/.../img_orb.cpp: In function ‘void img_orb_align(_IplImage*, _IplImage*)’:
/.../img_orb.cpp:78:36: error: no matching function for call to ‘cv::ORB::create(int)’
  orb = cv::ORB::create(MAX_FEATURES);
                                    ^
In file included from /usr/include/opencv2/opencv.hpp:53:0,
                 from /.../img_orb.cpp:19:
/usr/include/opencv2/features2d/features2d.hpp:269:35: note: candidate: static cv::Ptr<cv::Feature2D> cv::Feature2D::create(const string&)
     CV_WRAP static Ptr<Feature2D> create( const string& name );
                                   ^~~~~~
/usr/include/opencv2/features2d/features2d.hpp:269:35: note:   no known conversion for argument 1 from ‘int’ to ‘const string& {aka const std::__cxx11::basic_string<char>&}’
/.../img_orb.cpp:79:7: error: ‘class cv::Feature2D’ has no member named ‘detectAndCompute’; did you mean ‘detectImpl’?
  orb->detectAndCompute(img_0, cv::Mat(), keypoints_0, descriptors_0);
       ^~~~~~~~~~~~~~~~
/.../img_orb.cpp:80:7: error: ‘class cv::Feature2D’ has no member named ‘detectAndCompute’; did you mean ‘detectImpl’?
  orb->detectAndCompute(img_1, cv::Mat(), keypoints_1, descriptors_1);
       ^~~~~~~~~~~~~~~~
Makefile:101: recipe for target 'img_orb.s' failed

我所举的例子是简单的吗?是否会因为缺少一个头而失败?它会因为我不了解某些C ++知识而失败吗?还有吗?

编辑:

像这样安装的OpenCV:apt-get install libopencv-dev

debian延伸版本为:2.4.9.1+dfsg1-2

1 个答案:

答案 0 :(得分:0)

更改代码的以下部分:

void    img_orb_align   (struct _IplImage  *pattern,
                struct _IplImage  **imgptr2)

...

imgptr代替*imgptr2

...

    /* Detect ORB features & compute descriptors */
    /* This works in openCV 2.4, but does not work in openCV 3.x */
    class cv::ORB   orb;
    orb(img_0, cv::Mat(), keypoints_0, descriptors_0);
    orb(img_1, cv::Mat(), keypoints_1, descriptors_1);
#if 0
    /* This did not work in openCV 2.4;  It does work in openCV 3.x */
    class cv::Ptr <class cv::Feature2D> orb;
    orb = cv::ORB::create(MAX_FEATURES);
    orb->detectAndCompute(img_0, cv::Mat(), keypoints_0, descriptors_0);
    orb->detectAndCompute(img_1, cv::Mat(), keypoints_1, descriptors_1);
#endif

...

    /* Write img_align into imgptr (need a tmp img;  don't know why) */
    struct _IplImage    imgtmp;
    int         cols;
    int         rows;
    int         depth;
    int         chan;
    cols        = img_align.cols;
    rows        = img_align.rows;
    depth       = (*imgptr2)->depth;
    chan        = (*imgptr2)->nChannels;
    cvReleaseImage(imgptr2);
    *imgptr2    = cvCreateImage(cvSize(cols, rows), depth, chan);
    imgtmp      = img_align;
    cvCopy(&imgtmp, *imgptr2);
    img_align.release();
#if 0
    /* This did not work */
    *imgptr = img_align;
#endif