首页 > 解决方案 > 在 C++ 中将向量转换为 OpenCV Matd1d

问题描述

我有一个变量M,它是一个cv::Mat1d矩阵。它是这样制作的:

cv::Mat1d<double> M;

它在其他一些可能不需要的代码中填充了一堆值,当我打印它时它看起来像这样:

[-0.9344576352096885;
 -0.9344576352096885;
 -0.5766199600499906;
 0.2846686026510846;
 0.9589011777015718;
 0.9285453673591227;
 0.3137239980297359;
 -0.2302718892981206;
 -0.2921750731112262;
 -0.2206633656711884;
 -0.2175072323850435;
 -0.1725991485554647;
 -0.2140556050785325;
 -0.4148403958730175;
 -0.4036417215304363;
 -0.06016889338878993;
 0.3028103268622913;
 0.4454375499811856;
 0.3803583582813156;
 0.3188387192279333;
 0.3914868895364941;
 0.4488724871465618;
 0.2694705005556897;
 -0.05248136866304744;
 -0.2971598882254832;
 -0.3545797186279719;
 -0.2294426230118397;
 -0.1673776410980104;
 -0.2768386357175945;
 -0.3276029287776189;
 -0.2361695287135101;
 -0.06139424097086685;
 0.1621769468562924;
 0.3275221571852822;
 0.3153071221383847;
 0.1341365194415481;
 -0.04596232030582767;
 -0.08961855126383761;
 -0.02999823421387905;
 -0.03225119207066054]

它是大小[1 x 40]

我必须转换M为向量X才能对其进行一些计算。我是这样转换的:

vector<ld> X;
X.push_back(M.at<double>(0, 0));
for (int i = 1; i < M.rows; i++) {
    X.push_back(M.at<double>(i, 0));
    }

现在当我打印它时(在我所做的计算无关紧要之后),它看起来像这样:

[0 0 0 0 0 -1 -1 0 1 0 0 0 0 0 0 0 -1 0 0 0 0 0 0 0 0 -1 0 0 0 0 0 0 0 0 0 0 1 0 0]

并且是大小40

如何转换X回 [1x40]cv::Mat1d使其与 的类型相同M

注意:如果我的问题/语法/其他任何事情令人震惊,我很抱歉。我刚刚将python的相对安全性留给c ++......

编辑

我想我解决了。如果有人好奇或者我的解决方案需要更正,这里是:

 Mat1d test;
    for (int i = 0; i < X.size(); i++) {
        double new_val = (double) X[i];
        test.push_back(new_val);
    }

标签: c++opencvmatrixvector

解决方案


我不确定我是否完全了解您的需求。你在这里做两件事,

  1. 处理整数和浮点类型之间的类型转换
  2. 在行向量和列向量之间重塑数组

cv::Mat::reshape与 numpy 的 reshape 有点不同,但做同样的事情。你可以让两个 Mats 共享相同的数据,一个用于行视图,另一个用于列视图。

cv::Mat m1_column, m2_row;
m2_row = m1_column.reshape(0, 1);
// first arg: number of channels. 0 means same.
// second arg: number of rows. make it a row vector.

cv::Mat::convertTo大致相当于 numpy 的ndarray.astype. 它将转换为所需类型的值复制到另一个cv::Mat.

cv::Mat m1_floats, m2_ints, m3_floats;
m1_floats.convertTo(m2_ints, CV_8U);
m2_ints.convertTo(m3_floats, CV_32F);

根据需要将两者结合起来。

您甚至不需要在列格式和行格式之间移动。只需在Mat::at<>(). 它会像被展平一样穿过矩阵。

您可以Mat从 a构造 astd::vector以便它共享向量的内存:

std::vector<int> X; // contains values from somewhere, ints should be 32 bit
cv::Mat X_as_a_Mat(1, X.size(), CV_32S, X.data()); // a single-row Mat sharing the std::vector's data
cv::Mat X_as_doubles;
X_as_a_Mat.convertTo(X_as_doubles, CV_64F); // converts data type

此代码假定它int是 32 位有符号类型 ( CV_32S)。我不知道你vector<ld>应该是什么元素类型。


推荐阅读