给定图像数据,我如何将 RGB 值叠加到 vector 的 vector 上。从下面的代码;我有一个代表图像的 uint8_t 类型的数组,然后我 reinterpret_cast 3 字节到 RGB 结构,并通过 for 循环将它们放入二维数组中。
这有效(在屏幕截图下方)但感觉“笨拙”,是否有任何其他方法可以实现同样的目的? (也许通过迭代器到 vector 的 vector ,copy_n 或类似的)
#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;
}
最佳答案
恕我直言,
vector<vector< >>
如果行可能具有不同的长度但这样的东西实际上不再称为矩阵,则适用。 (OP 样本的原始数据形成一个按行存储的矩阵。)为什么需要复制
temp
数组到vector<>
?这是复制数据。如果终身可以授予temp
可以直接访问。 (否则,它可能会被复制到一个vector<uint8_t>
中。)据我所知,
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
关于C++ RGB 图像数据叠加到二维数组中( vector 的 vector ),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50505481/