首页 > 解决方案 > 有效地展平结构数组

问题描述

我正在寻找最有效的方法来展平 C++ 中的结构数组,以便将展平的一维数组数据作为输入传递给cv::Mat. 该结构如下所示:

struct Color3
{
    uint8_t red, green, blue;
}

然后我的代码如下所示:

// Update color frame
cv::Mat colorMat = cv::Mat::zeros(cv::Size(1920, 1080), CV_8UC3)

const Color3* colorPtr = colorFrame->getData(); // Get Frame from Library
std::vector<uchar> vecColorData;
data.reserve(1920 * 1080 * 3);

for (int i = 0; i < 1920 * 1080; ++i)
{
     auto color = *colorPtr;
     vecColorData.push_back(color.red);
     vecColorData.push_back(color.green);
     vecColorData.push_back(color.blue);
     vecColorData++;
}

colorMat.data = vecColorData.data();

有没有比创建中间std::vector和循环整个数组更有效的方法?我想我正在寻找类似的东西:

colorMat.data = colorFrame->getData()

但是,我收到以下错误: type 的值Color3*不能分配给 type 的实体uchar*

标签: c++arraysopencvvector

解决方案


以下答案在技术上不是可移植的,但可以在您在现实生活中遇到的绝大多数平台上运行。

您的Color3结构极有可能没有填充。您可以使用以下方法验证这一点static_assert

static_assert(sizeof(Color3) == sizeof(uint8_t) * 3);

确认后,您可以将数组Color3转换为数组uint8_t并将其直接传递给colorMat.data(假设该成员实际接受uint8_t)。

因此,您的代码变为:

cv::Mat colorMat = cv::Mat::zeros(cv::Size(1920, 1080), CV_8UC3)

const Color3* colorPtr = colorFrame->getData(); // Get Frame from Library

colorMat.data = reinterpret_cast<const uint8_t*>(colorPtr);

请记住,我从未使用过该cv库,并且对数据指针的所有权要求一无所知。以上只是复制了您正在做的事情,而没有不必要的std::vector.


推荐阅读