C++ RGB 图像数据叠加到二维数组中( vector 的 vector )

标签 c++ image-processing vector rgb

给定图像数据,我如何将 RGB 值叠加到 vector 的 vector 上。从下面的代码;我有一个代表图像的 uint8_t 类型的数组,然后我 reinterpret_cast 3 字节到 RGB 结构,并通过 for 循环将它们放入二维数组中。

这有效(在屏幕截图下方)但感觉“笨拙”,是否有任何其他方法可以实现同样的目的? (也许通过迭代器到 vector 的 vector ,copy_n 或类似的)

enter image description here

#include<vector>


struct RGB {
    uint8_t red;
    uint8_t green;
    uint8_t blue;
};


int main() {
    std::vector<std::vector<RGB>> data;
    uint8_t height, width, idx = 0, jdx = 0;

    // data array representing image data - this would really be a bin fle
    //                    header         r,    g,    b        r,    g,    b      r,    g,    b        r,    g,    b       r,    g,    b       r,    g,    b      footer
    uint8_t temp[22] = { 0x02, 0x03,    0x01, 0x02, 0x03,   0x04, 0x05, 0x06,   0x07, 0xef, 0x05,   0x0a, 0x01, 0x02,   0x0d, 0xfe, 0x00,   0x10, 0xff, 0xff,   0xef, 0xef };

    // resize data vector based on (h,w) which we get from header info
    height = temp[0];
    width = temp[1];
    data.resize(height, std::vector<RGB>(width));

    // populate the 2D data of RGB values
    for (uint8_t i = 0; i<6; i++) {
        jdx = i % width;
        data[idx][jdx] = *(reinterpret_cast<RGB*>(&temp[(2 + (i*3))]));

        if (jdx == height)
            idx++;
    }

    return 0;
}

最佳答案

  1. 恕我直言,vector<vector< >>如果行可能具有不同的长度但这样的东西实际上不再称为矩阵,则适用。 (OP 样本的原始数据形成一个按行存储的矩阵。)

  2. 为什么需要复制 temp数组到 vector<> ?这是复制数据。如果终身可以授予temp可以直接访问。 (否则,它可能会被复制到一个 vector<uint8_t> 中。)

  3. 据我所知,struct RGB 中的组件包装不被授予。因此,reinterpret_cast<RGB*>()不是访问字节的最干净的方式。

因此,我想提出一个解决方案来防止所有这些问题 – class Image它用作 temp 中原始数据的包装器/访问器:

#include <cstddef>
#include <cstdint>

struct RGB {
  uint8_t red, green, blue;

  RGB() { } // leaving contents uninitialized
  RGB(uint8_t red, uint8_t green, uint8_t blue):
    red(red), green(green), blue(blue)
  { }
};

class Image {
  private:
    const uint8_t *_pData;
  public:
    class Row {
      private:
        const uint8_t *_pData;
      public:
        Row(const uint8_t *pData): _pData(pData) { }

        RGB operator[](size_t i) const
        {
          const uint8_t *pixel = _pData + 3 * i;
          return RGB(pixel[0], pixel[1], pixel[2]);
        }
    };

    Image(const uint8_t *pData): _pData(pData) { }

    size_t height() const { return _pData[0]; }
    size_t width() const { return _pData[1]; }

    RGB get(size_t i, size_t j) const
    {
      const uint8_t *pixel = _pData + 2 + (i * _pData[1] + j) * 3;
      return RGB(pixel[0], pixel[1], pixel[2]);
    }

    Row operator[](size_t i) const
    {
      return Row(_pData + 2 + i * _pData[1] * 3);
    }
};

可以使用 Image::get() 执行对 RGB 三元组的访问以及更直观的 Image::operator[]() .

示例代码:

#include <iomanip>
#include <iostream>

int main()
{
  // data array representing image data - this would really be a bin fle
  //                    header         r,    g,    b        r,    g,    b      r,    g,    b      footer
  uint8_t temp[22] = { 0x02, 0x03,    0x01, 0x02, 0x03,   0x04, 0x05, 0x06,   0x07, 0xef, 0x05,
                                      0x0a, 0x01, 0x02,   0x0d, 0xfe, 0x00,   0x10, 0xff, 0xff,   0xef, 0xef };
  // access via
  Image img(temp);
  std::cout << std::hex << std::setfill('0');
  // via Image::get()
  std::cout << "access with img.get(i, j):\n";
  for (size_t i = 0, n = img.height(); i < n; ++i) {
    for (size_t j = 0, m = img.width(); j < m; ++j) {
      RGB rgb = img.get(i, j);
      std::cout << "  "
        << std::setw(2) << (unsigned)rgb.red << std::setw(0) << ' '
        << std::setw(2) << (unsigned)rgb.green << std::setw(0) << ' '
        << std::setw(2) << (unsigned)rgb.blue << std::setw(0);
    }
    std::cout << '\n';
  }
  // via Image::operator[]
  std::cout << "access with img[i][j]:\n";
  for (size_t i = 0, n = img.height(); i < n; ++i) {
    for (size_t j = 0, m = img.width(); j < m; ++j) {
      RGB rgb = img[i][j];
      std::cout << "  "
        << std::setw(2) << (unsigned)rgb.red << std::setw(0) << ' '
        << std::setw(2) << (unsigned)rgb.green << std::setw(0) << ' '
        << std::setw(2) << (unsigned)rgb.blue << std::setw(0);
    }
    std::cout << '\n';
  }
  return 0;
}

输出:

access with img.get(i, j):
  01 02 03  04 05 06  07 ef 05
  0a 01 02  0d fe 00  10 ff ff
access with img[i][j]:
  01 02 03  04 05 06  07 ef 05
  0a 01 02  0d fe 00  10 ff ff

Live Demo on coliru

关于C++ RGB 图像数据叠加到二维数组中( vector 的 vector ),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50505481/

相关文章:

c++ - 如何在 C++ 中打印网格 vector

c++ - 如何在 C++ 中获取两个 vector 共有的字符?

c++ - 查询后未返回任何结果的 MongoDB 套接字异常

c++ - 如何为类的私有(private)和公共(public)成员分配内存

java - 如何在 Java 中自动裁剪图像的白色边框?

matlab - 增加图像饱和度

c++ - 如何使用具有用户定义结构的 C++ vector ?

c++ - 我为什么要使用 WinDbg?

c++ - 如何在 QT 中设置中央小部件的大小/位置

java - Zxing 不扫描某些 Data Matrix 代码