如何在 CImg 中获取像素数据作为 matrix/vector?
How to get pixel data as a matrix/vector in CImg?
我需要读取灰度 png 图像,以便将像素值 (0-255) 存储在无符号字符的二维矩阵中。
目前我在 C++ 中使用 CImg,它成功读取了图像,但我不知道如何从 CImg 容器中获取像素数据。
我能做到:
CImg<unsigned char> image("img1.png");
unsigned char* img1 = image.data();
但它给了我一个 char*,根据文档,它是 "the pointer to the first value of the image",但我不知道如何处理它,或者如何访问其他值。
对此有什么建议吗?
谢谢,
大卫
确实有很多可能性。
您可以使用当前的方法并只遍历原始像素数组:
CImg<unsigned char> image("img1.png");
unsigned char* img1 = image.data();
for(int i=0; i < image.size(); i++) {
logger_->info("*img1 value: {}", *(img1+i));
}
根据docs:
Size() returns width()*height()*depth()*spectrum(), i.e. the total number of values of type T in the pixel buffer of the image instance
所以你也可以直接使用这些维度:
像这样:
CImg<unsigned char> image("img1.png");
unsigned char* img1 = image.data();
for(int i=0; i < image.width()*image.height()*image.depth()*image.spectrum(); i++) {
logger_->info("*img1 value: {}", *(img1+i));
}
这当然允许您编写分别遍历每个维度的嵌套循环。
如果你不喜欢遍历原始数组,你可以使用迭代器:
CImg<unsigned char> image("img1.png");
unsigned char* img1 = image.data();
for (CImg<unsigned char>::iterator it = image.begin(); it < image.end(); ++it) {
logger_->info("it value: {}", *it);
}
或者,如果您想尝试其他方法,请查看文档,我提供的示例并不详尽。
不确定为什么要将 CImg structure/class 中的所有数据复制到另一个 2D 数组,而您仍然可以完全像那样访问它。所以,如果你想要位置 [x,y] 处的像素,只需使用:
img(x,y)
这是转储图像的完整程序 - 访问内部循环中的单个像素:
#include <iostream>
#include <cstdlib>
#define cimg_display 0
#include "CImg.h"
using namespace cimg_library;
using namespace std;
int main() {
CImg<unsigned char> img("test.pgm");
// Get width, height, number of channels
int w=img.width();
int h=img.height();
int c=img.spectrum();
cout << "Dimensions: " << w << "x" << h << " " << c << " channels" <<endl;
// Dump all pixels
for(int y=0;y<h;y++){
for(int x=0;x<w;x++){
cout << y << "," << x << " " << (int)img(x,y) << endl;
}
}
}
我使用了这个测试图像——它是 5x3 PGM(便携式灰度图),所以你可以很容易地看到像素值,但它与 PNG 图像是一样的:
P2
5 3
255
0 1 2 3 4
10 11 12 13 14
100 101 102 103 104
这是输出,您可以看到它与图像匹配:
Dimensions: 5x3 1 channels
0,0 0
0,1 1
0,2 2
0,3 3
0,4 4
1,0 10
1,1 11
1,2 12
1,3 13
1,4 14
2,0 100
2,1 101
2,2 102
2,3 103
2,4 104
我需要读取灰度 png 图像,以便将像素值 (0-255) 存储在无符号字符的二维矩阵中。 目前我在 C++ 中使用 CImg,它成功读取了图像,但我不知道如何从 CImg 容器中获取像素数据。
我能做到:
CImg<unsigned char> image("img1.png");
unsigned char* img1 = image.data();
但它给了我一个 char*,根据文档,它是 "the pointer to the first value of the image",但我不知道如何处理它,或者如何访问其他值。
对此有什么建议吗?
谢谢, 大卫
确实有很多可能性。
您可以使用当前的方法并只遍历原始像素数组:
CImg<unsigned char> image("img1.png"); unsigned char* img1 = image.data(); for(int i=0; i < image.size(); i++) { logger_->info("*img1 value: {}", *(img1+i)); }
根据docs:
Size() returns width()*height()*depth()*spectrum(), i.e. the total number of values of type T in the pixel buffer of the image instance
所以你也可以直接使用这些维度:
像这样:
CImg<unsigned char> image("img1.png"); unsigned char* img1 = image.data(); for(int i=0; i < image.width()*image.height()*image.depth()*image.spectrum(); i++) { logger_->info("*img1 value: {}", *(img1+i)); }
这当然允许您编写分别遍历每个维度的嵌套循环。
如果你不喜欢遍历原始数组,你可以使用迭代器:
CImg<unsigned char> image("img1.png"); unsigned char* img1 = image.data(); for (CImg<unsigned char>::iterator it = image.begin(); it < image.end(); ++it) { logger_->info("it value: {}", *it); }
或者,如果您想尝试其他方法,请查看文档,我提供的示例并不详尽。
不确定为什么要将 CImg structure/class 中的所有数据复制到另一个 2D 数组,而您仍然可以完全像那样访问它。所以,如果你想要位置 [x,y] 处的像素,只需使用:
img(x,y)
这是转储图像的完整程序 - 访问内部循环中的单个像素:
#include <iostream>
#include <cstdlib>
#define cimg_display 0
#include "CImg.h"
using namespace cimg_library;
using namespace std;
int main() {
CImg<unsigned char> img("test.pgm");
// Get width, height, number of channels
int w=img.width();
int h=img.height();
int c=img.spectrum();
cout << "Dimensions: " << w << "x" << h << " " << c << " channels" <<endl;
// Dump all pixels
for(int y=0;y<h;y++){
for(int x=0;x<w;x++){
cout << y << "," << x << " " << (int)img(x,y) << endl;
}
}
}
我使用了这个测试图像——它是 5x3 PGM(便携式灰度图),所以你可以很容易地看到像素值,但它与 PNG 图像是一样的:
P2
5 3
255
0 1 2 3 4
10 11 12 13 14
100 101 102 103 104
这是输出,您可以看到它与图像匹配:
Dimensions: 5x3 1 channels
0,0 0
0,1 1
0,2 2
0,3 3
0,4 4
1,0 10
1,1 11
1,2 12
1,3 13
1,4 14
2,0 100
2,1 101
2,2 102
2,3 103
2,4 104