首先,这是我第一次使用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内核编码风格。这就是我回避typedef
,namespace
和写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
答案 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