Added bilinear debayer of GRBG16, not yet tested

master
Stefan Jahn 3 years ago
parent 59c59e557a
commit 032cbdc0cf

@ -8,7 +8,7 @@ OBJECTS := $(OBJECTS) gui.oo main.oo \
video.oo videoframe.oo \
videodev.oo videodev-v4l2.oo videodev-dumpfile.oo \
convert.oo filter.oo detect.oo histogram.oo \
json.oo configuration.oo ser.oo dng.oo
json.oo configuration.oo ser.oo dng.oo debayer.oo
DISTNAME=simpleskycam-$(VERSION)
DEPENDFILE=.depend

@ -10,6 +10,7 @@
#include "gui.h"
#include "video.h"
#include "configuration.h"
#include "debayer.h"
uint32_t convert_pixelformats [] = {
V4L2_PIX_FMT_MJPEG,
@ -346,59 +347,8 @@ int Convert (ConvertData *cdata, VideoFrame *dest, unsigned char *ptrsrc, int sr
break;
case (V4L2_PIX_FMT_SGRBG16):
// GG RR GG RR
// BB GG BB GG
// GG RR GG RR
// BB GG BB GG
uint16_t t;
for (ys = 0, yd = 0; ys < (signed int)srch; ys++) {
for (xs = 0, xd = 0; xs < (signed int)srcw; xs++) {
/* read the pixel */
t = (*((uint16_t*)ptrsrc)) & 0x00FF;
ptrsrc += 2;
if (xs & 1) {
if (ys & 1) {
b = 0;
g = t;
r = 0;
}
else {
b = t;
g = 0;
r = 0;
}
}
else {
if (ys & 1) {
b = 0;
g = t;
r = 0;
}
else {
b = 0;
g = 0;
r = t;
}
}
/* only paint the image if the source is within the destination */
if (xd < dest->w) {
/* set the pixel */
*(ptrdst++) = b;
*(ptrdst++) = g;
*(ptrdst++) = r;
xd++;
}
}
/* if the source image is too small ignore the other places.. */
if (xd < dest->w)
ptrdst += 3 * (dest->w - xd);
yd++;
}
//debayer_grbg16_simple ((uint16_t *)ptrsrc, srcw, srch, ptrdst, dest->w, dest->h);
debayer_grbg16_bilinear ((uint16_t *)ptrsrc, srcw, srch, ptrdst, dest->w, dest->h);
break;
case (V4L2_PIX_FMT_UYVY):

@ -0,0 +1,188 @@
#include <stdint.h>
/*
The function converts a 16bit GRBG 2x2 CFA coded image into an 8bit
RGB image by setting the missing RGB values to zero.
*/
void debayer_grbg16_simple (uint16_t * src, int src_w, int src_h,
uint8_t * dst, int dst_w, int dst_h) {
// GG RR
// BB GG
uint16_t t;
uint8_t r, g, b;
int ys, yd, xs, xd;
for (ys = 0, yd = 0; ys < src_h; ys++) {
for (xs = 0, xd = 0; xs < src_w; xs++) {
/* read the pixel but only the lower 8bit */
t = *(src++) & 0x00FF;
if (xs & 1) {
if (ys & 1) {
// lower right green pixel
b = 0; g = t; r = 0;
} else {
// upper right red pixel
b = 0; g = 0; r = t;
}
} else {
if (ys & 1) {
// lower left blue pixel
b = 0; g = t; r = 0;
} else {
// upper left green pixel
b = 0; g = t; r = 0;
}
}
/* only paint the image if the source is within the destination */
if (xd < dst_w) {
/* set the pixel */
*(dst++) = b;
*(dst++) = g;
*(dst++) = r;
xd++;
}
}
/* if the source image is too small ignore the other places */
if (xd < dst_w)
dst += 3 * (dst_w - xd);
yd++;
}
}
// macros to make code better readable
#define CE (*(src))
#define UP (*(src-src_w))
#define DN (*(src+src_w))
#define LE (*(src-1))
#define RI (*(src+1))
#define UPLE (*(src-src_w-1))
#define UPRI (*(src-src_w+11))
#define DNLE (*(src+src_w-1))
#define DNRI (*(src+src_w+11))
#define STORE *(dst++) = r; *(dst++) = g; *(dst++) = b; src++;
/*
The function converts a 16bit GRBG 2x2 CFA coded image into an 8bit
RGB image by bilinear interpolation.
*/
void debayer_grbg16_bilinear (uint16_t * src, int src_w, int src_h,
uint8_t * dst, int dst_w, int dst_h) {
// GG RR GG RR
// BB GG BB GG
// GG RR GG RR
// BB GG BB GG
uint8_t r, g, b;
int xs, ys;
// start with upper left pixel (green)
r = RI;
g = CE;
b = DN;
STORE;
// upper first line, starts with RR GG RR ...
for (xs = 1; xs < src_w - 1; xs+=2) {
// red pixel
r = CE;
g = (LE + RI + DN) / 3;
b = (DNLE + DNRI) / 2;
STORE;
// green pixel
r = (LE + RI) / 2;
g = CE;
b = DN;
STORE;
}
// upper right pixel (red)
r = CE;
g = (DN + LE) / 2;
b = DNLE;
STORE;
// got through the "body" of the image
for (ys = 1; ys < src_h - 1; ys+=2) {
// every second line with BB GG BB GG (start at 2nd line)
// left hand pixel (blue)
r = (UPRI + DNRI) / 2;
g = (UP + DN + RI) / 3;
b = CE;
STORE;
for (xs = 1; xs < src_w - 1; xs+=2) {
// green pixel
r = (UP + DN) / 2;
g = CE;
b = (LE + RI) / 2;
STORE;
// blue pixel
r = (UPLE + UPRI + DNLE + DNRI) / 4;
g = (LE + RI + UP + DN) / 4;
b = CE;
STORE;
}
// last pixel in line (green)
r = (UP + DN) / 2;
g = CE;
b = LE;
STORE;
// every second line with GG RR GG RR ... (start at 3rd line)
// left hand pixel (green)
r = RI;
g = CE;
b = (UP + DN) / 2;
STORE;
for (xs = 1; xs < src_w - 1; xs+=2) {
// red pixel
r = CE;
g = (LE + RI + UP + DN) / 4;
b = (UPLE + UPRI + DNLE + DNRI) / 4;
STORE;
// green pixel
r = (LE + RI) / 2;
g = CE;
b = (UP + DN) / 2;
}
// last pixel in line (red)
r = CE;
g = (UP + DN + LE) / 3;
b = (UPLE + DNLE) / 2;
STORE;
}
// bottom left pixel
r = UPRI;
g = (UP + RI) / 2;
b = CE;
STORE;
// last line starting with GG BB GG ...
for (xs = 1; xs < src_w - 1; xs+=2) {
// green pixel
r = UP;
g = CE;
b = (LE + RI) / 2;
STORE;
// blue pixel
r = (UPLE + UPRI) / 2;
g = (LE + UP + RI) / 2;
b = CE;
STORE;
}
// bottom right pixel (green)
r = UP;
g = CE;
b = LE;
STORE;
}

@ -0,0 +1,11 @@
#ifndef _DEBAYER_H_
#define _DEBAYER_H_
void debayer_grbg16_simple (uint16_t * src, int src_w, int src_h,
uint8_t * dst, int dst_w, int dst_h);
void debayer_grbg16_bilinear (uint16_t * src, int src_w, int src_h,
uint8_t * dst, int dst_w, int dst_h);
#endif
Loading…
Cancel
Save