【问题标题】:Can I cast a vector into an OpenCv matrix?我可以将向量转换为 OpenCv 矩阵吗?
【发布时间】:2017-03-09 03:06:59
【问题描述】:

我想直接使用 OpenCVs 矩阵函数对向量对象进行操作。

我目前正在做的是使用 memcpy 将数据复制到矩阵中,但我真的很想直接对其进行操作,因为我非常关心性能。以下是我当前按预期工作的实现。

工作实施

void TrajectorySmoother::SmoothTrajectoryOnce(
std::vector<navstack_msgs::location>& path,
const unsigned int& end_remove)
{
  cv::Mat_<double> matrix_orig = cv::Mat(path.size(), sizeof(navstack_msgs::location)/sizeof(double), CV_64F);
  memcpy(matrix_orig.data, path.data(), path.size()*sizeof(navstack_msgs::location));
  ROS_INFO_STREAM("mat: " << matrix_orig);
}

我尝试使用 static_castreinterpret_cast,但它们似乎不起作用,所以我尝试将指向数据的指针作为指向 openCV 矩阵的指针。

指针转换方法

void TrajectorySmoother::SmoothTrajectoryOnce(
    std::vector<navstack_msgs::location>& path,
    const unsigned int& end_remove)
{
  cv::Mat_<double> matrix_orig = cv::Mat(path.size(), sizeof(navstack_msgs::location)/sizeof(double), CV_64F);
  cv::Mat_<double> * matrix_ptr = reinterpret_cast<cv::Mat_<double> *>(path&);
  ROS_INFO_STREAM("mat: " << (*matrix_ptr));
}

它的输出是一个分号流。我认为它可能需要重新整形,但我得到一个错误,它不连续。

【问题讨论】:

  • 它们不是都是连续的数据类型吗?我认为既然 memcpy 有效,那么我应该能够随心所欲地转换数据。我的逻辑有问题吗?
  • 想一想,vector 通常只是指向分配给vector 的数据的几个指针,所以你已经将一个指向数据而不是数据的指针转换为你的mat。克罗姆只知道你穿过了谁的记忆。
  • 我知道内存区域的大小,因为我是counting on the vector to be contiguous。我想我应该可以施放它。
  • vector 数据是连续的。不幸的是,vector 数据在这里……而vector 本身就在那里。无论如何,你违反了Strict Aliasing Rule。阅读关于类型别名的部分。

标签: c++ opencv pointers vector casting


【解决方案1】:

您没有发布navstack_msgs::location 的定义,因此很难说您的要求是否合理。

OpenCV 为“借用”(即非拥有)内存提供了一堆 (4) cv::Mat 构造函数:

Mat (int rows, int cols, int type, void *data, size_t step=AUTO_STEP)

Mat (Size size, int type, void *data, size_t step=AUTO_STEP)

Mat (int ndims, const int *sizes, int type, void *data, const size_t *steps=0)

Mat (const std::vector< int > &sizes, int type, void *data, const size_t *steps=0)

http://docs.opencv.org/3.2.0/d3/d63/classcv_1_1Mat.html#a51615ebf17a64c968df0bf49b4de6a3a

由于 OpenCV 矩阵是行优先的,你可以像这样使用它来创建一个Mat“视图”:

std::vector<T> path;
cv::Mat mat(path.size(), sizeof(T), CV_8U, path.data());

现在每一行都有path中一个元素的数据。

但是您必须在这里假设将T 解释为uchars 的序列是有意义的。如果您认为 T 是一堆 doubles(例如 POD:struct T { double x; double y; };)。然后就可以了

cv::Mat mat(path.size(), sizeof(T) / 8, CV_64F, path.data());

但如果T 有其他内容或者它有指针(例如typedef std::vector&lt;double&gt; T),那么您将无法通过cv::Mat 查看它。

【讨论】:

  • 谢谢。我会在早上试一试,如果成功,我会记下我的答案。
  • 我等不及了。是的,这行得通。感谢您不抱怨并提供解决方案。
猜你喜欢
  • 1970-01-01
  • 2016-05-10
  • 2017-06-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-29
  • 2010-12-28
  • 1970-01-01
相关资源
最近更新 更多