如何通过cimg获取RGB值?

7
CImg<unsigned char> src("image.jpg");
int width = src.width();
int height = src.height();
unsigned char* ptr = src.data(10,10); 

我如何从ptr中获取rgb

4个回答

7

在Ubuntu 10.04上测试,使用手工制作的3x3 RGB图像test.png

sudo apt-get install cimg-dev

源文件cimg_test.cpp

#include <iostream>
using namespace std;

#include <CImg.h>
using namespace cimg_library;

int main()
{
    CImg<unsigned char> src("test.png");
    int width = src.width();
    int height = src.height();
    cout << width << "x" << height << endl;
    for (int r = 0; r < height; r++)
        for (int c = 0; c < width; c++)
            cout << "(" << r << "," << c << ") ="
                 << " R" << (int)src(c,r,0,0)
                 << " G" << (int)src(c,r,0,1)
                 << " B" << (int)src(c,r,0,2) << endl;
    return 0;
}

编译并运行:

g++ cimg_test.cpp -lX11 -lpthread -o cimg_test
./cimg_test 3x3 (0,0) = 红0 绿0 蓝0 (0,1) = 红255 绿0 蓝0 (0,2) = 红0 绿255 蓝0 (1,0) = 红0 绿0 蓝255 (1,1) = 红128 绿128 蓝128 (1,2) = 红0 绿0 蓝128 (2,0) = 红128 绿0 蓝0 (2,1) = 红0 绿128 蓝0 (2,2) = 红255 绿255 蓝255

它可以工作。


@wamp:src(c,r,0,0)是您的灰度图像(r,c)像素的0-255值。 - Vanni Totaro
1
(int)的显式调用在我的应用程序中非常关键。感谢您提供这个答案! - so860
1
将近11年后...欢迎,@so860! :D - Vanni Totaro

4
CImg文档的第34页的6.13部分和第120页的8.1.4.16部分可以看出,data方法似乎可以接受四个参数:x、y、z和c。
T* data(const unsigned int x, const unsigned int y = 0, 
        const unsigned int z = 0, const unsigned int c = 0)

...其中c代表颜色通道。如果您的图像确实是RGB图像,则在给定的x,y位置使用0、1或2的值将为您提供红色、绿色和蓝色组件。

例如:

unsigned char *r = src.data(10, 10, 0, 0);
unsigned char *g = src.data(10, 10, 0, 1);
unsigned char *b = src.data(10, 10, 0, 2);

(但这只是一个猜测!)

编辑:

看起来CImg还有一个operator(),工作方式类似:

unsigned char r = src(10, 10, 0, 0);

2
你尝试过使用operator()吗?例如:unsigned char r = src(10,10,0,0); - Nate Kohl
这真的取决于你的图像,但是r、g和b通道被分开,因此读取一个通道将获得红色值(即,使用jpg图像的通道0),通道1将获得绿色值,通道2将获得蓝色值...文档中有一个使用浮点图像的示例,在8.1.4.9节中...将浮点数更改为无符号字符即可...以下是一个示例:unsigned char r = src.data(10,10,0,0); unsigned char g = src.data(10,10,0,1); unsigned char b = src.data(10,10,0,2); - Jay Kramer
@wamp:我猜灰度图像每个像素只有一个数据通道,你可以通过与访问RGB图像的“红色”分量完全相同的方式来访问该值。例如:char v = src(10, 10, 0, 0); - Nate Kohl
如何使用cimg确定图像是RGB还是灰度图像? - user198729
@user198729:看起来spectrum方法返回颜色通道的数量。因此,int numChannels = src.spectrum();可能会将numChannels设置为3,用于RGB图像,而对于灰度图像,它可能是1。 - Nate Kohl

2
访问数据最简单的方式是使用()运算符:
unsigned char r = img(10,10,0,0);
unsigned char g = img(10,10,0,1);
unsigned char b = img(10,10,0,2);

您可能感到困惑,因为CImg以非交错方式存储原始数据。即,您的原始数据存储为R1, R2, ..., G1, G2, ..., B1, B2, ...而不是R1, G1, B1, R2, G2, B2, ...。请参见:http://cimg.eu/reference/group__cimg__storage.html .data()只返回指针,因此要像上面那样直接访问数据,您需要执行以下操作:
CImg<unsigned char> src("image.jpg");
int width = src.width();
int height = src.height();
unsigned char* ptr = src.data(10,10);
unsigned char r = ptr[0];
unsigned char g = ptr[0+width*height];
unsigned char b = ptr[0+2*width*height];

-1

@wamp:我不知道CImg,但在RGB中的灰度图像具有:

R = G = B

而在CMYK中:

C = M = Y = 0

K = 亮度

所以你甚至不需要一个函数来实现这个...


这是不正确的。虽然你可以将图像保存为仅使用R=G=B的RGB格式,但你将使用比存储图像所需数据多3倍的数据。这就是为什么有一种灰度格式用于图像,只保存一个通道。 - Darrel Hoffman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接