我收到一些图像数据unsigned char *image = load_image(…);
此数据是一个3D矩阵:x
(字符),y
(字符)和channel (RGB)
(字符)。
如何通过重载image[x][y][channel]
以[]
的形式访问每个元素?例如。第999行,第10000列,绿色通道:image[999][10000][1]
澄清:
我想使用C多维数组语法:array[x][y][z]
,而不是array[x * height * channels + y * channels + z]
我可以将1D数组作为2D数组访问:
unsigned char (*imageMatrix)[height] = (unsigned char (*)[height])image
imageMatrix[x][y] = 100
I already asked如何在纯C中完成。在这里,我想知道如何在C ++中更好地实现它。
答案 0 :(得分:3)
您可以使用可获得所需内容的功能创建Image
课程
class Image {
int imgSize;
char * img;
public:
Image(): imgSize(0), img(nullptr) {}
Image(char* image, int size): imgSize(size), img(image) {}
char getPixel(int x, int y, int z) {
if(x < imgSize && y < imgSize && z < imgSize) {
return img[x * imgSize * imgSize + y * imgSize + z];
} else {
// Error
}
}
char operator(int x, int y, int z) {
// The same as getPixel
}
}
getPixel
在我看来是最好的方法,因为无论何时你打电话,你(以及使用你的代码的人)都会知道你的名字是什么(即使在6个月后你会立即认识你)得到一个像素)。重载operator()
也是一种很好的方法,但我不会用它来引起混淆或不需要的行为。两者都隐藏了类的内部结构,不需要任何代理类。
重载operator[]
是一个选项,但为了支持[][][]
之类的链接,您需要代理类,如果设计不正确,将严重影响代码的性能。
您可以阅读C++ FAQ了解详情。
答案 1 :(得分:0)
如何通过重载
将每个元素作为image[x][y][channel]
?[]
进行访问
当您为图像类重载数组运算符时,它只能在其接口中支持语法image[x]
。
为了能够支持image[x][y]
,image[x]
需要返回一个对象或对需要支持数组运算符的对象的引用。
为了能够支持image[x][y][z]
,image[x][y]
需要返回一个对象或对需要支持数组运算符的对象的引用。
这是一个演示如何完成的示例程序。
免责声明请注意,这不是生产就绪代码。
#include <iostream>
#include <cassert>
struct Image
{
Image(unsigned int x,
unsigned int y,
unsigned int z) : x_(x), y_(y), z_(z), data(new unsigned char [x*y*z]) {}
// Need appropriate copy constructor and destructor.
// Helper classes to support the 3D array operator syntax.
struct image_2
{
image_2(Image& im, unsigned i, unsigned j) : im_(im), i_(i), j_(j) {}
unsigned char& operator[](unsigned k)
{
assert( k < im_.z_ );
unsigned int index = i_*im_.y_*im_.z_ + j_*im_.z_ + k;
return im_.data[index];
}
Image& im_;
unsigned int i_;
unsigned int j_;
};
struct image_1
{
image_1(Image& im, unsigned i) : im_(im), i_(i) {}
image_2 operator[](unsigned int j)
{
assert( j < im_.y_ );
return image_2(im_, i_, j);
}
Image& im_;
unsigned int i_;
};
// The toplevel array operator
image_1 operator[](unsigned i)
{
assert( i < x_ );
return image_1(*this, i);
}
unsigned x_;
unsigned y_;
unsigned z_;
unsigned char* data;
};
int main()
{
unsigned int x = 5;
unsigned int y = 5;
unsigned int z = 3;
Image im(5, 5, 3);
for ( unsigned int i = 0; i < x; ++i )
{
for ( unsigned int j = 0; j < y; ++j )
{
for ( unsigned int k = 0; k < z; ++k )
{
// Set some arbitrary value
im[i][j][k] = (i+1) + (j+1)*5 + (k+1)*5;
// Get the value
std::cout << (int)im[i][j][k] << " ";
}
std::cout << std::endl;
}
}
}
输出:
11 16 21
16 21 26
21 26 31
26 31 36
31 36 41
12 17 22
17 22 27
22 27 32
27 32 37
32 37 42
13 18 23
18 23 28
23 28 33
28 33 38
33 38 43
14 19 24
19 24 29
24 29 34
29 34 39
34 39 44
15 20 25
20 25 30
25 30 35
30 35 40
35 40 45