/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* GRetinex plug-in --
* Copyright (C) 2003 Fabien Pelisson <Fabien.Pelisson@inrialpes.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*
* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <gtk/gtk.h>
#include <libgimp/gimp.h>
#include <libgimp/gimpui.h>
#include <libgimp/gimpintl.h>
/*
Taille de l'image preview. La fonction
gimp_drawable_get_thumbnail_data retourne
l'image reduite en gardant l'aspect.
Le probleme est que cette fonction est
limite a une taille maximal de 128.
*/
#define PREVIEW_SIZE 128
/*
C'est le nombre maximal de filtrages
autorises.
*/
#define MAX_RETINEX_SCALES 8
/*
Definit comment sont repartis les
differents filtres en fonction de
l'echelle (~= ecart type de la gaussienne)
*/
#define RETINEX_UNIFORM 0
#define RETINEX_LOW 1
#define RETINEX_HIGH 2
/*
Cette structure est utilisee pour gerer
les parametres de l'algo de normalisation
couleur. Seulement on separe de la structure
les parametres qui ne doivent pas etre
accessibles via GIMP.
(1) les valeurs d'echelles
*/
typedef struct
{
gint nscales;
gint scales_mode;
gfloat cvar;
} RetinexParams;
static gfloat RetinexScales[MAX_RETINEX_SCALES];
typedef struct
{
/*
Indique le nombre de coefs utilises
par l'algo de filtrage recursif.
On utilise ici 3 coefs mais il existe
des implementations avec 5 coefs.
Un nombre + important augmente la qualite
du filtrage mais surtout pour des petites
echelles (< 2).
*/
int N;
/*
C'est l'echelle du filtre ~= ecart type.
Sigma est le nom utilise courament en stat
ou vision par ordinateur.
*/
float sigma;
/*
Parametres internes du filtrage.
*/
float alpha;
float b[4];
} gauss3_coefs;
/*
C'est une sorte de pointeur
de tableau qui permet de
naviguer selon la position
verticale dans les images.
*/
typedef struct
{
float* current;
int offset;
} oiterator;
typedef struct
{
gint run;
} RetinexInterface;
/*
Structure principale
qui gere l'interface graphique
et l'image preview.
*/
typedef struct
{
GtkWidget* all;
GtkWidget* preview;
gfloat preview_scale_x;
gfloat preview_scale_y;
guchar* preview_cache;
gint preview_cache_rowstride;
gint preview_cache_bpp;
} RetinexDialog;
/*
## Ces fonctions ne dependent pas de GIMP ##
Ce sont les fonctions associees
a l'algo de filtrage recursif.
+ une fonction de calcul de la moyenne et de la variance
en une passe.
*/
static void compute_coefs3(gauss3_coefs* c, float sigma);
static void GaussG0mirror(float* src, float* dst, int w, int h, gauss3_coefs* c);
static void gausssmoothmirror_X(float* src, float* dst, float* cache, int s, gauss3_coefs* c);
static void gausssmoothmirror_Y(oiterator* src, oiterator* dst, float* cache, int s, gauss3_coefs* c);
static void compute_mean_var(float* src, float* mean, float* var, int s);
/*
Ce sont les fonctions associees
a l'algorithme de normalisation couleur.
Elles vont de paire avec les fonctions
de l'algo de filtrage recursif.
MSRCR = MultiScale Retinex with Color Restoration
*/
static void MSRCR(float* cache, int w, int h, float* scales, int nscales);
static void MSRCR_aux(float* cache, int w, int h, float scale, float weight);
/*
## Ces fonctions dependent de GIMP ##
Ces fonctions permettent l'utilisation
de l'algo de normalisation couleur sous gimp.
*/
static void retinex(GimpDrawable* drawable);
static void retinex_preview(GtkWidget* preview);
static void retinex_scales_distribution(gfloat* scales, gint nscales, gint mode, gint s);
static void drawable_to_floatmatrix(GimpDrawable* src, gint x1, gint y1, gint w, gint h, gfloat* dst);
static void preview_to_floatmatrix(guchar* src, gint w, gint h, gfloat* dst);
/*
Fonctions d'interfaces obligatoires
pour que Gimp puisse demarrer le plugin/
*/
static void plugin_query(void);
static void plugin_run(gchar* name,
gint nparams,
GimpParam* param,
gint* nreturn_vals,
GimpParam** return_vals);
/*
Fonctions qui gerent l'interface
graphique (gtk et gimp).
*/
static gint retinex_dialog(GimpDrawable *drawable);
static GtkWidget* retinex_preview_widget(GimpDrawable* drawable);
static void retinex_fill_preview(gint32 drawable_ID);
static void retinex_preview_do_row(gint row,
gint width,
guchar* even,
guchar* odd,
guchar* src);
static void retinex_ok_callback(GtkWidget* widget,
gpointer data);
static void retinex_button_callback(GtkWidget* widget,
gpointer value);
/*
Variables globales.
*/
static RetinexParams rvals =
{
3, /* Nombre de filtres */
RETINEX_UNIFORM, /* Echelles reparties uniformement */
1.2 /* A voir */
};
static RetinexInterface retint =
{
/*
Indique si on a appuye sur OK (TRUE)
ou CANCEL (FALSE) lorsque l'interface
graphique est detruite.
*/
FALSE
};
GimpPlugInInfo PLUG_IN_INFO =
{
NULL, /* init_proc */
NULL, /* quit_proc */
plugin_query, /* query_proc */
plugin_run, /* run_proc */
};
static RetinexDialog* dlg = NULL;
/*************************************************************************/
/** **/
/** +++ Plug-in Interfaces **/
/** **/
/*************************************************************************/
/*
macro definissant la fonction main (gimp_main) appelee par GIMP.
Cette macro est definie dans libgimp/gimp.h.
*/
MAIN();
/*
Tout le necessaire pour enregistrer le plugin dans la
PDB (procedural database) de GIMP. La fonction importante
est gimp_install_procedure qui indique a GIMP le nom
du plugin, l'endroit (dans les menus) ou le plugin
est installe, le type d'images autorisees, ...
*/
static void plugin_query(void)
{
static GimpParamDef args[] =
{
/*
Les trois premiers parametres sont necessaires
lorsque le plugin se trouve dans le sous-menu <Image>.
*/
{ GIMP_PDB_INT32, "run_mode", "Interactive, non-interactive" },
{ GIMP_PDB_IMAGE, "image", "Input image (unused)" },
{ GIMP_PDB_DRAWABLE, "drawable", "Input drawable"},
{ GIMP_PDB_INT32, "nscales", "Number of retinex"},
{ GIMP_PDB_INT32, "scales_mode", "Retinex distribution through scales"},
{ GIMP_PDB_FLOAT, "cvar", "variance value"}
};
static GimpParamDef *return_vals = NULL;
static int nargs = sizeof(args) / sizeof(args[0]);
static int nreturn_vals = 0;
gimp_install_procedure("plug_in_retinex",
"Image color restoration algorithm",
"This plug-in normalise the image with the multiscale retinex algorithm.",
"Fabien Pelisson",
"Fabien Pelisson",
"2003",
/*
Position dans les menus, sous-menus...
Pourquoi pas egalement <Filters>/Enhance/Retinex...
Le choix de la position dans le menu
implique la presence de certains parametres
dans la structure GimpParamDef.
*/
N_("<Image>/Image/Colors/Retinex..."),
/*
On peut modifier l'algo pour travailler
pour prendre en compte l'alpha channel
des RGBA et/ou seulement l
- 1
- 2
- 3
- 4
- 5
- 6
前往页