将CHW格式的浮点向量转换为cv::Mat

Converting vector of floats in CHW format to a cv::Mat

本文关键字:转换 cv 向量 Mat CHW 格式      更新时间:2023-10-16

我有一个以CHW格式存储元素的std:vector<float>。在这里C=8, H=48, W=48

我希望将其存储在HWC格式的cv::Mat中。

我不知道该怎么做。

最简单的方法之一是创建大小为48 x 48的单通道cv::Mats,然后将它们与cv::merge合并在一起。

下面是一个函数,它接收具有行、列和通道数的std::vector<float>,然后创建大小为H x W x C的最终cv::Mat。由于您的数据是C x H x W格式,不幸的是,这会变得有点困难,因为每个通道的数据不是连续的格式。具体来说,如果数据是典型的H x W x C格式,那么访问扁平格式数据的方法是:

HWC ---> index = (i*cols + j) + k*rows*cols

(i, j, k)将是访问向量中相应元素的行、列和信道索引。您的数据是C x H x W格式,这意味着以扁平格式访问数据:

CHW ---> index = (k*rows + i) + j*channels*rows

因此,我们将迭代每个通道k,获取行和列位置(i, j)并将其临时存储到向量中,然后使用该向量创建单个通道cv::Mat。然后,我们将把这些cv::Mat堆叠在最后。

#include <opencv2/opencv.hpp>
cv::Mat CreateMatFromVector(const std::vector<float>& data, const int rows, const int cols, const int channels)
{
// Create stacked vector of cv::Mats
std::vector<cv::Mat> stacked_mats;
stacked_mats.reserve(channels);  // Reserve space for efficiency
// Stack the channels
for (int k = 0; k < channels; ++k) {
std::vector<float> pixels;
pixels.reserve(rows * cols);
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j) {
pixels.push_back(data[k * rows + i + j * channels * rows]);
}
}
cv::Mat channel(rows, cols, CV_32FC1, pixels.data());
stacked_mats.push_back(channel);
}
// Stores output matrix
cv::Mat output;
// Create the output matrix
cv::merge(stacked_mats, output);
return output;
}

使用此功能:

std::vector<float> data = ...; // Data is created here
cv::Mat output = CreateMatFromVector(data, 48, 48, 8);