added a new tool : fimgfx
This commit is contained in:
parent
59bcdf30d4
commit
9ae7e4d85f
1
.gitignore
vendored
1
.gitignore
vendored
@ -43,3 +43,4 @@ tools/addtga2fimg
|
|||||||
tools/addpnm2fimg
|
tools/addpnm2fimg
|
||||||
tools/cumulfimgs
|
tools/cumulfimgs
|
||||||
tools/fimgops
|
tools/fimgops
|
||||||
|
tools/fimgfx
|
||||||
|
@ -51,9 +51,10 @@ chaque pixel en virgule flottante sur 32bits, le type
|
|||||||
|
|
||||||
Attention, tout le code que nous allons voir ensemble est en
|
Attention, tout le code que nous allons voir ensemble est en
|
||||||
perpétuelle évolution\footnote{voir page \pageref{TODO}},
|
perpétuelle évolution\footnote{voir page \pageref{TODO}},
|
||||||
et sa fiablité reste à démontrer\index{valgrind}.
|
et sa fiablité (surtout sur certains aspects mathématiques)
|
||||||
|
reste à démontrer\index{valgrind}.
|
||||||
Mais le service après-vente est assez réactif. Du moins
|
Mais le service après-vente est assez réactif. Du moins
|
||||||
pour ceux qui suivent \texttt{\#tetalab} sur le réseau
|
pour ceux qui suivent le canal \texttt{\#tetalab} sur le réseau
|
||||||
IRC de Freenode.
|
IRC de Freenode.
|
||||||
|
|
||||||
% -------------------------------------------------------------------
|
% -------------------------------------------------------------------
|
||||||
@ -79,6 +80,8 @@ puis l'enregistrer dans un fichier \texttt{.fimg}\index{.fimg},
|
|||||||
un format complètement inconnu, puisque je viens de l'inventer
|
un format complètement inconnu, puisque je viens de l'inventer
|
||||||
à l'instant même.
|
à l'instant même.
|
||||||
|
|
||||||
|
\vspace{1em}
|
||||||
|
|
||||||
Tout d'abord, nous devons déclarer et garnir quelques variables
|
Tout d'abord, nous devons déclarer et garnir quelques variables
|
||||||
pour gérer la machinerie interne.
|
pour gérer la machinerie interne.
|
||||||
|
|
||||||
@ -89,8 +92,9 @@ FloatImg fimg;
|
|||||||
\end{verbatim}
|
\end{verbatim}
|
||||||
|
|
||||||
Ensuite, nous enchainerons trois étapes : création de l'image
|
Ensuite, nous enchainerons trois étapes : création de l'image
|
||||||
en mémoire centrale, initialisations des valeurs de pixel à 0.0,
|
en mémoire centrale, initialisation des valeurs de chaque pixel à 0.0,
|
||||||
et pour conclure, enregistrement dans un fichier.
|
et pour conclure, enregistrement dans un fichier\footnote{Au format
|
||||||
|
ésotérique, mais très véloce.} binaire.
|
||||||
|
|
||||||
\begin{verbatim}
|
\begin{verbatim}
|
||||||
foo = fimg_create(&fimg, width, height, FIMG_TYPE_RGB);
|
foo = fimg_create(&fimg, width, height, FIMG_TYPE_RGB);
|
||||||
@ -139,6 +143,9 @@ lesquels sont décrits en page \pageref{outils}.
|
|||||||
% -------------------------------------------------------------------
|
% -------------------------------------------------------------------
|
||||||
\section{Installation}
|
\section{Installation}
|
||||||
|
|
||||||
|
\textit{Attention, ça devient un peu gore.}
|
||||||
|
|
||||||
|
|
||||||
\subsection{Prérequis}
|
\subsection{Prérequis}
|
||||||
|
|
||||||
Vous devez, en dehors des outils classiques (bash, gcc, make\dots),
|
Vous devez, en dehors des outils classiques (bash, gcc, make\dots),
|
||||||
@ -255,8 +262,9 @@ int fimg_destroy(FloatImg *fimg);
|
|||||||
\end{verbatim}
|
\end{verbatim}
|
||||||
|
|
||||||
Les types d'images actuellement gérés sont les trois grands
|
Les types d'images actuellement gérés sont les trois grands
|
||||||
classiques : gray, rgb et rgba. Il y a les constantes adéquates
|
classiques : gray, rgb et rgba. Les constantes adéquates sont
|
||||||
dans \texttt{floatimg.h}. Les codes d'erreur sont disparates
|
dans \texttt{floatimg.h} et expliquées quelques lignes plus haut.
|
||||||
|
Les codes d'erreur sont disparates
|
||||||
et non documentés.
|
et non documentés.
|
||||||
\vspace{1em}
|
\vspace{1em}
|
||||||
|
|
||||||
@ -272,7 +280,44 @@ int fimg_plot_rgb (FloatImg *head, int x, int y,
|
|||||||
Les paramètres sont explicites, mais leur validité doit être
|
Les paramètres sont explicites, mais leur validité doit être
|
||||||
sévèrement controlée par l'appelant. Il y a une fonction
|
sévèrement controlée par l'appelant. Il y a une fonction
|
||||||
soeur, \texttt{fimg\_add\_rgb}\index{fimg\_add\_rgb},
|
soeur, \texttt{fimg\_add\_rgb}\index{fimg\_add\_rgb},
|
||||||
qui ajoute du rgb à un pixel.
|
qui ajoute du rgb à un pixel, laquelle a d'ailleur été
|
||||||
|
la base de la seconde génération de la
|
||||||
|
photographie\index{photographie} en cumul\index{cumul}.
|
||||||
|
|
||||||
|
\subsubsection{Contraste}\index{contraste}
|
||||||
|
|
||||||
|
Certaines opérations d'ajustement du contraste d'une image
|
||||||
|
semblent cohérents avec la notion d'image flottante.
|
||||||
|
Certains d'entre eux, les plus simples, sont disponibles.
|
||||||
|
|
||||||
|
Ils prennent chacun trois paramètres, d'abord les images
|
||||||
|
source et destination (\texttt{* FloatImg}), et le troisième
|
||||||
|
est un nombre en double précision donnant la valeur
|
||||||
|
maximale \textsl{supposée} de l'image source.
|
||||||
|
|
||||||
|
\begin{verbatim}
|
||||||
|
/* source in lib/contrast.c */
|
||||||
|
int fimg_square_root(FloatImg *s, FloatImg *d, double maxval);
|
||||||
|
int fimg_power_2(FloatImg *s, FloatImg *d, double maxval);
|
||||||
|
int fimg_cos_01(FloatImg *s, FloatImg *d, double maxval);
|
||||||
|
\end{verbatim}
|
||||||
|
|
||||||
|
Rappelons qu'il est possible pour un logiciel applicatif
|
||||||
|
comme \texttt{grabvidseq} (Cf page \pageref{grabvidseq})
|
||||||
|
de renseigner deux champs du descripteur d'image avec des
|
||||||
|
données pertinentes.
|
||||||
|
Ces deux champs sont \textit{fval} et \textit{count}.
|
||||||
|
Dans ce cas particulier, le premier indique la valeur
|
||||||
|
maximale du capteur, et le second sert à compter le
|
||||||
|
nombre de capture\footnote{Et c'est bien géré aussi
|
||||||
|
dans l'upscaling.} effectuées.
|
||||||
|
|
||||||
|
\vspace{1em}
|
||||||
|
|
||||||
|
La prochaine étape consistera à trouver une façon de faire
|
||||||
|
une égalisation\index{égalisation} par histogramme\index{histogramme}
|
||||||
|
qui respecte, dans toute sa futilité, le concept\index{concept}
|
||||||
|
de pixel flottant.
|
||||||
|
|
||||||
\subsection{funcs/}\index{funcs/}\label{funcs}
|
\subsection{funcs/}\index{funcs/}\label{funcs}
|
||||||
|
|
||||||
@ -386,9 +431,15 @@ les valeurs moyennes de chaque composante.
|
|||||||
Puis nous rajouterons\footnote{Les patchs sont les bienvenus}
|
Puis nous rajouterons\footnote{Les patchs sont les bienvenus}
|
||||||
le calcul de la variance\index{variance}.
|
le calcul de la variance\index{variance}.
|
||||||
|
|
||||||
|
\subsection{fimgfx}\index{fimgfx}\label{fimgfx}
|
||||||
|
|
||||||
|
\textit{En cours de création\index{XXX}.
|
||||||
|
Attention, je vais expérimenter un parsing un peu étrange
|
||||||
|
sur les arguments de la ligne de commande. coredump expected.}
|
||||||
|
|
||||||
\subsection{fimgops}\index{fimgops}\label{fimgops}
|
\subsection{fimgops}\index{fimgops}\label{fimgops}
|
||||||
|
|
||||||
Quelques opérations diverses entre deeux images, qui doivent être
|
Quelques opérations diverses entre deux images, qui doivent être
|
||||||
de la même taille, et du même type \textsl{pour le moment,
|
de la même taille, et du même type \textsl{pour le moment,
|
||||||
uniquement RGB}.
|
uniquement RGB}.
|
||||||
|
|
||||||
@ -448,14 +499,15 @@ Il reste plein de choses à faire pour que ce soit vraiment utilisable.
|
|||||||
\textsl{[en cours]}.
|
\textsl{[en cours]}.
|
||||||
\item Compléter les traitements mathémathiques (eg le gamma\index{gamma}).
|
\item Compléter les traitements mathémathiques (eg le gamma\index{gamma}).
|
||||||
\item Formaliser les codes d'erreur.
|
\item Formaliser les codes d'erreur.
|
||||||
\
|
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
|
|
||||||
% -------------------------------------------------------------------
|
% -------------------------------------------------------------------
|
||||||
\section{Exemples pour yusers}\index{example}
|
\section{Exemples pour yusers}\index{example}
|
||||||
|
|
||||||
Nous allons \textsl{essayer d'improviser} un exemple presque réel,
|
Nous allons \textsl{essayer d'improviser} un exemple presque réel,
|
||||||
avec un peu de rache\index{rache} dedans.
|
avec un peu de rache\index{rache} dedans. Ce qui est autorisé dans
|
||||||
|
les exemples.
|
||||||
|
|
||||||
\vspace{1em}
|
\vspace{1em}
|
||||||
|
|
||||||
@ -485,7 +537,7 @@ convert -delay 10 xx*.pnm foo.gif
|
|||||||
\end{verbatim}
|
\end{verbatim}
|
||||||
|
|
||||||
Voilà, si les choses se passent mal, vous allez découvrir
|
Voilà, si les choses se passent mal, vous allez découvrir
|
||||||
que votre drand n'est pas si drand que ça.
|
que votre drand n'est pas si drand que ça. Séquence angoisse.
|
||||||
|
|
||||||
|
|
||||||
% -------------------------------------------------------------------
|
% -------------------------------------------------------------------
|
||||||
@ -546,7 +598,9 @@ de l'image, en profitant du fait que l'on est capable
|
|||||||
de prendre $N$ images en rafale.
|
de prendre $N$ images en rafale.
|
||||||
|
|
||||||
Pour être rigoureux dans la prise de vue, ce $N$ doit
|
Pour être rigoureux dans la prise de vue, ce $N$ doit
|
||||||
être un multiple de 4, surtout si le nombre de capture est faible..
|
être un multiple de 4, surtout si le nombre de capture est faible.
|
||||||
|
N'hésitez pas à faire des essais, le résultat est parfois
|
||||||
|
aléatoire, surtout avec une caméra qui bouge.
|
||||||
|
|
||||||
\vspace{1em}
|
\vspace{1em}
|
||||||
|
|
||||||
@ -590,7 +644,7 @@ en mode portnawak\dots
|
|||||||
|
|
||||||
L'idée est donc de construire un appareil autonome, basé sur un Raspi et
|
L'idée est donc de construire un appareil autonome, basé sur un Raspi et
|
||||||
une webcam \textsc{usb}\index{USB}, alimenté par batterie et permettant d'aller
|
une webcam \textsc{usb}\index{USB}, alimenté par batterie et permettant d'aller
|
||||||
faire des images au bord d'un lac.
|
faire des images au bord d'un lac ou dans la campagne de l'Ariège.
|
||||||
|
|
||||||
% -------------------------------------------------------------------
|
% -------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* floatimg.h
|
* floatimg.h
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define FIMG_VERSION 77
|
#define FIMG_VERSION 78
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* in memory descriptor
|
* in memory descriptor
|
||||||
|
@ -9,7 +9,7 @@ DEPS = ../floatimg.h ../libfloatimg.a Makefile
|
|||||||
# ----------
|
# ----------
|
||||||
|
|
||||||
all: fimg2pnm mkfimg png2fimg fimgstats fimg2png \
|
all: fimg2pnm mkfimg png2fimg fimgstats fimg2png \
|
||||||
addpnm2fimg cumulfimgs fimgops
|
addpnm2fimg cumulfimgs fimgops fimgfx
|
||||||
|
|
||||||
fimgstats: fimgstats.c $(DEPS)
|
fimgstats: fimgstats.c $(DEPS)
|
||||||
gcc $(COPT) $< ../libfloatimg.a -o $@
|
gcc $(COPT) $< ../libfloatimg.a -o $@
|
||||||
@ -23,6 +23,9 @@ mkfimg: mkfimg.c $(DEPS)
|
|||||||
fimgops: fimgops.c $(DEPS)
|
fimgops: fimgops.c $(DEPS)
|
||||||
gcc $(COPT) $< ../libfloatimg.a -o $@
|
gcc $(COPT) $< ../libfloatimg.a -o $@
|
||||||
|
|
||||||
|
fimgfx: fimgfx.c $(DEPS)
|
||||||
|
gcc $(COPT) $< ../libfloatimg.a -o $@
|
||||||
|
|
||||||
fimg2pnm: fimg2pnm.c $(DEPS)
|
fimg2pnm: fimg2pnm.c $(DEPS)
|
||||||
gcc $(COPT) $< ../libfloatimg.a -o $@
|
gcc $(COPT) $< ../libfloatimg.a -o $@
|
||||||
|
|
||||||
|
168
tools/fimgfx.c
Normal file
168
tools/fimgfx.c
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
/*
|
||||||
|
FIMGFX
|
||||||
|
*/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "../floatimg.h"
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
int verbosity;
|
||||||
|
float global_fvalue;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char *name;
|
||||||
|
int id;
|
||||||
|
int nbarg;
|
||||||
|
} Fx;
|
||||||
|
|
||||||
|
enum fxid { Fx_cos01, Fx_pow2, Fx_sqrt };
|
||||||
|
|
||||||
|
Fx fx_list[] = {
|
||||||
|
{ "cos01", Fx_cos01, 0 },
|
||||||
|
{ "pow2", Fx_pow2, 0 },
|
||||||
|
{ "sqrt", Fx_sqrt, 0 },
|
||||||
|
{ NULL, 0, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------- */
|
||||||
|
int lookup_fx(char *txt)
|
||||||
|
{
|
||||||
|
Fx *fx;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
#if DEBUG_LEVEL
|
||||||
|
fprintf(stderr, ">>> %s ( '%s' )\n", __func__, txt);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (n=0, fx=fx_list; fx->name; fx++, n++) {
|
||||||
|
#if DEBUG_LEVEL
|
||||||
|
fprintf(stderr, "-> %3d %s\n", n, fx->name);
|
||||||
|
#endif
|
||||||
|
if (!strcmp(fx->name, txt)) {
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
/* --------------------------------------------------------------------- */
|
||||||
|
static void help(int lvl)
|
||||||
|
{
|
||||||
|
|
||||||
|
printf("fimg special effects (%d)\n", lvl);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
/* --------------------------------------------------------------------- */
|
||||||
|
int do_an_effect(char *sf, int act, char *df)
|
||||||
|
{
|
||||||
|
FloatImg src, dest;
|
||||||
|
int foo;
|
||||||
|
double maxval;
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
fprintf(stderr, ">>> %s ( '%s' %d '%s' )\n", __func__,
|
||||||
|
sf, act, df);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
foo = fimg_create_from_dump(sf, &src);
|
||||||
|
if (foo) {
|
||||||
|
fprintf(stderr, "err load '%s' : %d\n", sf, foo);
|
||||||
|
return foo;
|
||||||
|
}
|
||||||
|
|
||||||
|
maxval = (double)fimg_get_maxvalue(&src);
|
||||||
|
|
||||||
|
foo = fimg_clone(&src, &dest, 0);
|
||||||
|
if (foo) {
|
||||||
|
fprintf(stderr, "err clone %p : %d\n", &src, foo);
|
||||||
|
return foo;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (act) {
|
||||||
|
case Fx_cos01:
|
||||||
|
fimg_cos_01(&src, &dest, maxval); break;
|
||||||
|
case Fx_pow2:
|
||||||
|
fimg_power_2(&src, &dest, maxval); break;
|
||||||
|
case Fx_sqrt:
|
||||||
|
fimg_square_root(&src, &dest, maxval); break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "*** %s : %d is bad action\n", __func__, act);
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
foo = fimg_dump_to_file(&dest, df, 0);
|
||||||
|
if (foo) {
|
||||||
|
fprintf(stderr, "dumping datas to file give us a %d\n", foo);
|
||||||
|
return foo;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* --------------------------------------------------------------------- */
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int foo, opt, action;
|
||||||
|
int nba;
|
||||||
|
char *operator;
|
||||||
|
|
||||||
|
char *srcname = "";
|
||||||
|
char *dstname = "out.fimg";
|
||||||
|
|
||||||
|
while ((opt = getopt(argc, argv, "hk:v")) != -1) {
|
||||||
|
switch(opt) {
|
||||||
|
case 'h': help(0); break;
|
||||||
|
case 'k': global_fvalue = atof(optarg); break;
|
||||||
|
case 'v': verbosity++; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
fprintf(stderr, "argc %d optind %d\n", argc, optind);
|
||||||
|
for (foo=0; foo<argc; foo++)
|
||||||
|
fprintf(stderr, "%3d %c %s\n", foo, foo==optind?'*':' ', argv[foo]);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (3 > argc-optind) {
|
||||||
|
fprintf(stderr, "%s need some arguments...\n", argv[0]);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
operator = argv[optind];
|
||||||
|
action = lookup_fx(operator);
|
||||||
|
if (action < 0) {
|
||||||
|
fprintf(stderr, "garbage found in opcode field : %s\n", operator);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (verbosity) {
|
||||||
|
fprintf(stderr, "global fvalue %f\n", global_fvalue);
|
||||||
|
fprintf(stderr, "action %d\n", action);
|
||||||
|
fprintf(stderr, "verbosity %d\n", verbosity);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((nba=fx_list[action].nbarg)) {
|
||||||
|
fprintf(stderr, "action '%s' need %d arg\n", operator, nba);
|
||||||
|
}
|
||||||
|
|
||||||
|
srcname = argv[optind+1];
|
||||||
|
dstname = argv[optind+2];
|
||||||
|
fprintf(stderr, "%s ==> %s\n", srcname, dstname);
|
||||||
|
|
||||||
|
foo = do_an_effect(srcname, action, dstname);
|
||||||
|
fprintf(stderr, "do an effect -> %d\n", foo);
|
||||||
|
|
||||||
|
|
||||||
|
fprintf(stderr, "\n%s [done]\n", argv[0]);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* --------------------------------------------------------------------- */
|
Loading…
Reference in New Issue
Block a user