On Thu, Jan 11, 2007 at 10:47:10PM +0100, Laurent Pinchart wrote:
> Hi Luca,
> 
> > This is function in C to convert from Bayer to RGB24 pixel formats.
> > The linear interpolation is more efficient than the ones I saw in other
> > similar functions on internet, as the code omits "if-then-else" conditional
> > statements in the loops.
> 
> Thanks for the code. This will be usefull for all the users who are 
> interested 
> in raw image processing. There seem to be quite a lot of them lately :-)
 
That is easy to explain: Those interested in raw processing are looking
for a webcam that can do USB 2.0 and is supported on Linux. Not that
much choice. ;)

Btw, my take on Bayer->RGB processing: (attached)

-- 
Vojtech Pavlik
Director SuSE Labs
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <string.h>
#include <sys/select.h>

#define u8 uint8_t
#define u16 uint16_t
#define u32 uint32_t

static uint8_t rgb[640*480*3];

#define R(x,y) pRGB24[0 + 3 * ((x) + 640 * (y))]
#define G(x,y) pRGB24[1 + 3 * ((x) + 640 * (y))]
#define B(x,y) pRGB24[2 + 3 * ((x) + 640 * (y))]

#define Bay(x,y) pBay[(x) + 640 * (y)]

static void bayer_copy(u8 *pBay, u8 *pRGB24, int x, int y)
{

        G(x + 0, y + 0) = Bay(x + 0, y + 0);
        G(x + 1, y + 1) = Bay(x + 1, y + 1);
        G(x + 0, y + 1) = G(x + 1, y + 0) = ((u32)Bay(x + 0, y + 0) + 
(u32)Bay(x + 1, y + 1)) / 2;
        R(x + 0, y + 0) = R(x + 1, y + 0) = R(x + 1, y + 1) = R(x + 0, y + 1) = 
Bay(x + 0, y + 1);
        B(x + 1, y + 1) = B(x + 0, y + 0) = B(x + 0, y + 1) = B(x + 1, y + 0) = 
Bay(x + 1, y + 0);
}

static void bayer_bilinear(u8 *pBay, u8 *pRGB24, int x, int y)
{
        R(x + 0, y + 0) = ((u32)Bay(x + 0, y + 1) + (u32)Bay(x + 0, y - 1)) / 2;
        G(x + 0, y + 0) = Bay(x + 0, y + 0);
        B(x + 0, y + 0) = ((u32)Bay(x - 1, y + 0) + (u32)Bay(x + 1, y + 0)) / 2;

        R(x + 0, y + 1) = Bay(x + 0, y + 1);
        G(x + 0, y + 1) = ((u32)Bay(x + 0, y + 0) + (u32)Bay(x + 0, y + 2)
                         + (u32)Bay(x - 1, y + 1) + (u32)Bay(x + 1, y + 1)) / 4;
        B(x + 0, y + 1) = ((u32)Bay(x + 1, y + 0) + (u32)Bay(x - 1, y + 0)
                         + (u32)Bay(x + 1, y + 2) + (u32)Bay(x - 1, y + 2)) / 4;

        R(x + 1, y + 0) = ((u32)Bay(x + 0, y + 1) + (u32)Bay(x + 2, y + 1)
                         + (u32)Bay(x + 0, y - 1) + (u32)Bay(x + 2, y - 1)) / 4;
        G(x + 1, y + 0) = ((u32)Bay(x + 0, y + 0) + (u32)Bay(x + 2, y + 0)
                         + (u32)Bay(x + 1, y - 1) + (u32)Bay(x + 1, y + 1)) / 4;
        B(x + 1, y + 0) = Bay(x + 1, y + 0);

        R(x + 1, y + 1) = ((u32)Bay(x + 0, y + 1) + (u32)Bay(x + 2, y + 1)) / 2;
        G(x + 1, y + 1) = Bay(x + 1, y + 1);
        B(x + 1, y + 1) = ((u32)Bay(x + 1, y + 0) + (u32)Bay(x + 1, y + 2)) / 2;
}


static void bayer_to_rgb24(u8 *pBay, u8 *pRGB24)
{
        int i, j;

        for (i = 0; i < 640; i += 2)
                for (j = 0; j < 480; j += 2)
                        if (i == 0 || j == 0 || i == 640 - 2 || j == 480 - 2)
                                bayer_copy(pBay, pRGB24, i, j);
                        else
                                bayer_bilinear(pBay, pRGB24, i, j);
}

void writepnm(uint8_t *data, int i)
{
        FILE *fd;
        char name[32];
        sprintf(name, "p5-%04d.pnm", i);
        fd = fopen(name, "w");
        fputs("P6\n", fd);
        fputs("640 480\n", fd);
        fputs("255\n", fd);
        fwrite(data, 640*480*3, 1, fd);
        fclose(fd);     
}

int main(void)
{
        int fdi;
        u8 *ibot;

        if ((fdi = open("bayer.raw", O_RDONLY)) < 0) {
                perror("open");
                return -1;
        }

        if ((ibot = mmap(NULL, 640 * 480 + 640*4, PROT_READ, MAP_SHARED, fdi, 
0)) == MAP_FAILED) {
                perror("mmap");
                return -1;
        }

        bayer_to_rgb24(ibot, rgb);
        writepnm(rgb, 0);

        close(fdi);

        return 0;
}
_______________________________________________
Linux-uvc-devel mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/linux-uvc-devel

Reply via email to