有效地展平结构数组

时间:2018-06-21 15:30:49

标签: c++ arrays opencv vector

我正在寻找一种最有效的方式来扁平化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()

但是,出现以下错误:Color3*类型的值不能分配给uchar*类型的实体。

2 个答案:

答案 0 :(得分:0)

您不需要中间向量。 据我了解,您想为所有数据分配相同的RGB三元组。 对我来说,还不清楚您是否必须自行分配colorMat.data。 在这种情况下,一旦分配了colorMat.data并将其大小设置为1920 * 1080 * 3,您可以执行以下操作:

  uchar * data = colorMat.data;
  for (int i = 0; i < 1920 * 1080; ++i)
  {
    *data++ = (uchar)colorPtr->red;
    *data++ = (uchar)colorPtr->green;
    *data++ = (uchar)colorPtr->.blue;
  }

答案 1 :(得分:0)

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

您的Color3结构很可能没有填充。您可以使用static_assert来实现这一点:

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

确认后,您可以将Color3的数组强制转换为uint8_t的数组,并将其直接传递给colorMat.data(假定该成员实际上接受uint8_t)。 / p>

您的代码因此变为:

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