7

I want to read the RGB values for each pixel from a raw image. Can someone tell me how to achieve this? Thanks for help!

the format of my raw image is .CR2 which come from camera.

  • 2
    You need to specify how the "raw image" is represented and what format it is. – sharptooth Oct 08 '09 at 07:32
  • 2
    Define "raw image". Is it an image file? If so, what sort of file? Or are you trying to do a screen capture? Edit your question to add the details. – Artelius Oct 08 '09 at 07:33
  • 1
    What format is your "raw" image. Is it a bitmap or an image file taken from a camera perhaps? – ChrisBD Oct 08 '09 at 08:01

3 Answers3

10

Assuming the image is w * h pixels, and stored in true "packed" RGB format with no alpha component, each pixel will require three bytes.

In memory, the first line of the image might be represented in awesome ASCII graphics like this:

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

Here, each Rn Gn and Bn represents a single byte, giving the red, green or blue component of pixel n of that scanline. Note that the order of the bytes might be different for different "raw" formats; there's no agreed-upon world standard. Different environments (graphics cards, cameras, ...) do it differently for whatever reason, you simply have to know the layout.

Reading out a pixel can then be done by this function:

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];
}

Notice how the height of the image is not needed for this to work, and how the function is free from bounds-checking. A production-quality function might be more armor-plated.

Update If you're worried this approach will be too slow, you can of course just loop over the pixels, instead:

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. */
  }
}
unwind
  • 391,730
  • 64
  • 469
  • 606
  • If he only needs to query 1 pixel, your function is fine. If however he needs to process all pixels, this function is not the way to go since it's too slow (function overhead + 3 multiplications for every pixel) – Toad Oct 08 '09 at 08:12
  • @reinier: That might be true, assuming no inlining. I've added an explicit nested-for snippet to show that, too. Thanks. – unwind Oct 08 '09 at 08:33
  • @unwind I have a jpg file, I used imagemagick and applied threshold, and that changes all the pixels above the threshold value as black and others white. Now, I want to check for each pixel, if it is black or white. Will the above method work. What will be the value for red , green and blue? 255? – Kraken Apr 15 '13 at 19:58
  • @unwind Also, how do I specify my file. If I have my file as "abc.jpg" then where does that info go? Thanks. – Kraken Apr 15 '13 at 20:02
6

None of the methods posted so far are likely to work with a camera "raw" file. The file formats for raw files are proprietary to each manufacturer, and may contain exposure data, calibration constants, and white balance information, in addition to the pixel data, which will likely be in a packed format where each pixel can takes up more than one byte, but less than two.

I'm sure there are open-source raw file converter programs out there that you could consult to find out the algorithms to use, but I don't know of any off the top of my head.


Just thought of an additional complication. The raw file does not store RGB values for each pixel. Each pixel records only one color. The other two colors have to be interpolated from heighboring pixels. You'll definitely be better off finding a program or library that works with your camera.

Krunal Sonparate
  • 1,122
  • 10
  • 29
Mark Bessey
  • 19,598
  • 4
  • 47
  • 69
  • To add to the footnote, each pixel in a camera [has a color filter (e.g. a bayer pattern)](https://en.wikipedia.org/wiki/Bayer_filter). Hence each pixel is really only R, G or B. Often cameras have their own image signal processor (ISP) which does the color interpolation mentioned by Mark. – Ralph Sep 23 '22 at 18:09
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.

fortran
  • 74,053
  • 25
  • 135
  • 175