简体   繁体   中英

How to align 2 images in OpenCV with ORB? (fail to compile)

First of all, this is my first time using C++. I'm using C++ because OpenCV is very limited in C.

OpenCV documentation isn't the most explicative I've seen.

I have tried to rewrite this ORB example for use in my project.

The code is:

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 **********************************************************
 ******************************************************************************/

Note: When I write C, I always try to follow the Linux Kernel Coding Style; that's the reason I avoided typedef s, namespace s, and wrote class and all that stuff before everything; I like to have everything be very explicit.

The first thing is that I had to remove #include "opencv2/xfeatures2d.hpp" because that header does not exist on my system (Debian Stretch). However, I read that header here , and it doesn't seem to contain the solution to my problem.

When I compile that file, I get the following errors:

/.../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

Is the example I took simply broken? Does it fail because I lack one header? Does it fail because I didn't understand some C++ stuff? Else?

EDIT:

Installed OpenCV like this: apt-get install libopencv-dev

Version in debian stretch is: 2.4.9.1+dfsg1-2

Change the following parts of the code:

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

...

substitute imgptr by *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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM