use*_*rfi 2 c++ image-processing
我有一个类图像,其中包含一个名为buffer的成员,一个存储图像像素的unsigned char矢量.我想把这个缓冲区作为一个矩阵处理.我想像img [i] [j]那样访问缓冲区,但我不知道怎么做?有谁能建议我一个解决方案?
这是我的试探性的:
unsigned char * &Image::operator[](int i) {
return buffer[ rows+i ]
}
Run Code Online (Sandbox Code Playgroud)
我读了这篇文章然后我认为这是可能的.我的课就是这样的:
class Image {
private:
unsigned char * buffer;
int buf_size;
int rows;
int cols;
Phisical_img_manager phisical_img_manager;
const char * in_img_filename;
public:
unsigned char * & operator[](int i);
Image(const char * in_img_filename);
unsigned char * get_buffer();
int get_cols();
int get_rows();
};
Run Code Online (Sandbox Code Playgroud)
您可以按行主要顺序执行以下操作:
class Image {
int rows, cols;
unsigned char *buffer;
public:
// ...
unsigned char* operator[](int const i) { return &(buffer[i * cols]); }
unsigned char const* operator[](int const i) const { return &(buffer[i * cols]); }
};
Run Code Online (Sandbox Code Playgroud)
您的缓冲区是一个连续的内存块.大小N = rows * cols.
然而,图像的概念是以2D构造/矩阵排列的一组像素:
我们想要的是将这个2D构造安排在计算机内存中的1D缓冲区中.我们可以通过两种方式做到这一点:
在行优先顺序我们店后,其他的像一个的每一行.也就是说,对于以下尺寸的2x2图像
相应的缓冲存储器看起来像:
在列主要顺序中,我们一个接一个地存储图像的每一列.也就是说,相同大小的2x2图像的缓冲区存储看起来像:

支持多维数组的编程语言要么为它们实现行主要或列主要存储顺序.在C和C++中,使用行主要顺序.
在上面显示的代码中,我们实现了行主顺序.我们定义了一个重载的下标运算符,它将i我们想要访问的行索引(例如)作为输入.将其i与列数相乘,我们得到ith图像中行的起始索引.我们返回该特定地址中元素的地址.此地址标记原始缓冲区的子数组的开始以及ith行的开头.为了进一步说明,请参阅以下代码示例:
Image I(2, 3);
I[1][2] = 42;
Run Code Online (Sandbox Code Playgroud)
呼叫I[1][2] = 42就像呼叫:
(I.operator[](1))[2];
Run Code Online (Sandbox Code Playgroud)
sub-call I.operator[](1)返回指向图像第二行开始的地址的指针.然后我们将此返回的指针用作普通的动态分配数组.在这个具体的例子中,我们向这个指针添加2(即,这是做什么[2]),因此我们得到行的元素,该行位于行的第一个元素之后的2个位置(即,第二行的第三个元素)图片).
如果您的编译器支持C++ 11和智能指针,您可以执行以下方案以避免内存管理.此外,我会重载,operator()(std::size_t const, std::size_t const)因为上面的重载你暴露缓冲区,因此你正在伤害封装:
class Image {
int rows, cols;
std::unique_ptr<unsigned char[]> buffer;
public:
Image(int const rows_ = 0, int const cols_ = 0)
: rows(rows_), cols(cols_), buffer(new unsigned char[rows * cols]) {}
Image(Image const &other)
: rows(other.rows), cols(other.cols), buffer(new unsigned char[rows * cols]) {
std::copy(other.buffer.get(), other.buffer.get() + (rows * cols), buffer.get());
}
Image(Image &&other)
: rows(other.rows), cols(other.cols), buffer(std::move(other.buffer)) {
other.rows = 0;
other.cols = 0;
}
unsigned char& operator()(std::size_t const i, std::size_t const j) {
return buffer[cols * i + j];
}
unsigned char const& operator()(std::size_t const i, std::size_t const j) const {
return buffer[cols * i + j];
}
Image& operator=(Image const &other) {
rows = other.rows;
cols = other.cols;
buffer.reset(new unsigned char[rows * cols]);
std::copy(other.buffer.get(), other.buffer.get() + (rows * cols), buffer.get());
return *this;
}
Image& operator=(Image &&other) {
rows = other.rows;
cols = other.cols;
buffer.swap(other.buffer);
other.rows = 0;
other.cols = 0;
return *this;
}
// ...
};
Run Code Online (Sandbox Code Playgroud)