c++ - OpenCV - linker error when implementing a new descriptor - rotation invariant BRIEF -
this question has answer here:
as part of research on binary descriptor, i'm implementing rotation invariant version of brief. basically, rotate sampling points angle of patch (given detector).
now, i'm having linking problems function:
algorithminfo* info() const;
i'm getting "unresolved external symbol" function's name.
here code: in features2d.hpp":
class cv_exports invariantbriefdescriptorextractor : public descriptorextractor { public: static const int patch_size = 48; static const int kernel_size = 9; // bytes length of descriptor in bytes. can equal 16, 32 or 64 bytes. invariantbriefdescriptorextractor(int bytes = 32); virtual void read(const filenode&); virtual void write(filestorage&) const; virtual int descriptorsize() const; virtual int descriptortype() const; algorithminfo* info() const; protected: virtual void computeimpl(const mat& image, vector<keypoint>& keypoints, mat& descriptors) const; typedef void(*pixeltestfn)(const mat&, const vector<keypoint>&, const int *, mat&); int bytes_; pixeltestfn test_fn_; static int bit_pattern_64_[512 * 4]; };
and file briefri.cpp (which contains implementation):
#include "precomp.hpp" #include <algorithm> #include <vector> #include <iostream> #include <iomanip> using namespace cv; static void calculatesums(const mat &sum, const int &count, const int *pattern, float &cos_theta, float &sin_theta, keypoint pt); inline int smoothedsum(const mat& sum, const keypoint& pt, int y, int x) { static const int half_kernel = briefdescriptorextractor::kernel_size / 2; int img_y = (int)(pt.pt.y + 0.5) + y; int img_x = (int)(pt.pt.x + 0.5) + x; return sum.at<int>(img_y + half_kernel + 1, img_x + half_kernel + 1) - sum.at<int>(img_y + half_kernel + 1, img_x - half_kernel) - sum.at<int>(img_y - half_kernel, img_x + half_kernel + 1) + sum.at<int>(img_y - half_kernel, img_x - half_kernel); } static void pixeltests16(const mat& sum, const std::vector<keypoint>& keypoints, const int *pattern, mat& descriptors) { (int = 0; < (int)keypoints.size(); ++i) { uchar* desc = descriptors.ptr(i); const keypoint& pt = keypoints[i]; float angle = pt.angle; angle *= (float)(cv_pi / 180.f); float cos_theta = cos(angle); float sin_theta = sin(angle); int count = 0; (int ix = 0; ix < 16; ix++){ (int jx = 7; jx >= 0; jx--){ int suma, sumb; calculatesums(sum, count, pattern,cos_theta, sin_theta, pt); desc[ix] += (uchar)((suma< sumb) << jx); count += 4; } } } } static void pixeltests32(const mat& sum, const std::vector<keypoint>& keypoints, const int *pattern, mat& descriptors) { (int = 0; < (int)keypoints.size(); ++i) { uchar* desc = descriptors.ptr(i); const keypoint& pt = keypoints[i]; float angle = pt.angle; angle *= (float)(cv_pi / 180.f); float cos_theta = cos(angle); float sin_theta = sin(angle); int count = 0; (int ix = 0; ix < 32; ix++){ (int jx = 7; jx >= 0; jx--){ int suma, sumb; calculatesums(sum, count, pattern,cos_theta, sin_theta, pt); desc[ix] += (uchar)((suma< sumb) << jx); count += 4; } } } } static void pixeltests64(const mat& sum, const std::vector<keypoint>& keypoints, const int *pattern, mat& descriptors) { (int = 0; < (int)keypoints.size(); ++i) { uchar* desc = descriptors.ptr(i); const keypoint& pt = keypoints[i]; float angle = pt.angle; angle *= (float)(cv_pi / 180.f); float cos_theta = cos(angle); float sin_theta = sin(angle); int count = 0; (int ix = 0; ix < 64; ix++){ (int jx = 7; jx >= 0; jx--){ int suma, sumb; calculatesums(sum, count,pattern, cos_theta, sin_theta, pt); desc[ix] += (uchar)((suma< sumb) << jx); count += 4; } } } } static void calculatesums(const mat &sum, const int &count, const int *pattern, float &cos_theta, float &sin_theta, keypoint pt){ int ax = pattern[count]; int ay = pattern[count + 1]; int bx = pattern[count + 2]; int = pattern[count + 3]; int ax2 = ((float)ax)*cos_theta - ((float)ay)*sin_theta; int ay2 = ((float)ax)*sin_theta + ((float)ay)*cos_theta; int bx2 = ((float)bx)*cos_theta - ((float)by)*sin_theta; int by2 = ((float)bx)*sin_theta + ((float)by)*cos_theta; int suma = smoothedsum(sum, pt, ay, ax); int sumb = smoothedsum(sum, pt, by, bx); } namespace cv { invariantbriefdescriptorextractor::invariantbriefdescriptorextractor(int bytes) : bytes_(bytes), test_fn_(null) { switch (bytes) { case 16: test_fn_ = pixeltests16; break; case 32: test_fn_ = pixeltests32; break; case 64: test_fn_ = pixeltests64; break; default: cv_error(cv_stsbadarg, "bytes must 16, 32, or 64"); } } int invariantbriefdescriptorextractor::descriptorsize() const { return bytes_; } int invariantbriefdescriptorextractor::descriptortype() const { return cv_8uc1; } void invariantbriefdescriptorextractor::read(const filenode& fn) { int dsize = fn["descriptorsize"]; switch (dsize) { case 16: test_fn_ = pixeltests16; break; case 32: test_fn_ = pixeltests32; break; case 64: test_fn_ = pixeltests64; break; default: cv_error(cv_stsbadarg, "descriptorsize must 16, 32, or 64"); } bytes_ = dsize; } void invariantbriefdescriptorextractor::write(filestorage& fs) const { fs << "descriptorsize" << bytes_; } void invariantbriefdescriptorextractor::computeimpl(const mat& image, std::vector<keypoint>& keypoints, mat& descriptors) const { // construct integral image fast smoothing (box filter) mat sum; mat grayimage = image; if (image.type() != cv_8u) cvtcolor(image, grayimage, cv_bgr2gray); ///todo allow user pass in precomputed integral image //if(image.type() == cv_32s) // sum = image; //else integral(grayimage, sum, cv_32s); //remove keypoints close border keypointsfilter::runbyimageborder(keypoints, image.size(), patch_size / 2 + kernel_size / 2); descriptors = mat::zeros((int)keypoints.size(), bytes_, cv_8u); test_fn_(sum, keypoints, bit_pattern_64_,descriptors); } int invariantbriefdescriptorextractor:: bit_pattern_64_[512 * 4] = { -1, -2, -1, 7 , -1, -14, 3, -3 , -2, 1, 2, 11 , 6, 1, -7, -10 , 2, 13, 0, -1 , 5, -14, -3, 5 , 8, -2, 4, 2 , 8, -11, 5, -15 (long list)
thanks in advance!
gil
there cv_init_algorithm macro available (within, not outside) opencv libs. used implement algorithm::init() method. set class name create, , expose member vars of algo get() , set() functions, , write()/read() serialization.
here example kaze (taken features2d_init.cpp):
cv_init_algorithm(kaze, "feature2d.kaze", obj.info()->addparam(obj, "upright", obj.upright); obj.info()->addparam(obj, "extended", obj.extended))
so , add features2d lib, have add similar code extractor there.
also, adding line bool cv::initmodule_features2d(void)
(at end of features2d_init.cpp) might nessecary
in meantime, preliminary duct-tape-fix (also, while you're trying code outside features2d module), dummy impl:
class cv_exports invariantbriefdescriptorextractor : public descriptorextractor { public: // ... algorithminfo* info() const { return 0; }
(btw, imho computeimpl function not match inherited 1 descriptorextractor, might next problem.)
Comments
Post a Comment