opencv c++ mat to vector<keypoint>
Posted
技术标签:
【中文标题】opencv c++ mat to vector<keypoint>【英文标题】: 【发布时间】:2015-04-27 14:33:45 【问题描述】:在搜索了这个问题的答案(1、2、3、4)之后,我仍然对这两个问题感到困惑
如果可能的话 如果是的话,怎么做我希望能够从已写入包含Point2f keypoints
的cv::Mat
的.xml
文件中读取,并将其读回其原始状态std::vector<cv::KeyPoint>
。
我对文件的写入如下所示:
cv::Ptr<cv::FeatureDetector> detector = new cv::OrbFeatureDetector(featureSize);
cv::FileStorage fsKpts("keypoints.xml", cv::FileStorage::WRITE);
for(size_t i = 0; i < ImgVec.size(); i ++)
std::vector<cv::KeyPoint> imgKpts;
std::vector<cv::Point2f> points;
std::vector<cv::KeyPoint>::iterator it;
detector->detect(ImgVec[i], imgKpts);
for(it = imgKpts.begin(); it != imgKpts.end(); it ++) points.push_back(it->pt);
cv::Mat matKpts(points);
cv::string iValue = std::to_string(i);
cv::string filename = "Image_" + iValue;
fsKpts << filename << matKpts;
fsKpts.release();
但到目前为止,我完全无法将它读回原来的std::vector<cv::KeyPoint>
状态,所以要进行keypoint
匹配。
有什么帮助吗?
编辑
目前的阅读猜测:
std::vector<cv::KeyPoint> fileKptsVec;
std::vector<cv::Point2f> filePoints;
cv::FileStorage fs("keypoints.xml", cv::FileStorage::READ);
for(size_t i = 0; i < imgVec.size(); i++)
cv::string iValue = std::to_string(i);
cv::string filename = "Image_" + iValue;
fs[filename] >> filePoints[i];
fileKptsVec.push_back(filePoints[i]); // -- Doesn't work
fs.release();
编辑 2
.xml
内容:
<?xml version="1.0"?>
<opencv_storage>
<Image_0 type_id="opencv-matrix">
<rows>500</rows>
<cols>1</cols>
<dt>"2f"</dt>
<data>
456. 640. 458. 638. 603. 525. 411. 353. 604. 548. 417. 334. 600.
515. 382. 334. 594. 448. 572. 481. 449. 603. 574. 612. 441. 648.
470. 334. 439. 650. 412. 387. 438. 550. 568. 514. 575. 602. 452.
...
</data></Image_0>
<Image_1 type_id="opencv-matrix">
<rows>500</rows>
<cols>1</cols>
<dt>"2f"</dt>
<data>
521. 353. 467. 563. 537. 510. 505. 378. 479. 286. 451. 552. 460.
554. 541. 545. 463. 554. 492. 404. 457. 552. 534. 546. 463. 562.
541. 550. 519. 350. 490. 285. 498. 473. 497. 635. 451. 578. 461.
...
</data></Image_1>
etc. etc.
【问题讨论】:
您检查过您的 .xml 内容吗?这是你所期望的? 你能把你的代码也发布出来吗?.xml
的内容是正确的,我的“读取代码”只是猜测,实际上不起作用,但我想我可以添加它
【参考方案1】:
你应该这样做:http://docs.opencv.org/2.4.9/modules/core/doc/xml_yaml_persistence.html 获取功能。
但是,如果您想使用 Mat,则在访问 Mat 元素时,基本上使用 http://docs.opencv.org/2.4.9/modules/core/doc/basic_structures.html#mat-at 您的模板将是 Point2f。
Mat image_i;
fs2["Image_i"] >> image_i;
Point2f firstPoint = image_i.at<Point2f>(0);
编辑:
我检查了你的代码,所以,你应该这样做:
std::vector<std::vector<cv::KeyPoint>> fileKptsVec;
std::vector<cv::Mat> filesVec(imgVec.size());
cv::FileStorage fs("keypoints.xml", cv::FileStorage::READ);
for(size_t i = 0; i < imgVec.size(); i++)
std::vector<cv::KeyPoint> imageIKeypoints;
cv::string iValue = std::to_string(i);
cv::string filename = "Image_" + iValue;
fs[filename] >> filesVec[i];
for(size_t j = 0; j < filesVec[i].rows; j++)
cv::KeyPoint kp;
kp.pt = filesVec[i].at<cv::Point2f>(j);
imageIKeypoints.push_back(kp);
fileKptsVec.push_back(imageIKeypoints);
fs.release();
但是,当您返回 KeyPoint 时,您有位置但丢失了其他信息。如果有问题:http://docs.opencv.org/2.4.9/modules/core/doc/xml_yaml_persistence.html 获取功能。
【讨论】:
filesVec
有一个小问题,经过一些修改后,它现在无法将行 fs[filename] >> filesVec[i];
运行为 vector subscript is out of range
,但我看不出是什么原因造成的这一点都没有。 filename
对 .xml
文件是正确的,我用不同的数字替换了 i
,检查是否有任何重复的变量......什么都没有!这是一个已知问题,还是这里有问题?
我对上面的代码做了一点修改,将filesVec初始化为imgVec的大小。 filesVec.push_back(fs[文件名]);应该也可以。
奇怪的是它之前运行良好...不过谢谢!以上是关于opencv c++ mat to vector<keypoint>的主要内容,如果未能解决你的问题,请参考以下文章
阅读 vector<Mat> 或 Video ? (Opencv 和 C++)
在 OpenCV 中 std::vector 而不是 cv::Mat 的 `type` 的解释是啥,我该如何更改它? (C++)
使用 python 预处理后,C++(opencv)中的 Mat 类型数据与 image_to_array 相同吗?