C++ C++;叠加到2D数组中的RGB图像数据(矢量中的矢量)
给定图像数据,如何将RGB值覆盖到向量向量上。从下面的代码;我有一个类型为uint8_t的数组来表示图像,然后 重新解释\u将3个字节强制转换为RGB结构,并将其放置到for循环上的2D数组中 这很有效(屏幕截图下方),但感觉“笨重”,有没有其他方法可以达到同样的效果?(可能通过迭代器对向量向量进行复制或类似操作)C++ C++;叠加到2D数组中的RGB图像数据(矢量中的矢量),c++,image-processing,vector,rgb,C++,Image Processing,Vector,Rgb,给定图像数据,如何将RGB值覆盖到向量向量上。从下面的代码;我有一个类型为uint8_t的数组来表示图像,然后 重新解释\u将3个字节强制转换为RGB结构,并将其放置到for循环上的2D数组中 这很有效(屏幕截图下方),但感觉“笨重”,有没有其他方法可以达到同样的效果?(可能通过迭代器对向量向量进行复制或类似操作) #包括 结构RGB{ uint8_t红色; uint8_t绿色; uint8_t蓝; }; int main(){ std::矢量数据; uint8_t高度、宽度,idx=0,jd
#包括
结构RGB{
uint8_t红色;
uint8_t绿色;
uint8_t蓝;
};
int main(){
std::矢量数据;
uint8_t高度、宽度,idx=0,jdx=0;
//表示图像数据的数据数组-这真的是一个二进制文件
//页眉r、g、BR、g、BR、g、BR、g、BR、g、BR、g、BR、g、b页脚
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};
//根据(h,w)调整数据向量大小,这是我们从标题信息中获得的
高度=温度[0];
宽度=温度[1];
调整大小(高度,标准::向量(宽度));
//填充RGB值的二维数据
对于(uint8_t i=0;i
总之,如果行可能具有不同的长度,但这样的东西实际上不再称为矩阵,则向量>
是合适的。(OP样本的原始数据形成了按行存储的矩阵。)
为什么需要将temp
数组复制到向量
?这是在复制数据。如果可以授予生存期,则可以直接访问temp
。(否则,可以将其复制到向量
)
另外,struct RGB
中的组件打包是不允许的。因此,reinterpret\u cast()
不是访问字节的最干净的方式
因此,我想建议一种解决方案来防止所有这些问题–类映像
,它充当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);
}
};
输出:
使用img.get(i,j)访问:
01 02 03 04 05 06 07 ef 05
0a 01 02 0d fe 00 10 ff ff
使用img[i][j]访问:
01 02 03 04 05 06 07 ef 05
0a 01 02 0d fe 00 10 ff ff
关于3,我认为,对于POD类型,或者更好的平凡类型,重新解释CAST版本是安全的。如果可能的话,不使用更少的裸骨C++似乎还不是更好的……多谢,Scheff回应(1)图像数据将形成矩阵,(2)temp数组表示真正来自二进制文件的数据(如注释中所述,我应该更清楚),并且(3)是的,打包可能是个问题,应该使用#pragma pack()对于alignment@Scheff这是一个微妙的不同问题,因此您所指的句子是关于非平凡类型的,这些类型通过继承是非平凡的。@Scheff这使得在更大的项目中依赖您的类型作为POD是很危险的,依我看。如果您从POD继承,并且满足了某些先决条件,突然之间,我会怎么做ook像一个POD,从POD继承可能不再是POD了。struct RGB
在这里实现了,但是,所有数据成员必须在同一个类中,而不是在多个类中。
并且没有显示继承,因此编译器不能使用填充。@GeckoGeorge是的,问题有点不同-我同意。不过,注释提到了r
和g
这两个都是struct RGB
的组件-就像这个问题/示例中一样。
#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);
}
};
#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;
}