camlibs/mars: mars_white_balance function added
git-svn-id: https://svn.code.sf.net/p/gphoto/code/trunk/libgphoto2@10989 67ed7778-7388-44ab-90cf-0a291f65f57c
This commit is contained in:
@@ -1,3 +1,10 @@
|
||||
2008-03-15 Theodore Kilgore <kilgota@auburn.edu>
|
||||
* mars.[c,h]: mars_white_balance() postprocessing function, based
|
||||
upon work with Amauri Magagna done for an Aox camera.
|
||||
* library.c: Added line to use mars_white_balance()
|
||||
* README.mars: Description of what mars_white_balance() does.
|
||||
|
||||
|
||||
2007-11-15 Theodore Kilgore <kilgota@auburn.edu>
|
||||
* library.c: Added Sakar no. 1638x Cyberpix
|
||||
* README.mars: Description of new camera added.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
MARS MR97310 STILLCAM DRIVER
|
||||
Copyright Theodore Kilgore <kilgota@auburn.edu> April, 2004. Latest revision
|
||||
of this README November 15, 2007.
|
||||
of this README March 15, 2008.
|
||||
|
||||
(Everything in libgphoto2/camlibs/mars is LGPL-licensed, including this README;
|
||||
see any of the source files for a more complete statement of the license.)
|
||||
@@ -228,6 +228,16 @@ you would like to see this file and it is not included for some reason in a
|
||||
"released" version of libgphoto2, then it can be found in the SVN source
|
||||
repository.
|
||||
|
||||
THE mars_white_balance() FUNCTION
|
||||
|
||||
This function first of all does what its name implies. It also re-computes a
|
||||
better gamma factor for the individual image, based upon internal
|
||||
characteristics detected in the image, and does color enhancement. If you do
|
||||
not like what it is doing, then you can turn it off by commenting out the line
|
||||
in library.c where it is called, but I expect that the user will not want to
|
||||
do that, because it seems to me that the image quality is much, much better.
|
||||
|
||||
|
||||
WARRANTY?
|
||||
|
||||
Absolutely none. Remember, I did not sell you this software. I have written
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <math.h>
|
||||
#include <bayer.h>
|
||||
#include <gamma.h>
|
||||
|
||||
@@ -298,8 +298,10 @@ get_file_func (CameraFilesystem *fs, const char *folder, const char *filename,
|
||||
if (compressed) {
|
||||
mars_decompress (data + 12, p_data, w, h);
|
||||
}
|
||||
else memcpy (p_data, data + 12, w*h);
|
||||
gamma_factor = (float)data[7]/128.;
|
||||
else memcpy (p_data, data + 12, w*h);
|
||||
gamma_factor = sqrt((float)data[7]/100.);
|
||||
if (gamma_factor <= .60)
|
||||
gamma_factor = .60;
|
||||
free(data);
|
||||
|
||||
/* Now put the data into a PPM image file. */
|
||||
@@ -315,14 +317,10 @@ get_file_func (CameraFilesystem *fs, const char *folder, const char *filename,
|
||||
ptr = ppm + strlen ((char *)ppm);
|
||||
size = strlen ((char *)ppm) + (w * h * 3);
|
||||
GP_DEBUG ("size = %i\n", size);
|
||||
|
||||
gp_bayer_decode (p_data, w , h , ptr, BAYER_TILE_RGGB);
|
||||
|
||||
if (gamma_factor < .4) gamma_factor = .4;
|
||||
if (gamma_factor > .6) gamma_factor = .6;
|
||||
gp_gamma_fill_table (gtable, gamma_factor );
|
||||
gp_gamma_correct_single (gtable, ptr, w * h);
|
||||
|
||||
mars_white_balance (ptr, w*h, 1.4, gamma_factor);
|
||||
gp_file_set_mime_type (file, GP_MIME_PPM);
|
||||
gp_file_set_name (file, filename);
|
||||
gp_file_set_data_and_size (file, (char *)ppm, size);
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
*
|
||||
* Copyright (C) 2004 Theodore Kilgore <kilgota@auburn.edu>
|
||||
*
|
||||
* white_balance() Copyright (C) 2008 Theodore Kilgore and Amauri Magagna.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
@@ -25,6 +27,7 @@
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <gamma.h>
|
||||
|
||||
#include <gphoto2/gphoto2.h>
|
||||
#include <gphoto2/gphoto2-port.h>
|
||||
@@ -343,3 +346,188 @@ mars_routine (Info *info, GPPort *port, char param, int n)
|
||||
|
||||
return(c[0]);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ========= White Balance / Color Enhance / Gamma adjust ===============
|
||||
*
|
||||
* Get histogram for each color plane
|
||||
* Expand to reach 0.5% of white dots in image
|
||||
*
|
||||
* Get new histogram for each color plane
|
||||
* Expand to reach 0.5% of black dots in image
|
||||
*
|
||||
* Get new histogram
|
||||
* Calculate and apply gamma correction
|
||||
*
|
||||
* if not a dark image:
|
||||
* For each dot, increases color separation
|
||||
*
|
||||
* ======================================================================
|
||||
*/
|
||||
|
||||
int
|
||||
histogram (unsigned char *data, unsigned int size, int *htable_r, int *htable_g, int *htable_b)
|
||||
{
|
||||
int x;
|
||||
/* Initializations */
|
||||
for (x = 0; x < 0x100; x++) {
|
||||
htable_r[x] = 0;
|
||||
htable_g[x] = 0;
|
||||
htable_b[x] = 0;
|
||||
}
|
||||
/* Building the histograms */
|
||||
for (x = 0; x < (size * 3); x += 3)
|
||||
{
|
||||
htable_r[data[x+0]]++; /* red histogram */
|
||||
htable_g[data[x+1]]++; /* green histogram */
|
||||
htable_b[data[x+2]]++; /* blue histogram */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
mars_white_balance (unsigned char *data, unsigned int size, float saturation,
|
||||
float image_gamma)
|
||||
{
|
||||
int x, r, g, b, max, d;
|
||||
double r_factor, g_factor, b_factor, max_factor;
|
||||
int htable_r[0x100], htable_g[0x100], htable_b[0x100];
|
||||
unsigned char gtable[0x100];
|
||||
double new_gamma, gamma=1.0;
|
||||
|
||||
/* ------------------- GAMMA CORRECTION ------------------- */
|
||||
|
||||
histogram(data, size, htable_r, htable_g, htable_b);
|
||||
x = 1;
|
||||
for (r = 48; r < 208; r++)
|
||||
{
|
||||
x += htable_r[r];
|
||||
x += htable_g[r];
|
||||
x += htable_r[r];
|
||||
}
|
||||
new_gamma = sqrt((double) (x * 1.5) / (double) (size * 3));
|
||||
x=0;
|
||||
GP_DEBUG("Provisional gamma correction = %1.2f\n", new_gamma);
|
||||
/* Recalculate saturation factor for later use. */
|
||||
saturation=saturation*new_gamma*new_gamma;
|
||||
GP_DEBUG("saturation = %1.2f\n", saturation);
|
||||
if(new_gamma >= 1.0)
|
||||
gamma = new_gamma;
|
||||
else
|
||||
gamma = image_gamma;
|
||||
|
||||
GP_DEBUG("Gamma correction = %1.2f\n", gamma);
|
||||
gp_gamma_fill_table(gtable, gamma);
|
||||
|
||||
/* ---------------- BRIGHT DOTS ------------------- */
|
||||
max = size / 200;
|
||||
histogram(data, size, htable_r, htable_g, htable_b);
|
||||
|
||||
for (r=0xfe, x=0; (r > 32) && (x < max); r--)
|
||||
x += htable_r[r];
|
||||
for (g=0xfe, x=0; (g > 32) && (x < max); g--)
|
||||
x += htable_g[g];
|
||||
for (b=0xfe, x=0; (b > 32) && (x < max); b--)
|
||||
x += htable_b[b];
|
||||
r_factor = (double) 0xfd / r;
|
||||
g_factor = (double) 0xfd / g;
|
||||
b_factor = (double) 0xfd / b;
|
||||
|
||||
max_factor = r_factor;
|
||||
if (g_factor > max_factor) max_factor = g_factor;
|
||||
if (b_factor > max_factor) max_factor = b_factor;
|
||||
|
||||
if (max_factor >= 2.5) {
|
||||
r_factor = (r_factor / max_factor) * 2.5;
|
||||
g_factor = (g_factor / max_factor) * 2.5;
|
||||
b_factor = (b_factor / max_factor) * 2.5;
|
||||
}
|
||||
GP_DEBUG("White balance (bright): r=%1d, g=%1d, b=%1d, fr=%1.3f, fg=%1.3f, fb=%1.3f\n", r, g, b, r_factor, g_factor, b_factor);
|
||||
if (max_factor <= 2.5) {
|
||||
for (x = 0; x < (size * 3); x += 3)
|
||||
{
|
||||
d = (data[x+0]<<8) * r_factor;
|
||||
d >>=8;
|
||||
if (d > 0xff) { d = 0xff; }
|
||||
data[x+0] = d;
|
||||
d = (data[x+1]<<8) * g_factor;
|
||||
d >>=8;
|
||||
if (d > 0xff) { d = 0xff; }
|
||||
data[x+1] = d;
|
||||
d = (data[x+2]<<8) * b_factor;
|
||||
d >>=8;
|
||||
if (d > 0xff) { d = 0xff; }
|
||||
data[x+2] = d;
|
||||
}
|
||||
}
|
||||
/* ---------------- DARK DOTS ------------------- */
|
||||
max = size / 200; /* 1/200 = 0.5% */
|
||||
histogram(data, size, htable_r, htable_g, htable_b);
|
||||
|
||||
for (r=0, x=0; (r < 96) && (x < max); r++)
|
||||
x += htable_r[r];
|
||||
for (g=0, x=0; (g < 96) && (x < max); g++)
|
||||
x += htable_g[g];
|
||||
for (b=0, x=0; (b < 96) && (x < max); b++)
|
||||
x += htable_b[b];
|
||||
|
||||
r_factor = (double) 0xfe / (0xff-r);
|
||||
g_factor = (double) 0xfe / (0xff-g);
|
||||
b_factor = (double) 0xfe / (0xff-b);
|
||||
|
||||
max_factor = r_factor;
|
||||
if (g_factor > max_factor) max_factor = g_factor;
|
||||
if (b_factor > max_factor) max_factor = b_factor;
|
||||
|
||||
if (max_factor >= 1.15) {
|
||||
r_factor = (r_factor / max_factor) * 1.15;
|
||||
g_factor = (g_factor / max_factor) * 1.15;
|
||||
b_factor = (b_factor / max_factor) * 1.15;
|
||||
}
|
||||
GP_DEBUG(
|
||||
"White balance (dark): r=%1d, g=%1d, b=%1d, fr=%1.3f, fg=%1.3f, fb=%1.3f\n",
|
||||
r, g, b, r_factor, g_factor, b_factor);
|
||||
|
||||
for (x = 0; x < (size * 3); x += 3)
|
||||
{
|
||||
d = (int) 0xff08-(((0xff-data[x+0])<<8) * r_factor);
|
||||
d >>= 8;
|
||||
if (d < 0) { d = 0; }
|
||||
data[x+0] = d;
|
||||
d = (int) 0xff08-(((0xff-data[x+1])<<8) * g_factor);
|
||||
d >>= 8;
|
||||
if (d < 0) { d = 0; }
|
||||
data[x+1] = d;
|
||||
d = (int) 0xff08-(((0xff-data[x+2])<<8) * b_factor);
|
||||
d >>= 8;
|
||||
if (d < 0) { d = 0; }
|
||||
data[x+2] = d;
|
||||
}
|
||||
|
||||
/* ------------------ COLOR ENHANCE ------------------ */
|
||||
|
||||
if(saturation > 0.0) {
|
||||
for (x = 0; x < (size * 3); x += 3)
|
||||
{
|
||||
r = data[x+0]; g = data[x+1]; b = data[x+2];
|
||||
d = (int) (r + g + b) /3.;
|
||||
if ( r > d )
|
||||
r = r + (int) ((r - d) * (0xff-r)/(0x100-d) * saturation);
|
||||
else
|
||||
r = r + (int) ((r - d) * (0xff-d)/(0x100-r) * saturation);
|
||||
if (g > d)
|
||||
g = g + (int) ((g - d) * (0xff-g)/(0x100-d) * saturation);
|
||||
else
|
||||
g = g + (int) ((g - d) * (0xff-d)/(0x100-g) * saturation);
|
||||
if (b > d)
|
||||
b = b + (int) ((b - d) * (0xff-b)/(0x100-d) * saturation);
|
||||
else
|
||||
b = b + (int) ((b - d) * (0xff-d)/(0x100-b) * saturation);
|
||||
data[x+0] = CLAMP(r);
|
||||
data[x+1] = CLAMP(g);
|
||||
data[x+2] = CLAMP(b);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -44,6 +44,9 @@ int mars_read_picture_data (Camera *camera, Info *info,
|
||||
GPPort *port, char *data, int size, int n);
|
||||
|
||||
int mars_decompress (unsigned char *inp ,unsigned char *outp, int w, int h);
|
||||
|
||||
int histogram (unsigned char *data, unsigned int size, int *htable_r,
|
||||
int *htable_g, int *htable_b);
|
||||
int mars_white_balance (unsigned char *data, unsigned int size, float saturation,
|
||||
float image_gamma);
|
||||
#endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user