Bibliothèque de traitements d'images en virgule flottante. http://la.buvette.org/photos/cumul/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
FloatImg/doc/the_floatimg_hack.tex

455 lines
15 KiB

\documentclass[a4paper,10pt]{article}
4 years ago
% \listfiles % pour le debug
\usepackage[french]{babel}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
% XXX \usepackage{lipsum}
\usepackage{makeidx}
\usepackage{listings}
3 years ago
\usepackage{babel}
\usepackage{pifont} % caractères rigolos
\usepackage{enumitem}
\setitemize[1]{label={\ding{82}}}
\frenchbsetup{CompactItemize=false}
4 years ago
% \usepackage{color}
% \usepackage{url}
\usepackage{xspace}
\usepackage[verbose]{layout}
\makeindex
% -------------------------------------------------------------------
\title{Floating images processing}
4 years ago
\author{tTh}
\begin{document}
\maketitle
\section{Image flottante ?}
3 years ago
Mais de quoi parle-t-on exactement ?
\vspace{1em}
Traditionnellement, les valeurs des pixels dans les images
informatiques sont mémorisées sur 8 bits, un octet\index{octet},
soit 256 valeurs différentes.
Ceci dit, on trouve parfois des images codées sur 16 bits par
composante, mais c'est loin d'être le cas général.
J'ai donc souhaité aller plus loin, et coder chaque canal de
chaque pixel en virgule flottante sur 32bits, le type
\texttt{float}\index{float} du langage C.
3 years ago
\vspace{1em}
Attention, tout le code que nous allons voir ensemble est en
perpétuelle évolution\footnote{voir page \pageref{TODO}},
et sa fiablité reste à démontrer\index{valgrind}.
% -------------------------------------------------------------------
4 years ago
\tableofcontents
\pagebreak
4 years ago
% -------------------------------------------------------------------
3 years ago
\section{Premier example}\index{example}\label{example}
4 years ago
3 years ago
\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
et sur disque.
Nous allons donc directement rentrer au cœur du problème.
\vspace{1em}
Pour commencer par quelques chose de simple,
nous allons créer une image RGB\index{RGB} complètement noire,
puis l'enregistrer dans un fichier \texttt{.fimg}\index{.fimg},
un format complètement inconnu, puisque je viens de l'inventer
à l'instant même.
Tout d'abord, nous devons déclarer et garnir quelques variables
pour gérer la machinerie interne.
\begin{verbatim}
int width = 640, height = 480;
3 years ago
char *fname = "exemple.fimg";
FloatImg fimg;
\end{verbatim}
Ensuite, nous enchainerons trois étapes : création de l'image
en mémoire centrale, initialisations des valeurs de pixel à 0.0,
et pour conclure, enregistrement dans un fichier.
\begin{verbatim}
3 years ago
foo = fimg_create(&fimg, width, height, FIMG_TYPE_RGB);
if (foo) {
fprintf(stderr, "create floatimg -> %d\n", foo);
exit(1);
}
fimg_clear(&fimg);
foo = fimg_dump_to_file(&fimg, fname, 0);
if (foo) {
fprintf(stderr, "dump fimg -> %d\n", foo);
exit(1);
}
\end{verbatim}
Une fois ce code enrobé dans un \texttt{main()}, compilé et exécuté,
nous pouvons entrevoir, grâce au logiciel
\texttt{fimgstats} (voir page \pageref{fimgstats}),
le résultat sous forme de chiffres divers, et/ou inutiles~:
\begin{verbatim}
3 years ago
$ ./fimgstats quux.img
----------- numbers from 'quux.img' :
640 480 3 0x7f3718c4f010 0x7f3718d7b010 0x7f3718ea7010
surface 307200
mean values:
R 0.000000
G 0.000000
B 0.000000
A 0.000000
max value 0.000000
\end{verbatim}
3 years ago
Nous avons donc sous la main une mécanique qui ne demande qu'à
faire des trucs futiles et des images qui clignotent.
La suite vers la page \pageref{codaz}.
\vspace{1em}
Vous trouverez dans le répertoire \texttt{tools/}\index{tools/}
d'autres exemples de mise en œuvre des fonctions disponibles
3 years ago
sous formes d'outils en ligne de commande,
décrits en page \pageref{outils}.
% -------------------------------------------------------------------
\section{Installation}
\subsection{Prérequis}
3 years ago
Vous devez, en dehors des outils classiques (bash, gcc, make\dots),
avoir quelques bibliothèques installées\footnote{Les \texttt{-dev}
pour Debain et dérivées}~: libv4l2, libpnglite, libtiff, libpnm,
et probablement d'autres choses.
Être familier avec l'utilisation du shell\index{shell} et l'écriture
de Makefile's sera un plus.
\subsection{Compilation}
Un script \texttt{build.sh} permet de construire approximativement
3 years ago
le bouzin. Il est loin d'être parfait\footnote{Il doit être possible
de faire un Makefile récursif, mais\dots}.
Dans chacun des
répertoires à traiter, ce script devrait trouver un Makefile et un fichier
\texttt{t.c} source de la cible par défaut du make.
3 years ago
\vspace{1em}
Pour le moment, la procédure d'installation est un peu rude,
pour ne pas dire clairement sommaire.
3 years ago
Si le résultat vous semble correct, vous pouvez copier
les deux fichiers \texttt{floatimg.h} et \texttt{libfloatimg.a}
dans un emplacement
3 years ago
approprié, par exemple
\texttt{/usr/local/include} et \texttt{/usr/local/lib}.
% -------------------------------------------------------------------
3 years ago
\section{Utilisation coté codeur}\label{codaz}
Classiquement, il y a un fichier à inclure, \texttt{floatimg.h},
contenant un certain nombre de
définition de structures, de macros,
de constantes\footnote{À l'ancienne, via le pré-processur}
et les prototypes des fonctions utilisables.
\vspace{1em}
Au niveau du code source, ces fonctions sont approximativement
classées en deux catégories : \texttt{lib/} et \texttt{funcs/}.
La première contient les choses qui sont relativement figées,
et la seconde celles qui risquent de bouger. Cette classification
est en fait arbitraire.
\subsection{Structures, macros\dots}
Les pixels flottants d'une image résidant en mémoire centrale
sont décrits par un ensemble
de données (certains appelent ça des \textsl{metadats}) regroupées
dans une jolie structure que nous allons examiner dès maintenant.
\begin{verbatim}
/* in memory descriptor */
typedef struct {
int width;
int height;
int type;
float fval;
int count;
float *R, *G, *B, *A;
int reserved;
} FloatImg;
\end{verbatim}\index{FloatImg}
Les deux premiers champs sont \textsl{obvious}.
Le troisième est le type d'image : pour le moment, il y en a trois
qui sont définis\footnote{et plus ou moins bien gérés\dots} :
gris, rgb et rgba\index{rgba}.
\begin{verbatim}
#define FIMG_TYPE_GRAY 1
#define FIMG_TYPE_RGB 3
#define FIMG_TYPE_RGBA 4
\end{verbatim}
Un peu plus loin, nous avons les pointeurs vers les
différents \textsl{pixmaps} de l'image. En principe l'organisation
interne de ces zones est improbable, puisque qu'elle dérive
d'idées approximatives.
\vspace{1em}
Les deux champs suivants (fval et count) sont à la disposition du
\textsl{yuser}
qui peut jouer avec à loisir pour faire, par exemple, ce genre de
chose. Imaginons un périphérique de capture qui nous fournisse des
images en gris sur 4 bits. Et que nous voulions cumuler\index{cumul}
quelques images...
\vspace{1em}
Le champ \textsl{count} sera mis à 0 et
le champ \textsl{fval} sera initialisé à 15.0
(valeur maximale renvoyée par le capteur).
Ensuite, dans la boucle capture/cumul, \textsl{count} sera
incrémenté à chaque passe, et nous aurons donc, en finale,
toutes les informations nécessaires pour exploiter au mieux la dynamique
de notre image dans les étapes ultérieures.
\subsection{lib/}\index{lib/}
Première chose, la gestion dynamique de la mémoire occupées
par tous ces pixels flottants est faite par ces deux fonctions~:
\begin{verbatim}
int fimg_create(FloatImg *fimg, int w, int h, int type);
int fimg_destroy(FloatImg *fimg);
\end{verbatim}
Les types d'images actuellement gérés sont les trois grands
classiques : gray, rgb et rgba. Il y a les constantes adéquates
dans \texttt{floatimg.h}. Les codes d'erreur sont disparates
et non documenté.
\vspace{1em}
Bon, vous avez une image latente, et vous souhaitez dessiner dessus
(ou dedans ?) avec vos encres flottantes ?
Il y a une fonction pour ça.
\subsection{funcs/}\index{funcs/}\label{funcs}
Une bonne partie de ces fonctions est indéterministe. Ce qui
veut dire, en langage de tous les soirs, que ça risque de ne
pas être la même chose dans l'avenir.
\vspace{1em}
On y trouve pêle-mêle de l'import/export de fichiers, de l'analyse
de chaines de caractères, du tracé de choses bizarres\dots
Plein de trucs qu'il faudra bien expliquer un jour\footnote{Mais
il fait trop chaud dans le dd2\index{dd2}}.
% -------------------------------------------------------------------
\section{Les outils}\label{outils}
4 years ago
\textsl{3615mavie} : sur des projets comme celui-ci, qui travaillent
in-fine sur des objets que l'on peut considérer comme « physiques »,
il est important de passer à une utilisation
normale\footnote{Il y a une vie en dehors de git.} et construire
des trucs qui mettent en action le code primitif.
\vspace{1em}
Ces machins ont en commun deux options bien pratiques~:
\texttt{-h} pour avoir un résumé des options disponibles
et \texttt{-v} qui augmente la puissance de bavardage.
Dans un avenir incertain, il existera des pages de man\index{man}.
\subsection{mkfimg}\index{mkfimg}\label{mkfimg}
3 years ago
Création d'un fichier contenant une image de « teinte » constante
(ou pas).
Cette notion de teinte est assez inconsistante pour le moment,
3 years ago
\begin{verbatim}
tth@debian:~/Devel/FloatImg/tools$ ./mkfimg -v -h
Usage: mkfimg [options] quux.fimg width height
-k N.N give a float parameter
-t bla howto make the pic
black, drand48...
-v increase verbosity
*** FloatImg library, alpha v73 (Sep 28 2019, 23:34:29)
\end{verbatim}
\subsection{png2fimg}\index{png2fimg}\label{png2fimg}
Grosse panne à réparer.
\begin{verbatim}
tth@debian:~/TMP/floatimg$ png2fimg A.png foo.fimg
error in 'fimg_create_from_png' : read png -> -1 File error
png2fimg : err -1, abort.
\end{verbatim}
Il faut envisager le passage à \texttt{libpng}\index{libpng}.
\subsection{fimgstats}\index{fimgstats}\label{fimgstats}
3 years ago
Affichage de quelques valeurs calculées à partir du contenu d'un fichier
\texttt{.fimg}\index{.fimg}.
3 years ago
\begin{verbatim}
usage : fimgstats [options] file.fimg
-c make a machinable csv
-v increase verbosity
\end{verbatim}
À vrai dire, je ne sais pas encore quelles métriques seront utiles
3 years ago
en première approche, alors commençont par le plus simple,
les valeurs moyennes de chaque composante.
Puis nous rajouterons le calcul de la variance\index{variance}.
\subsection{fimgops}\index{fimgops}\label{fimgops}
Operations diverses sur ou entre des images.
3 years ago
\begin{verbatim}
usage:
3 years ago
fimgops [options] A.fimg B.fimg operator D.fimg
operators:
add 1
sub 2
mix 3
mul 4
options:
-g convert output to gray
-k N.N set float value
-v increase verbosity
3 years ago
\end{verbatim}
Pour des operateurs paramétrable (comme \texttt{mix}), le paramêtre flottant doit
être fourni en utilisant l'option \texttt{-k}.
\subsection{fimg2png, fimg2pnm, fimg2tiff}
\index{fimg2png}\label{fimg2png}
\index{fimg2pnm}\label{fimg2pnm}
\index{fimg2tiff}\label{fimg2tiff}
Quelques petits proggies pour exporter notre format\index{.fimg} secret
vers des choses plus directement utilisables. À condition que le
code soit écrit et documenté en page \pageref{funcs}.
\subsection{fimg2gray}\index{fimg2gray}\label{fimg2gray}
Nous avons vu dans ce document que chaque image flottante pouvait
avoir plusieurs plans de réalité. Il ne faut en négliger aucun.
\vspace{1em}
Il faut quand même deviner que pour passer de l'espace RGB\index{RGB}
à une abstraction linéaire mono-dimensionnelle, il existe une foultitude
de méthodes, toutes plus légitimes que les autres.
% -------------------------------------------------------------------
\section{TODO}\index{TODO}\label{TODO}
Il reste plein de choses à faire pour que ce soit vraiment utilisable.
\vspace{1em}
3 years ago
\begin{itemize}
\item Import/export au format \textsc{tiff}\index{tiff}.
\item Remplacer le « fait-maison » par \textsc{libnetpnm}\index{pnm}.
\textsl{[en cours]}.
\item Compléter les traitements mathémathiques (eg le gamma\index{gamma}).
\item Formaliser les codes d'erreur.
3 years ago
\
\end{itemize}
3 years ago
% -------------------------------------------------------------------
\section{Exemples pour yusers}\index{example}
\begin{verbatim}
#!/bin/bash
ACCU="quux.fimg"
TMPF="tmp.fimg"
DIMS="640 480"
mkfimg ${ACCU} ${DIMS}
for i in {0..100}
do
fname=$( printf "f%04d.pnm" $i )
echo $fname
mkfimg -t drand48 ${TMPF} ${DIMS}
done
\end{verbatim}
% -------------------------------------------------------------------
\section{Video for Linux}\index{v4l2}
Donc, maintenant, nous savons un peu tripoter ces images flottantes.
Et nous devons nous poser une question fondamentale\footnote{primitive ?}
3 years ago
sur la provenance de ces données prétendant être des images.
\vspace{1em}
En fait, notre désir secret est la découverte des choses cachées du
monde qui nous entoure. Nous voulons des images du \textbf{réel} et
pour cela, l'outil le plus commun, le plus répandu,
est la webcam\index{webcam}. L'universelle webcam. Et l'incontournable
v4l2.
\subsection{grabvidseq}\index{grabvidseq}\label{grabvidseq}
Un logiciel en devenir, qui permet déja la capture d'images en
\textsl{longue pose} selon la méthode du cumul\index{cumul}.
\begin{verbatim}
tth@debian:~/Devel/FloatImg/v4l2$ ./grabvidseq -h
options :
-d /dev/? select video device
-g convert to gray
-n NNN how many frames ?
-O ./ set Output dir
-o bla set output filename
-p NN.N period in seconds
-s WxH size of capture
-u try upscaling...
-v increase verbosity
\end{verbatim}
3 years ago
\subsection{video-infos}\index{video-infos}\label{video-infos}
Que contient, que peut faire mon périphérique \textsl{àlc} ?
% -------------------------------------------------------------------
\section{Et pour la suite ?}
En fait, je fait de la photo par la méthode du « cumul »\index{cumul}
3 years ago
depuis plusieurs années. Une webcam\index{webcam},
un Linux\index{Linux}, et ça \textsl{juste marche}.
Sauf que c'est quand même un peu galère à déplacer, il faut
avoir un shell pour déclencher, c'est pas facile à utiliser
en mode portnawak\dots
\vspace{1em}
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
faire des images au bord d'un lac.
3 years ago
4 years ago
% -------------------------------------------------------------------
\printindex
\end{document}