tags:

views:

709

answers:

4

Hello, 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.

A: 

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
+3  A: 

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 R*n* G*n* and B*n* 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
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
@reinier: That might be true, assuming no inlining. I've added an explicit nested-for snippet to show that, too. Thanks.
unwind
A: 

hey - lets say i have something like the code unwind wrote above and i am reading each pixel, and getting each pixel's rgb. i need then to convert my 24bits triplet into 16bit ARGB triplet . there is this defined function i use but i do not get the wanted result .. can you help me ?

#define     ARGB16(a, r, g, b)   ( ((a) << 15) | (r)|((g)<<5)|((b)<<10))

Macro to convert 5 bit r g b components plus 1 bit alpha into a single 16 bit ARGB triplet.

seven
+2  A: 

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 puxel 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.

Mark Bessey