I have a std:vector<float>
storing elements in CHW
format. Here, C=8, H=48, W=48
.
I wish to store this in a cv::Mat
in HWC format.
I am clueless as to how to do this.
One of the simplest methods is to create single-channel cv::Mat
s of size 48 x 48, then merge them all together with cv::merge
.
Below is a function that takes in a std::vector<float>
with the number of rows, columns and channels then creates a final cv::Mat
that is of size H x W x C
. Since your data is in C x H x W
format, this unfortunately becomes a bit more difficult as the data per channel is not in a contiguous format. Specifically, if the data was in a typical H x W x C
format, the way to access the data in a flattened format would be:
HWC ---> index = (i*cols + j) + k*rows*cols
(i, j, k)
would be the row, column and channel indices to access the corresponding element in the vector. Your data is in C x H x W
format which means to access the data in a flattened format:
CHW ---> index = (k*rows + i) + j*channels*rows
Therefore, we will iterate over each channel k
, and grab the row and column location (i, j)
and temporarily store it into a vector then use this vector and create a single-channel cv::Mat
. We'll then stack these cv::Mat
s at the very end.
#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;
}
To use this function:
std::vector<float> data = ...; // Data is created here
cv::Mat output = CreateMatFromVector(data, 48, 48, 8);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.