Один из простейших способов - создать одноканальные cv::Mat
s размером 48 x 48, а затем объединить их все вместе с cv::merge
.
Ниже приведена функция который принимает std::vector<float>
с количеством строк, столбцов и каналов, а затем создает окончательный cv::Mat
с размером H x W x C
. Поскольку ваши данные имеют формат 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);