6

我想从原始图像中读取每个像素的 RGB 值。有人可以告诉我如何实现这一目标吗?感谢帮助!

我的原始图像的格式是来自相机的 .CR2。

4

3 回答 3

9

假设图像是 w * h 像素,并以没有 alpha 分量的真正“打包”RGB 格式存储,每个像素将需要三个字节。

在内存中,图像的第一行可能会以很棒的 ASCII 图形表示,如下所示:

   R0 G0 B0 R1 G1 B1 R2 G2 B2 ... R(w-1) G(w-1) B(w-1)

这里,每个 R n G n和 B n代表一个字节,给出了该扫描线像素n的红色、绿色或蓝色分量。请注意,不同“原始”格式的字节顺序可能不同;没有公认的世界标准。无论出于何种原因,不同的环境(显卡、相机等)都会有不同的表现,您只需要了解布局即可。

然后可以通过此函数读取一个像素:

typedef unsigned char byte;
void get_pixel(const byte *image, unsigned int w,
               unsigned int x,
               unsigned int y,
               byte *red, byte *green, byte *blue)
{
    /* Compute pointer to first (red) byte of the desired pixel. */
    const byte * pixel = image + w * y * 3 + 3 * x;
    /* Copy R, G and B to outputs. */
    *red = pixel[0];
    *green = pixel[1];
    *blue = pixel[2];
}

请注意如何不需要图像的高度来使其工作,以及该功能如何免于边界检查。一个生产质量的功能可能更加装甲。

更新如果您担心这种方法会太慢,您当然可以只循环像素,而不是:

unsigned int x, y;
const byte *pixel = /* ... assumed to be pointing at the data as per above */

for(y = 0; y < h; ++y)
{
  for(x = 0; x < w; ++x, pixel += 3)
  {
    const byte red = pixel[0], green = pixel[1], blue = pixel[2];

    /* Do something with the current pixel. */
  }
}
于 2009-10-08T08:00:11.717 回答
5

到目前为止发布的所有方法都不可能适用于相机“原始”文件。原始文件的文件格式是每个制造商专有的,除了像素数据外,还可能包含曝光数据、校准常数和白平衡信息,这些数据可能采用打包格式,每个像素可以占用多个像素字节,但少于两个。

我确信那里有开源的原始文件转换器程序,您可以查阅这些程序以找出要使用的算法,但我不知道有什么在我脑海中。


只是想到了一个额外的并发症。原始文件不存储每个像素的 RGB 值。每个像素只记录一种颜色。其他两种颜色必须从高像素内插。你肯定会更好地找到一个适用于你的相机的程序或库。

于 2009-10-29T07:05:43.297 回答
1

A RAW image is an uncompressed format, so you just have to point where your pixel is (skipping any possible header, and then adding the size of the pixel times the number columns times the number of row plus the number of the colum), and then read whatever binary data is giving a meaningful format to the layout of the data (with masks and shifts, you know).

That's the general procedure, for your current format you'll have to check the details.

于 2009-10-08T07:42:57.213 回答