此函数提取并计算query.keypoints:
// extract features
analyzer->analyze(query);
像这样:
bool Analyzer::analyze(Query &query) {
// detect keypoints
query.keypoints.clear();
assert(query.keypoints.empty());
detector->detect(query.grayImage, query.keypoints);
// no keypoints detected!
if (query.keypoints.empty()) {
cout << "no keypoints detected!" << endl;
return false;
}
// compute descriptors
query.descriptors.release();
assert(query.descriptors.empty());
extractor->compute(query.grayImage, query.keypoints, query.descriptors);
// note: keypoints for which a descriptor cannot be computed are removed
if (query.keypoints.empty()) {
cout << "cannot compute keypoints!" << endl;
return false;
}
}
之后我将query.keypoints与模式/训练关键点匹配:
// if analyze() is ok, match descriptors
analyzer->match(query);
像这样:
void Analyzer::match(Query &query) {
assert(!query.descriptors.empty());
// query.matches.clear();
matcher->match(query.descriptors, query.matches);
}
现在我想分析匹配集:
double max_dist = 200; double min_dist = 100;
//-- Quick calculation of max and min distances between keypoints
for( int i = 0; i < pattern->descriptors.rows; i++ ) {
double dist = query.matches[i].distance;
if( dist < min_dist ) min_dist = dist;
if( dist > max_dist ) max_dist = dist;
}
//-- Localize the object
std::vector<cv::Point2f> obj;
std::vector<cv::Point2f> scene;
for( int i = 0; i < pattern->descriptors.rows; i++ ) {
if( query.matches[i].distance <= max(2*min_dist, 0.02) ) {
// get keypoints from good matches
// SEGMENTATION FAULT HERE!
// query.matches[i].queryIdx seems to be negative? possible?
cout << query.keypoints[query.matches[i].queryIdx].pt <<endl;
// BASICALLY THIS FAILS
// obj.push_back( pattern->keypoints[ query.matches[i].queryIdx ].pt );
// scene.push_back( query.keypoints[ query.matches[i].trainIdx ].pt );
}
}
但每次尝试时,我都会在上面的代码
中看到分段错误// SEGMENTATION FAULT HERE!
// query.matches[i].queryIdx seems to be negative? possible?
cout << query.keypoints[query.matches[i].queryIdx].pt <<endl;
我认为缺少关键点。所以我无法通过queryID检索query.keypoints。
cv::DMatch match = query.matches[i];
cout << match.queryIdx << endl;
cout << query.matches.size() << endl;
int queryID = match.queryIdx;
cv::KeyPoint test = query.keypoints[queryID]; // FAILS
cout << test.pt << endl;
我做错了什么?我被困了..!请点赞我..;)
---编辑---
这是Valgrind Memcheck输出:
[Result] Features: 420; Matches: 181; Time(ms): 757.842
Creating Query instance..
-- Max dist : 224,000000
-- Min dist : 0,000000
==11770== Invalid read of size 4
==11770== at 0x41759C: cv::Point_<float>::Point_(cv::Point_<float> const&) (operations.hpp:1623)
==11770== by 0x41A166: cv::KeyPoint::KeyPoint(cv::KeyPoint const&) (features2d.hpp:69)
==11770== by 0x41AFA2: Controller::detectObject(om::Query&) (Controller.cpp:169)
==11770== by 0x41B9B7: Controller::displayFunction(cv::Mat&, cv::Mat&) (Controller.cpp:261)
==11770== by 0x414909: processVideo() (App.cpp:109)
==11770== by 0x414C4F: main (App.cpp:144)
==11770== Address 0x2c9d9620 is not stack'd, malloc'd or (recently) free'd
==11770==
==11770==
==11770== Process terminating with default action of signal 11 (SIGSEGV)
==11770== Access not within mapped region at address 0x2C9D9620
==11770== at 0x41759C: cv::Point_<float>::Point_(cv::Point_<float> const&) (operations.hpp:1623)
==11770== by 0x41A166: cv::KeyPoint::KeyPoint(cv::KeyPoint const&) (features2d.hpp:69)
==11770== by 0x41AFA2: Controller::detectObject(om::Query&) (Controller.cpp:169)
==11770== by 0x41B9B7: Controller::displayFunction(cv::Mat&, cv::Mat&) (Controller.cpp:261)
==11770== by 0x414909: processVideo() (App.cpp:109)
==11770== by 0x414C4F: main (App.cpp:144)
==11770== If you believe this happened as a result of a stack
==11770== overflow in your program's main thread (unlikely but
==11770== possible), you can try to increase the size of the
==11770== main thread stack using the --main-stacksize= flag.
==11770== The main thread stack size used in this run was 8388608.
==11770==
==11770== HEAP SUMMARY:
==11770== in use at exit: 37,488,211 bytes in 27,473 blocks
==11770== total heap usage: 121,456 allocs, 93,983 frees, 60,575,106 bytes allocated
==11770==
==11770== LEAK SUMMARY:
==11770== definitely lost: 16,496 bytes in 35 blocks
==11770== indirectly lost: 2,140,260 bytes in 623 blocks
==11770== possibly lost: 22,477,384 bytes in 1,566 blocks
==11770== still reachable: 12,635,159 bytes in 24,368 blocks
==11770== suppressed: 0 bytes in 0 blocks
==11770== Rerun with --leak-check=full to see details of leaked memory
==11770==
==11770== For counts of detected and suppressed errors, rerun with: -v
==11770== Use --track-origins=yes to see where uninitialised values come from
==11770== ERROR SUMMARY: 1502 errors from 47 contexts (suppressed: 0 from 0)
Killed
with --leak-check = full
==11938== Process terminating with default action of signal 11 (SIGSEGV)
==11938== Access not within mapped region at address 0x2C774CA4
==11938== at 0x41759C: cv::Point_<float>::Point_(cv::Point_<float> const&) (operations.hpp:1623)
==11938== by 0x41A166: cv::KeyPoint::KeyPoint(cv::KeyPoint const&) (features2d.hpp:69)
==11938== by 0x41AFA2: Controller::detectObject(om::Query&) (Controller.cpp:169)
==11938== by 0x41B9B7: Controller::displayFunction(cv::Mat&, cv::Mat&) (Controller.cpp:261)
==11938== by 0x414909: processVideo() (App.cpp:109)
==11938== by 0x414C4F: main (App.cpp:144)
==11938== If you believe this happened as a result of a stack
==11938== overflow in your program's main thread (unlikely but
==11938== possible), you can try to increase the size of the
==11938== main thread stack using the --main-stacksize= flag.
==11938== The main thread stack size used in this run was 8388608.
==11938==
==11938== HEAP SUMMARY:
==11938== in use at exit: 35,574,636 bytes in 27,138 blocks
==11938== total heap usage: 97,784 allocs, 70,646 frees, 58,484,719 bytes allocated