https://github.com/6by9/RPiTest/tree/master/dcraw
I played with raspiraw and dcraw, and wanted to get a better understanding of the raw bayer data. The Bayer pattern of OV5647 chip is described here, it is BG/GR:
http://cdn.sparkfun.com/datasheets/Dev/ ... df#page=25
I took a 640*480 frame dumped from raspiraw @60fps, and compared 4 conversions from that:

Here I scaled each pixel by factor of two in x and y direction.
For top left I really used blue/green/red pixels where OV5647 B/G/R pixels are.
Top right is result of postprocessing with hacked dcraw.
Bottom left is generated with below program "rawvga", which discards each 5th byte (conatining least precision 2 bits of 10 bit representation) and uses some luminosity mapping for blue, green and red.
Bottom right is generated similar, just ignoring the color and using the high 8 bit as grey values:
Code: Select all
$ gcc rawvga.c -Wall -pedantic -o rawvga
$ ./rawvga -c o7b.raw > outc.ppm
$ ./rawvga -g o7b.raw > outg.ppm
$ ./rawvga -l o7b.raw > outl.ppm
$

This is top right full image, dcraw converted:

This is bottom left full image (-l):

And this bottom right full image (-g):

The best generated with rawvga (that only can handle 640x480 frames) is bottom right (-g). The reason for writing rawvga was to get an understanding, not to replace dcraw.
On one of my robots I have added a tilt servo Raspberry camera, mainly to help with linefollowing:

This is a sample 240x320 image taken with a cheap USB camera much earlier, but that is what I want to process, do feature extraction (where does the line go) and feed that into PID controller making robot follow the line (the bottom of image is "present", middle is "near future", and top is "far future"):

Until yesterday I had the plan to use a raspivid/gstreamer pipeline and write a gstreamer plugin in order to proces the frames. All has become much simpler, I can now use raspiraw, eliminating writing to SD card, and do frame processing in callback routine called every 11.1ms in case of 90fps (which is every 5.5cm for 5m/s robot speed). This is where to find the (-g) grey value of pixel (x,y) in frame:
Code: Select all
[0x8000 + ] y*(640*5/4) + 5*(x>>2) + (x%4)
My son told me that edge detection in general is not an easy thing (I hope that it will be with the line following frames I get), and I definitely should have a look on OpenCV (wich seems to be capable of dealing with 640x480 @90fps from Raspberry camera).
I will do that, but try my own feature extraction as well. Yes, a VGA frame has 300KB of data, but on the other hand there are 11 million clock cycles before the next frame callback gets triggered ...
Hermann.
"rawvga" can handle raw data, with or without header:
Code: Select all
/* rawvga converts raspiraw VGA resolution .raw to .ppm/.pgm without dcraw
A) https://www.johndcook.com/blog/2009/08/24/algorithms-convert-color-grayscale
*/
#include <stdio.h>
#include <string.h>
#include <assert.h>
int hdr=0x8000, siz=640*480*5/4, shl=4, col=0;
char M[2][2]={{'B','G'},{'G','R'}};
int L[17] = { 1/*B*/, 0,0,0,0, 10/*G*/, 0,0,0,0,0,0,0,0,0,0, 3/*R*/}; /* A) */
void out(char C, unsigned char u) {
unsigned U = u * (col ? 1 : L[C-'B']); U <<= shl; if (U>255) { U=255; }
if (!col) {
putchar(U);
} else {
switch (C) {
case 'B': putchar(0); putchar(0); putchar(U); break;
case 'G': putchar(0); putchar(U); putchar(0); break;
case 'R': putchar(U); putchar(0); putchar(0); break;
}
}
}
int main(int argc, char *argv[]) {
FILE *src; int i,j;
if (argc!=3) { fprintf(stderr,"%s -c|-g|-l file.raw\n",argv[0]); return(1); }
if (strcmp(argv[1], "-c")==0) { printf("P6"); col=1; }
else if (strcmp(argv[1], "-g")==0) { printf("P5"); L['G'-'B']=L['R'-'B']=1; }
else if (strcmp(argv[1], "-l")==0) { printf("P5"); shl=1; }
else { assert( !"-c|-g|-l needed"); }
assert( src = fopen(argv[2],"rb") );
fseek(src,0,SEEK_END); if (ftell(src) != hdr+siz) { hdr=0; }
assert(ftell(src) == hdr+siz); fseek(src, hdr, 0);
printf("\n640 480\n255\n");
for(i=0; i<480; ++i) {
for(j=0; j<640; ++j) {
out(M[i%2][j%2], fgetc(src)); if (j%4 == 3) { fgetc(src); }
}
}
return fclose(src);
}