Compare commits

..

2 Commits

Author SHA1 Message Date
tth
2ee1645a4a trying some contrast funcs... 2019-11-12 00:20:28 +01:00
tth
efac70ab2d more doc 2019-11-12 00:19:32 +01:00
4 changed files with 176 additions and 65 deletions

View File

@ -21,6 +21,10 @@
\usepackage[verbose]{layout} \usepackage[verbose]{layout}
\makeindex \makeindex
% ------ a few new commands
\newcommand{\interparagraphe { \vspace{60pt} } }
% ------------------------------------------------------------------- % -------------------------------------------------------------------
\title{Floating images processing} \title{Floating images processing}
\author{tTh} \author{tTh}
@ -31,6 +35,7 @@
\section{Image flottante ?} \section{Image flottante ?}
Mais de quoi parle-t-on exactement ? Mais de quoi parle-t-on exactement ?
\vspace{1em} \vspace{1em}
Traditionnellement, les valeurs des pixels dans les images Traditionnellement, les valeurs des pixels dans les images
@ -41,11 +46,15 @@ composante, mais c'est loin d'être le cas général.
J'ai donc souhaité aller plus loin, et coder chaque canal de J'ai donc souhaité aller plus loin, et coder chaque canal de
chaque pixel en virgule flottante sur 32bits, le type chaque pixel en virgule flottante sur 32bits, le type
\texttt{float}\index{float} du langage C. \texttt{float}\index{float} du langage C.
\vspace{1em} \vspace{1em}
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é reste à démontrer\index{valgrind}.
Mais le service après-vente est assez réactif. Du moins
pour ceux qui suivent \texttt{\#tetalab} sur le réseau
IRC de Freenode.
% ------------------------------------------------------------------- % -------------------------------------------------------------------
@ -57,7 +66,9 @@ et sa fiablité reste à démontrer\index{valgrind}.
\textsc{FloatImg} a débuté sous la forme de quelques fonctions \textsc{FloatImg} a débuté sous la forme de quelques fonctions
basiques en C, gérant la structure des données d'image en mémoire basiques en C, gérant la structure des données d'image en mémoire
et sur disque. et sur disque. Ça a été imaginé de façon presque empirique,
mais nous sommes tous là pour améliorer les choses, dans
la mesure de nos moyes.
Nous allons donc directement rentrer au cœur du problème. Nous allons donc directement rentrer au cœur du problème.
\vspace{1em} \vspace{1em}
@ -123,7 +134,7 @@ La suite vers la page \pageref{codaz}.
Vous trouverez dans le répertoire \texttt{tools/}\index{tools/} Vous trouverez dans le répertoire \texttt{tools/}\index{tools/}
d'autres exemples de mise en œuvre des fonctions disponibles d'autres exemples de mise en œuvre des fonctions disponibles
sous formes d'outils en ligne de commande, sous formes d'outils en ligne de commande,
décrits en page \pageref{outils}. lesquels sont décrits en page \pageref{outils}.
% ------------------------------------------------------------------- % -------------------------------------------------------------------
\section{Installation} \section{Installation}
@ -134,8 +145,13 @@ Vous devez, en dehors des outils classiques (bash, gcc, make\dots),
avoir quelques bibliothèques installées\footnote{Les \texttt{-dev} avoir quelques bibliothèques installées\footnote{Les \texttt{-dev}
pour Debain et dérivées}~: libv4l2, libpnglite, libtiff, libpnm, pour Debain et dérivées}~: libv4l2, libpnglite, libtiff, libpnm,
et probablement d'autres choses. et probablement d'autres choses.
Être familier avec l'utilisation du shell\index{shell} et l'écriture
de Makefile's sera un plus. \vspace{1em}
Il est même quasiment certain que Bash soit indispensable, tout
comme \textsc{gnu}/make\index{make}.
Une connaissance de base de l'utilisation du shell\index{shell}
et de l'écriture de Makefile's sera un plus.
\subsection{Compilation} \subsection{Compilation}
@ -145,6 +161,7 @@ de faire un Makefile récursif, mais\dots}.
Dans chacun des Dans chacun des
répertoires à traiter, ce script devrait trouver un Makefile et un fichier répertoires à traiter, ce script devrait trouver un Makefile et un fichier
\texttt{t.c} source de la cible par défaut du make. \texttt{t.c} source de la cible par défaut du make.
\vspace{1em} \vspace{1em}
Pour le moment, la procédure d'installation est un peu rude, Pour le moment, la procédure d'installation est un peu rude,
@ -155,6 +172,8 @@ dans un emplacement
approprié, par exemple approprié, par exemple
\texttt{/usr/local/include} et \texttt{/usr/local/lib}. \texttt{/usr/local/include} et \texttt{/usr/local/lib}.
% ------------------------------------------------------------------- % -------------------------------------------------------------------
\section{Utilisation coté codeur}\label{codaz} \section{Utilisation coté codeur}\label{codaz}
@ -387,6 +406,7 @@ options:
Pour des operateurs paramétrable (comme \texttt{mix}), le paramêtre flottant doit Pour des operateurs paramétrable (comme \texttt{mix}), le paramêtre flottant doit
être fourni en utilisant l'option \texttt{-k}. être fourni en utilisant l'option \texttt{-k}.
La véracité mathématique n'est pas garantie.
\subsection{fimg2png, fimg2pnm, fimg2tiff} \subsection{fimg2png, fimg2pnm, fimg2tiff}
\index{fimg2png}\label{fimg2png} \index{fimg2png}\label{fimg2png}
@ -395,7 +415,11 @@ Pour des operateurs paramétrable (comme \texttt{mix}), le paramêtre flottant d
Quelques petits proggies pour exporter notre format\index{.fimg} secret Quelques petits proggies pour exporter notre format\index{.fimg} secret
vers des choses plus directement utilisables. À condition que le vers des choses plus directement utilisables. À condition que le
code soit écrit et documenté en page \pageref{funcs}. code soit écrit et documenté. Peut-être en page \pageref{funcs}\dots
D'un autre coté, écrire un greffon d'import/export pour
Gimp\index{Gimp} ou Imagemagick\index{Imagemagick}
ne devrait pas être trop difficile. Des volontaires ?
\subsection{fimg2gray}\index{fimg2gray}\label{fimg2gray} \subsection{fimg2gray}\index{fimg2gray}\label{fimg2gray}
@ -426,25 +450,39 @@ Il reste plein de choses à faire pour que ce soit vraiment utilisable.
% ------------------------------------------------------------------- % -------------------------------------------------------------------
\section{Exemples pour yusers}\index{example} \section{Exemples pour yusers}\index{example}
Nous allons \textsl{essayer d'improviser} un exemple presque réel,
avec un peu de rache\index{rache} dedans.
\vspace{1em}
Nous savons générer une image contenant des pixels aux valeurs
probablement aléatoires (drand48\index{drand48}). Que se passe-t-il si
nous faisons la somme de plusieurs centaines\footnote{Des erreurs toxiques ?}
de ces images ?
\begin{verbatim} \begin{verbatim}
#!/bin/bash #!/bin/bash
ACCU="quux.fimg" ACCU="quux.fimg"
TMPF="tmp.fimg" TMPF="tmp.fimg"
DIMS="640 480" DIMS="320 240"
mkfimg ${ACCU} ${DIMS} mkfimg $ACCU $DIMS
for i in {0..100} for i in {0..1000}
do do
fname=$( printf "f%04d.pnm" $i )
echo $fname
mkfimg -t drand48 ${TMPF} ${DIMS} mkfimg -t drand48 ${TMPF} ${DIMS}
fname=$( printf "xx%04d.pnm" $i )
fimgops $ACCU $TMPF add $ACCU
fimg2pnm -v -g $ACCU $fname
done done
convert -delay 10 xx*.pnm foo.gif
\end{verbatim} \end{verbatim}
En fait, je n'ai pas la moindre idée de ce que peut bien Voilà, si les choses se passent mal, vous allez découvrir
faire ce code\dots que votre drand n'est pas si drand que ça.
% ------------------------------------------------------------------- % -------------------------------------------------------------------
\section{Video for Linux}\index{v4l2} \section{Video for Linux}\index{v4l2}
@ -462,8 +500,10 @@ v4l2.
\subsection{grabvidseq}\index{grabvidseq}\label{grabvidseq} \subsection{grabvidseq}\index{grabvidseq}\label{grabvidseq}
Un logiciel en devenir, qui permet déja la capture d'images en Un logiciel en évolution, qui permet déja la capture d'images en
\textsl{longue pose} selon la méthode du cumul\index{cumul}. \textsl{longue pose} selon la méthode du cumul\index{cumul}, et
devrait bientôt retrouver sa capacité à enregistrer des
séquences.
\begin{verbatim} \begin{verbatim}
tth@debian:~/Devel/FloatImg/v4l2$ ./grabvidseq -h tth@debian:~/Devel/FloatImg/v4l2$ ./grabvidseq -h
@ -477,13 +517,22 @@ options :
-s WxH size of capture -s WxH size of capture
-u try upscaling... -u try upscaling...
-v increase verbosity -v increase verbosity
-X arg Xperiment option
\end{verbatim} \end{verbatim}
La plupart de ces options ont un usage quasi-évident. La plupart de ces options ont un usage quasi-évident.
L'option \texttt{-s} doit correspondre à une des L'option \texttt{-s} doit correspondre à une des
résolutions possibles de votre capteur. Le type du résolutions possibles de votre capteur. Le type du
fichier en sortie (option \texttt{-o}) est déterminé par fichier en sortie (option \texttt{-o}) est déterminé par
l'extension. l'extension, actuellement
seulement \texttt{.fimg} et \texttt{.pnm} sont reconnus.
La conversion en gris (option \texttt{-g}) mérite un
peu plus de travail, et une paramétrisation plus facile.
L'option \texttt{-X} me permet d'intégrer des \textit{fritures}
expérimentales dans le binaire, et ne doit donc pas être
utilisée dans des scripts si on a des visions à long
terme.
\subsubsection{Upscaling}\index{upscaling}\label{upscaling} \subsubsection{Upscaling}\index{upscaling}\label{upscaling}
@ -493,7 +542,16 @@ 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. être un multiple de 4, surtout si le nombre de capture est faible..
\vspace{1em}
\textbf{Là, il manque un schéma\dots}
\subsubsection{shoot.sh}\index{shoot.sh}\label{shoot.sh}
\hspace{4cm}XXX\index{XXX}
\subsection{video-infos}\index{video-infos}\label{video-infos} \subsection{video-infos}\index{video-infos}\label{video-infos}
@ -504,12 +562,16 @@ Quelles sont ses possibilités de réglage ?
tth@debian:~/Devel/FloatImg$ v4l2/video-infos -h tth@debian:~/Devel/FloatImg$ v4l2/video-infos -h
Options : Options :
-d select the video device -d select the video device
-K set the K parameter -K nnn set the K parameter
-l list video devices -l list video devices
-T bla add a title -T bla add a title
-v increase verbosity -v increase verbosity
\end{verbatim} \end{verbatim}
Je me sois d'avouer qu'il reste quelques points mystérieux dans
l'\textsc{api} de \textsc{v4l2}, et donc, que ce que raconte
ce logiciel doit être pris avec des pincettes. En particulier
la liste des résolutions disponibles.
% ------------------------------------------------------------------- % -------------------------------------------------------------------
\section{Et pour la suite ?} \section{Et pour la suite ?}

View File

@ -5,7 +5,7 @@
COPT = -Wall -fpic -g -no-pie -DDEBUG_LEVEL=0 COPT = -Wall -fpic -g -no-pie -DDEBUG_LEVEL=0
OBJS = fimg-core.o fimg-pnm.o fimg-file.o fimg-math.o \ OBJS = fimg-core.o fimg-pnm.o fimg-file.o fimg-math.o \
fimg-timers.o operators.o fimg-2gray.o \ fimg-timers.o operators.o fimg-2gray.o \
interpolate.o fimg-compare.o interpolate.o fimg-compare.o contrast.o
DEPS = Makefile ../floatimg.h DEPS = Makefile ../floatimg.h
@ -34,6 +34,9 @@ fimg-2gray.o: fimg-2gray.c $(DEPS)
operators.o: operators.c $(DEPS) operators.o: operators.c $(DEPS)
gcc $(COPT) -c $< gcc $(COPT) -c $<
contrast.o: contrast.c $(DEPS)
gcc $(COPT) -c $<
interpolate.o: interpolate.c $(DEPS) interpolate.o: interpolate.c $(DEPS)
gcc $(COPT) -c $< gcc $(COPT) -c $<

64
lib/contrast.c Normal file
View File

@ -0,0 +1,64 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <math.h>
#include "../floatimg.h"
extern int verbosity;
/* ---------------------------------------------------------------- */
int fimg_square_root(FloatImg *s, FloatImg *d, double maxval)
{
int nbre, idx;
double dval;
if (s->type != FIMG_TYPE_RGB) {
fprintf(stderr, "%s : type %d invalide\n",
__func__, s->type);
return -4;
}
if (NULL==d) {
d = s;
}
nbre = s->width * s->height * 3;
for (idx=0; idx<nbre; idx++) {
dval = s->R[idx] / maxval;
d->R[idx] = maxval * sqrt(dval);
}
return -1;
}
/* ---------------------------------------------------------------- */
int fimg_power_2(FloatImg *s, FloatImg *d, double maxval)
{
int nbre, idx;
double dval;
if (s->type != FIMG_TYPE_RGB) {
fprintf(stderr, "%s : type %d invalide\n",
__func__, s->type);
return -4;
}
if (NULL==d) {
d = s;
}
nbre = s->width * s->height * 3;
for (idx=0; idx<nbre; idx++) {
dval = s->R[idx] / maxval;
d->R[idx] = maxval * dval * dval;
}
return -1;
}
/* ---------------------------------------------------------------- */

76
lib/t.c
View File

@ -67,71 +67,53 @@ fimg_destroy(&gray);
return 0; return 0;
} }
/* ---------------------------------------------------------------- */ /* ---------------------------------------------------------------- */
/****
foo = fimg_create(&dessin, W, H, 3); int fimg_square_root(FloatImg *s, FloatImg *d, double maxval);
petit_dessin(&dessin); int fimg_power_2(FloatImg *s, FloatImg *d, double maxval);
foo = fimg_create(&noise, W, H, 3);
fimg_drand48(&noise, 0.1); int essai_contraste(char *fname)
****/ {
int foo;
FloatImg dessin;
double maxi;
foo = fimg_create_from_dump(fname, &dessin);
maxi = (double)fimg_get_maxvalue(&dessin);
fprintf(stderr, "avant valeur maxi = %f\n", maxi);
fimg_power_2(&dessin, NULL, maxi);
maxi = (double)fimg_get_maxvalue(&dessin);
fprintf(stderr, "apres valeur maxi = %f\n", maxi);
fimg_dump_to_file(&dessin, "dst.fimg", 0);
fimg_destroy(&dessin);
return -1;
}
/* ---------------------------------------------------------------- */ /* ---------------------------------------------------------------- */
#define W 320 #define W 320
#define H 240 #define H 240
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
int foo, idx, opt; int foo, idx, opt;
float coef; // char outname[100];
FloatImg dessin, noise, result;
char outname[100];
int gray = 0; int gray = 0;
int nb_img = 42;
while ((opt = getopt(argc, argv, "gn:v")) != -1) { while ((opt = getopt(argc, argv, "gn:v")) != -1) {
switch(opt) { switch(opt) {
case 'g': gray++; break; case 'g': gray++; break;
case 'n': nb_img=atoi(optarg); break; case 'n': foo=atoi(optarg); break;
case 'v': verbosity++; break; case 'v': verbosity++; break;
} }
} }
if (verbosity) fimg_print_version(0); if (verbosity) fimg_print_version(0);
foo = essai_contraste("src.fimg");
foo = fimg_create_from_png("/home/tth/TMP/floatimg/s1.png", &dessin);
if (foo) {
fprintf(stderr, "s1 load err %d\n", foo);
exit(1);
}
if (verbosity) fimg_describe(&dessin, "s1 dessin");
if (gray) fimg_to_gray(&dessin);
foo = fimg_create_from_png("/home/tth/TMP/floatimg/s2.png", &noise);
if (foo) {
fprintf(stderr, "s2 load err %d\n", foo);
exit(1);
}
if (verbosity) fimg_describe(&noise, "s2 noise");
fimg_mul_cste(&noise, 0.50);
if (gray) fimg_to_gray(&noise);
foo = fimg_create(&result, W, H, 3);
if (verbosity) fimg_describe(&result, "d result");
fprintf(stderr, "running for %d picz\n", nb_img);
for (idx=0; idx<nb_img; idx++) {
coef = (float)idx / (float)nb_img;
// coef = (0.5-0.5*cos(4*3.141592654*coef));
foo = fimg_interpolate(&dessin, &noise, &result, coef);
printf("%6d %9.6f\n", idx, coef);
sprintf(outname, "/home/tth/TMP/floatimg/%05d.pnm", idx);
foo = fimg_save_as_pnm(&result, outname, 0);
}
/* yes, we can cleanup after work */
fimg_destroy(&dessin), fimg_destroy(&noise), fimg_destroy(&result);
return 0; return 0;
} }