给定图像数据如何将RGB值叠加到矢量矢量上。从下面的代码;我有一个类型uint8_t的数组代表图像,然后我 reinterpret_cast将3字节映射到RGB结构,并通过for循环将它们放入2D数组中。
这是有效的(在屏幕截图下方),但感觉“笨拙”,有没有其他方法可以达到同样的效果? (可能是通过矢量向量,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;
}
答案 0 :(得分:1)
恕我直言,vector<vector< >>
是合适的,如果行可能有不同的长度,但这样的东西实际上不再称为矩阵。 (OP样本的原始数据形成一个按行存储的矩阵。)
为什么有必要将temp
数组复制到vector<>
?这是重复数据。如果可以授予终身时间,则可以直接访问temp
。 (否则,可以将其复制到vector<uint8_t>
。)
AFAIK,未授予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()
以及更直观的Image::operator[]()
来访问RGB-tripel。
示例代码:
#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