1879 lines
		
	
	
		
			68 KiB
		
	
	
	
		
			TeX
		
	
	
	
	
	
			
		
		
	
	
			1879 lines
		
	
	
		
			68 KiB
		
	
	
	
		
			TeX
		
	
	
	
	
	
\documentclass[a4paper,10pt]{article}
 | 
						||
 | 
						||
% \listfiles              % pour le debug
 | 
						||
 | 
						||
\usepackage[french]{babel}
 | 
						||
\usepackage[utf8]{inputenc}
 | 
						||
\usepackage[T1]{fontenc}
 | 
						||
\usepackage{makeidx}
 | 
						||
\usepackage{listings}
 | 
						||
 | 
						||
% \lstset{frame=single}           % dessin d'un cadre autour du listing
 | 
						||
\lstset{basicstyle=\ttfamily\small}
 | 
						||
\lstset{aboveskip=0.01em,belowskip=0.1em}
 | 
						||
 | 
						||
\usepackage{babel}			% ?
 | 
						||
 | 
						||
\usepackage{graphicx} 			% for gnuplot ylabel rotate
 | 
						||
 | 
						||
\usepackage{pifont}             	% caractères rigolos
 | 
						||
\usepackage{enumitem}
 | 
						||
\setitemize[1]{label={\ding{87}}}
 | 
						||
\frenchbsetup{CompactItemize=false}
 | 
						||
 | 
						||
% \usepackage{color}
 | 
						||
% \usepackage{url}
 | 
						||
\usepackage{xspace}
 | 
						||
\usepackage[verbose]{layout}
 | 
						||
\usepackage{ulem}
 | 
						||
 | 
						||
\setlength \parskip {0.18em}
 | 
						||
\setcounter{tocdepth}{2}        	% XXX à regarder un de ces jours ?
 | 
						||
 | 
						||
\makeatletter
 | 
						||
% explication de ce truc ?
 | 
						||
\def\verbatim@font{\normalfont\ttfamily\small}
 | 
						||
\makeatother
 | 
						||
 | 
						||
\setlength{\hoffset}{0em}
 | 
						||
\setlength{\textheight}{640pt}
 | 
						||
\setlength{\textwidth}{422pt}
 | 
						||
\setlength{\marginparwidth}{10pt}
 | 
						||
 | 
						||
\makeindex
 | 
						||
 | 
						||
% ------ a few new commands
 | 
						||
\newcommand{\interparagraphe { \vspace{50pt} } }
 | 
						||
 | 
						||
% -------------------------------------------------------------------
 | 
						||
\title{Floating images processing (for fun and profit ?)}
 | 
						||
\author{tTh}
 | 
						||
 | 
						||
\begin{document}
 | 
						||
\maketitle
 | 
						||
 | 
						||
\section*{Une image flottante ?}
 | 
						||
 | 
						||
\vspace{2em}
 | 
						||
\textsl{Mais de quoi parle-t-on exactement ?}
 | 
						||
\vspace{2em}
 | 
						||
 | 
						||
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. Ce qui correspond
 | 
						||
à la norme IEEE 754-1985. 
 | 
						||
 | 
						||
% XXX XXX XXX\vspace{1em}
 | 
						||
 | 
						||
\textbf{Attention !} tout le code que nous allons voir ensemble est en
 | 
						||
perpétuelle évolution\footnote{voir page \pageref{TODO} pour les détails},
 | 
						||
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
 | 
						||
pour ceux qui suivent le canal \texttt{\#tetalab} sur le réseau
 | 
						||
IRC de \textsl{libera.chat}.
 | 
						||
 | 
						||
\textbf{Attention !} ce document commence par une bonne rafale
 | 
						||
de technique parfois \textsl{hardue}\footnote{hard + ardue = private
 | 
						||
joke Usenet}, avec des pointeurs dedans, mais vous êtes déja
 | 
						||
au courant.
 | 
						||
Le pointeur, c'est bien, c'est comme le doigt sur les écrans
 | 
						||
de zombiephones, ça sert juste à dire «~C'est là !~», c'est
 | 
						||
donc gravement utile, mais parfois, le doigt glisse.
 | 
						||
Et là, tout peut arriver.
 | 
						||
Vous avez parfaitement le droit de sauter directement à
 | 
						||
la page \pageref{outils} pour quelque chose de plus concret.
 | 
						||
 | 
						||
% -------------------------------------------------------------------
 | 
						||
%
 | 
						||
%  d'après le mail de JearZ, en avril 2021, sur la ml tetalab@
 | 
						||
%
 | 
						||
\subsection*{MiniFaq}\index{FAQ}
 | 
						||
 | 
						||
En avril 2021, pendant la fin d'un monde, on m'a demandé de préciser
 | 
						||
certains points. Je vais tenter de répondre à ces FAQ~:%
 | 
						||
« Fréquentes et Absurdes Questions » avec des réponses
 | 
						||
absurdes et précises.
 | 
						||
 | 
						||
\subsubsection*{c'est quoi une image d'un point de vue physique ?}
 | 
						||
 | 
						||
Une représentation approximative d'un monde physique invisible.
 | 
						||
L'infinie bio-complexité de notre système oculaire et ses interactions
 | 
						||
avec notre multivac neuronal n'est devenue quantifiable qu'avec
 | 
						||
l'arrivée des premiers calculateurs
 | 
						||
numériques quand certains ont songé à passer du flou mental à la grille
 | 
						||
physique.
 | 
						||
 | 
						||
Les détails techniques sur cette représentation sont en page
 | 
						||
\pageref{FloatImg desc}, avec des pointeurs et des
 | 
						||
tableaux dedans.
 | 
						||
Ah, les pointeurs, la pire chose du monde, mais pourquoi s'en passer\dots
 | 
						||
 | 
						||
\subsubsection*{quelques rappels de comment on acquiert et numérise une image}
 | 
						||
 | 
						||
Avant de se l'approprier, il vaut la rendre réelle dans sa vision intérieur.
 | 
						||
Il faut l'imaginer comme des lignes de code interposées entre la grille
 | 
						||
physique dont on vient de parler, et une autre grille, bien réelle, des
 | 
						||
pixels sur notre écran Trinitron de 44cm.
 | 
						||
Et puisque on en parle, je me permet de vous conseiller avec
 | 
						||
\textbf{vigueur} la webcam de Playstation (aka PsEye).
 | 
						||
Moins de 10 Euros
 | 
						||
dans les machin-trocs, et un grain d'image vraiment présent.
 | 
						||
 | 
						||
\texttt{https://fr.wikipedia.org/wiki/PlayStation\_Eye}
 | 
						||
 | 
						||
\subsubsection*{définir les notions de base: canal, pixel, codage couleurs}
 | 
						||
 | 
						||
Ah vous en voulez de la technique ? Oké, on y va.
 | 
						||
En fait, on va tripoter pleins de nombres, plus ou moins rangés dans
 | 
						||
des champs de pixels, pour concrétiser l'existence perceptuelle de ces
 | 
						||
grains de lumière chromatisés.
 | 
						||
 | 
						||
\subsubsection*{quelques belles images / schémas polychromes en intro pour 
 | 
						||
			illustrer tout ça}
 | 
						||
 | 
						||
Tour cela est dans le grand Ternet
 | 
						||
mondial, je pourrais même vous donner l'url si vous me promettez de ne pas
 | 
						||
la glisser dans le capitalisme de surveillance.
 | 
						||
 | 
						||
% ===================================================================
 | 
						||
 | 
						||
\setlength \parskip {0em}
 | 
						||
 | 
						||
\pagebreak
 | 
						||
\tableofcontents
 | 
						||
\pagebreak
 | 
						||
\setlength \parskip {0.40em}
 | 
						||
 | 
						||
% XXX \layout \pagebreak
 | 
						||
 | 
						||
% ===================================================================
 | 
						||
 | 
						||
\section{Théorie}\index{théorie}
 | 
						||
 | 
						||
Pour le moment, seule la quête de l'empirisme absolu a été
 | 
						||
visée. Les justifications mathématiques attendront le retour
 | 
						||
de monsieur Schmod777.
 | 
						||
Ceci dit, rien ne nous empêche d'aller consulter
 | 
						||
Wikipedia, afin de mieux connaitre ces nombres flottants
 | 
						||
que nous allons utiliser~:
 | 
						||
 | 
						||
\begin{quotation}
 | 
						||
An IEEE 754 32-bit base-2 floating-point variable has
 | 
						||
a maximum value of
 | 
						||
$(2 - 2^{-23}) \times 2^{127} \approx 3.4028235 \times 10^{38}$.
 | 
						||
All integers with 7 or fewer decimal digits, and any $2^{n}$ for
 | 
						||
a whole number $-149 \leq n \leq 127$, can be converted exactly into
 | 
						||
an IEEE 754 single-precision floating-point value.
 | 
						||
 | 
						||
In the IEEE 754-2008 standard, the 32-bit base-2 format is
 | 
						||
officially referred to as binary32; it was called single in
 | 
						||
IEEE 754-1985.
 | 
						||
\end{quotation}
 | 
						||
 | 
						||
% XXX
 | 
						||
% Ce qui nous conduit à estimer qu'il est possible de cumuler environ
 | 
						||
% quelques milliers d'images standard à 256 niveaux, sans trop avoir
 | 
						||
% à se soucier des éventuelles pertes de précision. Mais ça demande
 | 
						||
% à être confirmé par des esprits supérieurs.
 | 
						||
 | 
						||
https://dl.acm.org/doi/pdf/10.1145/103162.103163
 | 
						||
 | 
						||
\subsection{Dynamique}\index{dynamique}
 | 
						||
 | 
						||
Dynamique, précision et \textsl{macheps} ? Peu de gens connaissent
 | 
						||
la fourbitude des calculs en virgule flottante avec les ordinateurs.
 | 
						||
Moi-même compris. Il est évident qu'une étude théorique doit être
 | 
						||
effectuée afin d'éviter les potentiels inconvénients.
 | 
						||
 | 
						||
Ceci dit, le standard \textsl{ieee754}\index{ieee754} nous indique qu'il
 | 
						||
y a 23 bits pour la mantisse, ce qui nous propose déja
 | 
						||
plus de huit millions de valeurs possibles.
 | 
						||
Considérons un cas typique~:
 | 
						||
le cumul de $N$ images ayant un niveau maximum $Vm$.
 | 
						||
 | 
						||
\subsection{Pixel négatif ?}
 | 
						||
 | 
						||
Il est très difficle d'imaginer une lumière négative. Sauf peut-être
 | 
						||
si nous songeons à des coefficients d'absorption, ou un canal
 | 
						||
\textsl{alpha} qui inverserait les valeurs ? Un domaine dont
 | 
						||
l'exploration peut confiner au mysticisme de part la multitude
 | 
						||
des traitement possibles : valeur absolue, \textsl{clamping},
 | 
						||
report sur les autres composantes. Votre imagination est
 | 
						||
la limite.
 | 
						||
 | 
						||
% ===================================================================
 | 
						||
 | 
						||
\section{Premier exemple}\index{exemple}\label{exemple}
 | 
						||
 | 
						||
\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. Ça a été imaginé de façon presque empirique,
 | 
						||
mais nous sommes tous là pour améliorer les choses, dans
 | 
						||
la mesure de nos moyens.
 | 
						||
Nous allons donc directement rentrer au cœur du problème,
 | 
						||
en écrivant quelques lignes de code montrant le fonctionnement
 | 
						||
général de la chose vu du coté de la machine.
 | 
						||
 | 
						||
\subsection{L'idée}
 | 
						||
 | 
						||
Pour commencer par quelque 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\footnote{Enfin, non, il y a déja longtemps,
 | 
						||
avant la grande pandémie.}.
 | 
						||
 | 
						||
Tout d'abord, nous devons déclarer et garnir quelques variables
 | 
						||
pour gérer la machinerie interne.
 | 
						||
 | 
						||
\begin{lstlisting}
 | 
						||
int             width = 640, height = 480;
 | 
						||
char            *fname = "quux.fimg";
 | 
						||
FloatImg        fimg;
 | 
						||
\end{lstlisting}
 | 
						||
 | 
						||
Ensuite, nous enchainerons trois étapes : la création de l'image
 | 
						||
en mémoire centrale, l'initialisation des valeurs de chaque pixel à 0.0
 | 
						||
(une valeur que certains associent au noir complet, et d'autres à une
 | 
						||
impossibilité quantique),
 | 
						||
et pour conclure, l'enregistrement de cette image dans un
 | 
						||
fichier\footnote{Au format ésotérique, mais très véloce.}
 | 
						||
binaire.
 | 
						||
 | 
						||
\begin{lstlisting}
 | 
						||
memset(fimg, 0, sizeof(FloatImg));
 | 
						||
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{lstlisting}
 | 
						||
 | 
						||
Une fois ce code enrobé dans un \texttt{main()}, compilé puis exécuté,
 | 
						||
nous pouvons entrevoir, grâce au logiciel
 | 
						||
\texttt{fimgstats} (décrit en page \pageref{fimgstats}),
 | 
						||
le résultat sous forme de chiffres divers, et/ou inutiles~:
 | 
						||
 | 
						||
\begin{verbatim}
 | 
						||
$ ./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}
 | 
						||
 | 
						||
\subsection{Action ?}
 | 
						||
 | 
						||
Nous avons donc sous la main un ensemble d'outils mécaniques qui ne demande
 | 
						||
qu'à faire des trucs futiles et des images qui clignotent.
 | 
						||
Avec un bon script bash, il y a déja de quoi faire.
 | 
						||
La suite vers la page \pageref{codaz}. 
 | 
						||
 | 
						||
Vous trouverez dans le répertoire \texttt{tools/}\index{tools/}
 | 
						||
d'autres exemples de mise en œuvre de quelques fonctions disponibles
 | 
						||
sous formes d'outils en ligne de commande,
 | 
						||
lesquels outils sont approximativement décrits en page \pageref{outils}.
 | 
						||
 | 
						||
% ===================================================================
 | 
						||
\section{Installation}
 | 
						||
 | 
						||
Sauf indications contraires, ces instructions se réfèrent à
 | 
						||
une distribution Debian\index{Debian} récente (amd64 et x86),
 | 
						||
mais ça marche quasiment pareil avec Fedora\index{Fedora} 64,
 | 
						||
et
 | 
						||
probablement Raspbian\index{Raspbian}, modulo les éventuels
 | 
						||
soucis de boutisme que j'ai absolument négligés de prendre
 | 
						||
en compte.
 | 
						||
\textit{Attention, ça va devenir un peu gore\dots}
 | 
						||
 | 
						||
\subsection{Prérequis}
 | 
						||
 | 
						||
Vous devez, en dehors des outils classiques (gcc, Awk, make\dots), 
 | 
						||
avoir quelques bibliothèques installées~:
 | 
						||
\textsf{
 | 
						||
libv4l2, libpnglite, libtiff,
 | 
						||
libnetpbm\footnote{package libnetpbm10-dev},
 | 
						||
libz\footnote{package zlib1g-dev}, libcurses,
 | 
						||
libcfitsio...
 | 
						||
} % end of textsf
 | 
						||
éventuellement avec le \textsf{-dev} correspondant, qui contient, entre
 | 
						||
autres, les fichiers \texttt{.h} associés
 | 
						||
et probablement d'autres choses.
 | 
						||
 | 
						||
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.
 | 
						||
 | 
						||
Il faut aussi savoir où trouver le code. Il est dans le Git du
 | 
						||
Tetalab\footnote{\texttt{https://git.tetalab.org/tTh/FloatImg}}.
 | 
						||
Mais comme je ne comprend rien à Git, c'est pas la peine
 | 
						||
de m'envoyer des trucs genre \textsl{pull-request} auquels je ne
 | 
						||
comprend rien.
 | 
						||
 | 
						||
\subsection{Compilation}
 | 
						||
 | 
						||
La première chose à faire est d'aller regarder le contenu du fichier
 | 
						||
\texttt{Global.makefile} à la racine du projet. Il contient des
 | 
						||
informations pertinentes pour la suite des choses.
 | 
						||
Ensuite, un script \texttt{build.sh} permet de construire approximativement 
 | 
						||
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} qui est le source de la cible
 | 
						||
par défaut du make.
 | 
						||
 | 
						||
Pour le moment, la procédure d'installation est un peu rude,
 | 
						||
pour ne pas dire clairement sommaire.
 | 
						||
Si le résultat de l'étape compilation vous semble correct,
 | 
						||
vous pouvez copier les deux fichiers \texttt{floatimg.h} et
 | 
						||
\texttt{libfloatimg.a} dans un emplacement approprié, par exemple
 | 
						||
\texttt{/usr/local/include} et \texttt{/usr/local/lib}.
 | 
						||
 | 
						||
Le script \texttt{install.sh}, à la racine du projet, est censé
 | 
						||
faciliter un peu la chose. Il prend également en compte la copie
 | 
						||
des divers binaires du dossier \texttt{tools/} (cf page \pageref{outils})
 | 
						||
dans le répertoire prévu à cet effet~: \texttt{/usr/local/bin}.
 | 
						||
 | 
						||
Il reste enfin quelques exemples d'utilisation des outils de la
 | 
						||
ligne de commande depuis un shell
 | 
						||
dans le répertoire \texttt{scripts/}.
 | 
						||
Ils sont décrits plus en détail page
 | 
						||
\pageref{scripts}, et c'est à vous de les adapter à votre \textsl{usecase}.
 | 
						||
Faites-en ce que vous voulez.
 | 
						||
 | 
						||
% =================================================================
 | 
						||
 | 
						||
\section{Utilisation coté codeur}\label{codaz}
 | 
						||
 | 
						||
Classiquement, il y a un fichier \texttt{.h} à inclure dans chacun
 | 
						||
de vos codes source,
 | 
						||
\texttt{floatimg.h}, généralement logé dans \texttt{/usr/local/include}
 | 
						||
et contenant un certain nombre de définition de structures, de macros, 
 | 
						||
de constantes\footnote{À l'ancienne, via le pré-processeur} 
 | 
						||
et les prototypes des fonctions utilisables par vos logiciels.
 | 
						||
 | 
						||
Au niveau du code source, ces fonctions sont très 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 indécement arbitraire.
 | 
						||
D'autant plus qu'il y a aussi un répertoire nommé « experimental ».
 | 
						||
 | 
						||
\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{metadatas}) regroupées
 | 
						||
dans une jolie structure que nous allons examiner dès maintenant.
 | 
						||
 | 
						||
\label{FloatImg desc}
 | 
						||
 | 
						||
\begin{lstlisting}
 | 
						||
/*      in memory descriptor */
 | 
						||
typedef struct {
 | 
						||
        unsigned long   magic;
 | 
						||
        int             width;
 | 
						||
        int             height;
 | 
						||
        int             type;
 | 
						||
        float           fval;
 | 
						||
        int             count;
 | 
						||
        float           *R, *G, *B, *A;
 | 
						||
        int             reserved;
 | 
						||
        } FloatImg;
 | 
						||
\end{lstlisting}\index{FloatImg desc}
 | 
						||
 | 
						||
Le premier champ, \texttt{magic}, servira un de ces jours à
 | 
						||
robustifier l'ensemble du machin.
 | 
						||
Les deux suivants sont \textsl{obvious}.
 | 
						||
Le troisième est le type d'image : pour le moment, il y en a % trois
 | 
						||
un certain nombre
 | 
						||
qui sont définis\footnote{et plus ou moins bien gérés\dots} :
 | 
						||
gris, rgb et rgba/rgbz\index{rgba}\index{rgbz}.
 | 
						||
Les constantes adéquates sont déclarées dans \texttt{floatimg.h}~:
 | 
						||
 | 
						||
\begin{lstlisting}
 | 
						||
#define FIMG_TYPE_GRAY              1
 | 
						||
#define FIMG_TYPE_RGB               3
 | 
						||
#define FIMG_TYPE_RGBA              4
 | 
						||
#define FIMG_TYPE_RGBZ              99
 | 
						||
\end{lstlisting}
 | 
						||
 | 
						||
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 elle dérive
 | 
						||
d'idées approximatives. C'est cette utilisation constructive de larache
 | 
						||
qui fait que seuls les champs documentés de cette structure ne sont
 | 
						||
pas explosifs.
 | 
						||
 | 
						||
Mais revenons aux choses sérieuses\dots
 | 
						||
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 linéaire).
 | 
						||
Et que nous voulions cumuler\index{cumul}
 | 
						||
quelques images...
 | 
						||
 | 
						||
Le champ \textsl{count} sera mis à 0 et 
 | 
						||
le champ \textsl{fval} sera initialisé à 15.0
 | 
						||
(ce qui est la valeur maximale que peut renvoyer ce 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, puisque la valeur
 | 
						||
maximale théorique est égale à $fval * count$.
 | 
						||
 | 
						||
La fonction \texttt{fimg\_printhead(FloatImg *h)} affiche
 | 
						||
sommairement le contenu de ce descripteur,
 | 
						||
et \texttt{fimg\_describe(FloatImg *head, char *txt)} propose
 | 
						||
un affichage plus détaillé. Ça peut parfois aider.
 | 
						||
 | 
						||
Une bonne partie des fonctions que nous allons voir 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. Mais après tout, ce n'est
 | 
						||
encore qu'un concept en devenir, n'est-il pas ?
 | 
						||
 | 
						||
%		----------------------------------
 | 
						||
 | 
						||
\subsection{Les fondations}\index{lib/}
 | 
						||
 | 
						||
La première chose que nous devons absolument voir est la gestion
 | 
						||
dynamique de la mémoire qui sera occupée par tous ces pixels flottants,
 | 
						||
ce qui est un sujet parfois délicat\footnote{GC or not GC ?} parce que
 | 
						||
les pixels sont précieux et doivent être bien rangés.
 | 
						||
Cette gestion est donc faite, à la base, par ces deux fonctions~:
 | 
						||
 | 
						||
\begin{lstlisting}
 | 
						||
int fimg_create(FloatImg *fimg, int w, int h, int type);
 | 
						||
int fimg_destroy(FloatImg *fimg);
 | 
						||
\end{lstlisting}
 | 
						||
 | 
						||
L'appelant doit lui-même gérer le descripteur d'image (une structure
 | 
						||
C décrite plus haut) en le considérant comme un type semi-opaque dont
 | 
						||
la forme \emph{peut} varier, mais qu'il convient de mettre à zéro
 | 
						||
avant le moindre usage\footnote{\texttt{man 3 memset}}.
 | 
						||
Certains membres de cette structure sont
 | 
						||
documentés dans ce document, et les autres sont dangereux à
 | 
						||
toucher. Les types d'images actuellement gérés sont les trois grands
 | 
						||
classiques : niveau de gris, rouge-vert-bleu et rgb avec un canal alpha, 
 | 
						||
et expliquées quelques lignes plus haut.
 | 
						||
 | 
						||
XXX\index{XXX} raconter fimg\_clone
 | 
						||
 | 
						||
Comme vous allez le voir plus loin, il y a plein de fonctions qui
 | 
						||
prennent en argument deux images: la source et la destination.
 | 
						||
Dans la plupart des cas, ces deux images doivent être compatibles,
 | 
						||
c'est à dire de même type et de mêmes dimensions.
 | 
						||
 | 
						||
\begin{lstlisting}
 | 
						||
/* return 0 if pictures are compatible */
 | 
						||
int fimg_images_not_compatible(FloatImg *a, FloatImg *b);
 | 
						||
\end{lstlisting}
 | 
						||
 | 
						||
C'est bien beau d'être enfin une image résidente en mémoire centrale, mais
 | 
						||
pouvoir aussi exister à long terme en étant stocké dans la matrice
 | 
						||
est tout aussi pertinent.
 | 
						||
Il y a deux opérations qui supportent le reste des transits ram/ps.
 | 
						||
Le format de ces fichiers est décrit page \pageref{formatfimg}.
 | 
						||
 | 
						||
\begin{lstlisting}
 | 
						||
int fimg_dump_to_file(FloatImg *fimg, char *fname, int notused);
 | 
						||
int fimg_load_from_dump(char *fname, FloatImg *where);
 | 
						||
\end{lstlisting}
 | 
						||
 | 
						||
Recharger une image depuis un fichier nécessite que celle-ci et
 | 
						||
l'image de destination en mémoire 
 | 
						||
ait précisément les mêmes caractéristiques
 | 
						||
(taille, type...), donc l'image en mémoire centrale doit être
 | 
						||
pré-allouée. On peut connaitre ces valeurs en appelant
 | 
						||
\texttt{int fimg\_fileinfos(char *fname, int datas[3])}.
 | 
						||
 | 
						||
Si tout s'est bien passé (valeur retournée égale à 0),
 | 
						||
on va trouver la largeur dans \texttt{datas[0]},
 | 
						||
la hauteur dans \texttt{datas[1]} et le type dans
 | 
						||
\texttt{datas[2]}\footnote{La fonction
 | 
						||
\texttt{fimg\_type\_is\_valid(int type)} peut vous aider\dots}.
 | 
						||
 | 
						||
Je sais aussi que certains d'entre vous aiment la facilité, aussi
 | 
						||
je vais vous révéler l'existence d'un nouveau truc bien plus
 | 
						||
simple, une fonction qui enchaine ces deux actions
 | 
						||
(allocation, puis lecture), et s'utilise
 | 
						||
comme ça :
 | 
						||
 | 
						||
\begin{lstlisting}
 | 
						||
FloatImg       head;
 | 
						||
memset(&head, 0, sizeof(FloatImg));
 | 
						||
foo = fimg_create_from_dump("lena.fimg", &head);
 | 
						||
\end{lstlisting}
 | 
						||
 | 
						||
Si la valeur retournée est différente de 0, c'est que quelque
 | 
						||
chose s'est probablement mal passé.
 | 
						||
Certains messages sont parfois  explicites. Mais parfois non.
 | 
						||
Quand aux valeurs retournées en cas d'erreur, c'est le désordre
 | 
						||
intégral\footnote{Un vrai désastre, même...}.
 | 
						||
 | 
						||
% 	_________
 | 
						||
 | 
						||
\subsection{Dessiner}
 | 
						||
 | 
						||
Bon, vous avez en mémoire centrale une image latente,
 | 
						||
et vous souhaitez dessiner dessus (ou dedans ?) avec vos encres flottantes ?
 | 
						||
Il y a actuellement deux fonctions pour ça, légèrement différentes~:
 | 
						||
 | 
						||
\begin{lstlisting}
 | 
						||
int fimg_plot_rgb(FloatImg *head, int x, int y, float r, float g, float b);
 | 
						||
int fimg_put_rgb(FloatImg *head, int x, int y, float rgb[3]);
 | 
						||
\end{lstlisting}
 | 
						||
 | 
						||
Les paramètres sont explicites, mais leur validité doit être
 | 
						||
sévèrement controlée par l'appelant. Il y a une fonction 
 | 
						||
soeur, \texttt{fimg\_add\_rgb}\index{fimg\_add\_rgb},
 | 
						||
qui ajoute du rgb à un pixel, laquelle fonction a d'ailleurs été
 | 
						||
à la base de la seconde génération de la
 | 
						||
photographie\index{photographie} en cumul\index{cumul}.
 | 
						||
 | 
						||
Inversement, la fonction
 | 
						||
\texttt{fimg\_get\_rgb(FloatImg *head, int x, int y, float *rgb)}
 | 
						||
permet de lire les valeurs des trois canaux d'un pixel donné.
 | 
						||
Là aussi, il n'y a aucun contrôle sur la validité des valeurs
 | 
						||
$x$ et $y$ de la demande.
 | 
						||
 | 
						||
Quand au canal \textsl{alpha}\index{alpha}, il est pour le moment
 | 
						||
superbement ignoré. Ceci dit, on vient de me faire remarquer qu'il
 | 
						||
peut être utilisable aussi pour faire du
 | 
						||
\textsl{z-buffer}\index{z-buffer}\index{rgbz}, une technique
 | 
						||
classique dans la génération d'images en trois dimensions.\dots
 | 
						||
 | 
						||
%		----------------------------------
 | 
						||
 | 
						||
\subsection{Contraste}\index{contraste}\label{contraste}
 | 
						||
 | 
						||
Certaines opérations d'ajustement du contraste d'une image
 | 
						||
semblent cohérentes avec la notion d'image flottante.
 | 
						||
Certaines d'entre elles, les plus simples, sont disponibles.
 | 
						||
Les autres sont à imaginer.
 | 
						||
 | 
						||
\begin{figure}[h]
 | 
						||
\input{cos01.tex}				% XXX XXX XXX 
 | 
						||
\caption{Correcteur cos01}
 | 
						||
\end{figure}
 | 
						||
 | 
						||
Ils prennent chacun trois paramètres, d'abord les images
 | 
						||
source et destination (\texttt{* FloatImg}),
 | 
						||
ensuite le troisième
 | 
						||
qui est un nombre en double précision donnant la valeur
 | 
						||
maximale \textsl{supposée} de l'image source,
 | 
						||
valeur qui peut être déterminée de plusieurs manières.
 | 
						||
 | 
						||
\begin{lstlisting}
 | 
						||
/* 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);
 | 
						||
int fimg_cos_010(FloatImg *s, FloatImg *d, double maxval);
 | 
						||
\end{lstlisting}
 | 
						||
 | 
						||
 | 
						||
Si vous souhaitez rajouter votre propre méthode de modification
 | 
						||
de contraste, il y a quelques explication en page \pageref{exemplefunc}.
 | 
						||
Mais rien ne vous oblige à le faire. Sauf vos envies.
 | 
						||
 | 
						||
 | 
						||
\begin{figure}[h]
 | 
						||
\input{cos010.tex}				% XXX XXX XXX 
 | 
						||
\caption{Correcteur cos010}
 | 
						||
\end{figure}
 | 
						||
 | 
						||
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.
 | 
						||
 | 
						||
La fonction
 | 
						||
\texttt{fimg\_normalize(FloatImg *fi, double maxima, int notused);}
 | 
						||
tente de gérer ce cas d'utilisation. Son ajout au captureur d'images
 | 
						||
floues sera probablement le bienvenue. Je me suis bien rendu compte
 | 
						||
à l'usage\footnote{Une histoire de \textit{fonderie}, un logiciel
 | 
						||
censé faire des films flous à partir d'images floues} en situation
 | 
						||
festive qu'il manquait des données dans la chaine de traitement.
 | 
						||
 | 
						||
L'autre façon de procéder est d'explorer notre image à la
 | 
						||
recherche de la valeur maximale.
 | 
						||
La fonction \texttt{float fimg\_get\_maxvalue(\&fimg)} est
 | 
						||
prévue pour ça de façon sommaire.
 | 
						||
C'est actuellement la méthode utilisée par l'outil qui
 | 
						||
sert à faire les modifications de contraste (page \pageref{fimgfx}).
 | 
						||
On pourra aussi envisager d'utiliser 
 | 
						||
\texttt{fimg\_get\_minmax\_rgb(FloatImg *head, float mmvals[6])},
 | 
						||
qui permet un contrôle bien plus fin des dérives.
 | 
						||
 | 
						||
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. \textsl{Et c'est pas gagné...}
 | 
						||
 | 
						||
%		----------------------------------
 | 
						||
 | 
						||
\subsection{Géométrie}\index{géométrie}\label{geometrie}
 | 
						||
 | 
						||
Très prochainement, le retour du blitter\index{blitter}.
 | 
						||
Et pour attendre, un truc improbable, voire même
 | 
						||
inutile, en fait l'inverse de l'upscaling.
 | 
						||
 | 
						||
\begin{lstlisting}
 | 
						||
int fimg_halfsize_0(FloatImg *src, FloatImg *dst, int notused);
 | 
						||
int fimg_halfsize_1(FloatImg *src, FloatImg *dst, int notused);
 | 
						||
\end{lstlisting}
 | 
						||
 | 
						||
Attention lors de l'appel, le descripteur \texttt{dst} ne doit pas
 | 
						||
contenir d'image, et doit être effacé avec un bon
 | 
						||
\texttt{memset(\&result, 0, sizeof(FloatImg));} bien senti.
 | 
						||
 | 
						||
La première propose un résultat très moyen : il n'y a pas d'interpolation,
 | 
						||
alors que la seconde semble bien mieux.
 | 
						||
 | 
						||
\begin{lstlisting}
 | 
						||
int fimg_extract_0(FloatImg *src, FloatImg *dst, int x, int y);
 | 
						||
\end{lstlisting}
 | 
						||
 | 
						||
Contrairement à la fonction précédente, celle-ci demande absolument une
 | 
						||
image de destination initialisée aux dimensions (largeur et hauteur)
 | 
						||
désirées.
 | 
						||
 | 
						||
\begin{lstlisting}
 | 
						||
int fimg_rotate_90(FloatImg *src, FloatImg *dst, int notused);
 | 
						||
\end{lstlisting}
 | 
						||
 | 
						||
Rotation\index{rotation} de 90 degrés dans le sens
 | 
						||
horlogique\footnote{ou trigonométrique,le code et la doc
 | 
						||
ne semblent pas d'accord.} d'une image RGB.
 | 
						||
L'image de destination peut être soit vierge, soit pré-allouée
 | 
						||
aux bonnes dimensions (échange W et H).
 | 
						||
 | 
						||
%		----------------------------------
 | 
						||
 | 
						||
\subsection{Format du fichier \textsc{fimg}}\index{format}\label{formatfimg}
 | 
						||
 | 
						||
D'un design très empirique, c'est certainement à revoir pour l'avenir.
 | 
						||
La force du \textsl{legacy} va-t-elle dominer le monde ?
 | 
						||
Il faudrait normaliser l'endianess et le packing dans les
 | 
						||
structuress\footnote{Directives du compilateur ?}, et surtout l'ajout
 | 
						||
de données sur la prise de vue, du genre type de capteur, date et heure,
 | 
						||
réglages divers. Nous appelerons ça les metadonnées, et
 | 
						||
nous en parlons dans quelques pages.\dots
 | 
						||
 | 
						||
\begin{lstlisting}
 | 
						||
typedef struct {
 | 
						||
	char		magic[8];
 | 
						||
	int32_t		w, h, t;
 | 
						||
	} FimgFileHead;
 | 
						||
\end{lstlisting}
 | 
						||
 | 
						||
 | 
						||
Le champ \texttt{magic[8]} doit contenir une valeur magique~:
 | 
						||
les quatre premiers octets doivent contenir les quatre caractères
 | 
						||
\texttt{'FIMG'}, et les quatre derniers doivent être à 0, sauf que,
 | 
						||
voir plus bas, le cinquième vas vous étonner.
 | 
						||
Le champ \texttt{t} (le type de l'image) doit avoir les trois octets
 | 
						||
de poids fort à 0\footnote{Pourquoi ? Je n'en sais rien.}.
 | 
						||
 | 
						||
Ensuite, nous aurons (dans le cas courant) : 1, 2 ou 4 blocs
 | 
						||
de WxH pixels sous forme de Float32. La première ligne lue
 | 
						||
est la ligne du haut de l'image. Les valeurs négatives sont
 | 
						||
tolérées.
 | 
						||
 | 
						||
Vous trouverez les constantes de type pertinentes dans le
 | 
						||
fichier \texttt{floatimg.h}, et quelques informations
 | 
						||
(non-)essentielles qui ne vous serviront probablement à rien.
 | 
						||
 | 
						||
 | 
						||
%		----------------------------------
 | 
						||
% new février 2022
 | 
						||
 | 
						||
\subsection{Métadonnées}
 | 
						||
\index{metadata} \index{timestamp}
 | 
						||
 | 
						||
Attention, ce n'est pas encore une version définitive, beaucoup de
 | 
						||
choses restent à préciser sur le contenu de cette structure, mais
 | 
						||
l'essentiel est déja là. On reconnait un fichier avec metadata
 | 
						||
quand l'octet \texttt{magic[4]} du premier header est égal à
 | 
						||
la lettre \texttt{'a'}.
 | 
						||
 | 
						||
\begin{lstlisting}
 | 
						||
typedef struct {
 | 
						||
	char		magic[8];
 | 
						||
	struct timeval	timestamp;
 | 
						||
	int32_t		count;
 | 
						||
	float		fval;
 | 
						||
	char		idcam[32];
 | 
						||
	int32_t		origin;			// enum ?
 | 
						||
	} FimgMetaData;
 | 
						||
\end{lstlisting}
 | 
						||
 | 
						||
Voyons maintenant chacun des champs de cette structure, en prenant bien
 | 
						||
en compte qu'à ce moment\footnote{4 avril 2022}, tout n'est pas figé.
 | 
						||
Ceci dit, nous allons aussi retrouver de vieilles connaissances.
 | 
						||
 | 
						||
\textbf{to be continued}
 | 
						||
 | 
						||
%		----------------------------------
 | 
						||
 | 
						||
\subsection{Exportation \& Importation}\index{export}\label{export}
 | 
						||
 | 
						||
Notre format de fichier étant totalement inconnu%
 | 
						||
\footnote{Du monde extérieur, vous l'aurez compris.},
 | 
						||
il nous
 | 
						||
faut bien exporter nos images en quelque chose de plus
 | 
						||
connu. Bien entendu, c'est toujours affaire de compromis
 | 
						||
entre précision de valeurs et taille des fichiers.
 | 
						||
 | 
						||
Et dans le sens inverse, il serait bien de savoir importer
 | 
						||
le monde extérieur dans nos sombres caves à pixel.
 | 
						||
Il faut quand même reconnaitre que c'est un peu la jungle dans les
 | 
						||
formats de fichiers d'image, ce qui explique le retard
 | 
						||
du développement dans ce domaine\dots 
 | 
						||
 | 
						||
\subsubsection{Vers PNM}\index{PNM}
 | 
						||
 | 
						||
Nous avons ici 16 bits par composante, soit 65536 valeurs différentes,
 | 
						||
ce qui est bien au-delà de ce que peuvent percevoir vos yeux.
 | 
						||
Hélas, c'est au prix
 | 
						||
d'une taille énorme sur les fichiers. D'un autre coté,
 | 
						||
l'utilisation du codage \textsc{ascii}\index{ascii}
 | 
						||
(alors qu'on pourrait mettre du binaire, plus compact) y est
 | 
						||
pour quelque chose.
 | 
						||
 | 
						||
\begin{lstlisting}
 | 
						||
int fimg_save_as_pnm(FloatImg *head, char *fname, int flags);
 | 
						||
\end{lstlisting}
 | 
						||
 | 
						||
Le bit \texttt{0} du paramètre \texttt{flags} mis à \texttt{1} demande
 | 
						||
à la fonction de faire la mise à l'échelle avec le couple
 | 
						||
\textsl{fvalue/count} décrit plus haut dans cette doc.
 | 
						||
Et si il est à zéro, c'est la fonction de recherche de valeur
 | 
						||
maximale (cf page \pageref{contraste}) qui est utilisée.
 | 
						||
 | 
						||
Le bit \texttt{1} permettra bientôt\index{vaporware} de demander
 | 
						||
l'enregistrement de métadonnées\index{metadata} pertinentes, telle
 | 
						||
que l'epochtime de l'enregistrement.
 | 
						||
 | 
						||
Les autres bits ne sont pas utilisés et doivent être à zéro.
 | 
						||
 | 
						||
\subsubsection{Vers PNG}\index{PNG}
 | 
						||
 | 
						||
Actuellement, on ne peut enregistrer qu'en mode RGB uniquement,
 | 
						||
avec 8 bits par composante,
 | 
						||
mais on a quand même une bonne compression, ça compense.
 | 
						||
 | 
						||
J'utilise \textsl{libpnglite} avec qui j'ai un peu de mal à suivre.
 | 
						||
Mais je me soigne. Le mode 16 bits va bientôt arriver.
 | 
						||
On peut aussi songer à l'export des metadonnées, pour celles qui
 | 
						||
sont compatibles avec le standard PNG.
 | 
						||
 | 
						||
\begin{lstlisting}
 | 
						||
int fimg_save_as_png(FloatImg *src, char *outname, int flags);
 | 
						||
\end{lstlisting}
 | 
						||
 | 
						||
Tous les flags doivent être à zéro. Sinon, ça foire parfois.
 | 
						||
Et en fait (mars 2021) je ne suis pas très content de 
 | 
						||
\texttt{pnglite}, donc un de ces jours, je prendrais
 | 
						||
\sout{cinq} quelques jours pour
 | 
						||
régler ce souci en passant à la bibliothèque canonique.
 | 
						||
 | 
						||
\subsubsection{Vers TIFF}\index{TIFF}
 | 
						||
 | 
						||
Le format canonique de la PAO\index{PAO} du siècle dernier. Il permet
 | 
						||
de gérer une foultitude de formats numériques. C'est aussi un format
 | 
						||
classique proposé par les gros scanners corporates.
 | 
						||
 | 
						||
\begin{lstlisting}
 | 
						||
int fimg_write_as_tiff(FloatImg *src, char *outname, int flags);
 | 
						||
\end{lstlisting}
 | 
						||
 | 
						||
Tous les flags doivent être à zéro. Pour le moment.
 | 
						||
Un premier jet pas forcément parfait.
 | 
						||
 | 
						||
\subsubsection{Vers FITS}\index{FITS}
 | 
						||
 | 
						||
Ce format est essentiellement utilisé pour stocker des images
 | 
						||
d'astronomie, donc il peut aussi servir pour des images floues.
 | 
						||
Cette partie est basée sur la bibliothèque \texttt{cfitsio} de
 | 
						||
la NASA.
 | 
						||
 | 
						||
\begin{lstlisting}
 | 
						||
int fimg_save_R_as_fits(FloatImg *src, char *outname, int flags);
 | 
						||
int fimg_save_G_as_fits(FloatImg *src, char *outname, int flags);
 | 
						||
int fimg_save_B_as_fits(FloatImg *src, char *outname, int flags);
 | 
						||
\end{lstlisting}
 | 
						||
 | 
						||
Bizarrement, l'image est stockée \textsl{upside-down} et je ne
 | 
						||
sais pas encore comment régler ce petit détail. 
 | 
						||
 | 
						||
Tous les flags doivent être à zéro.
 | 
						||
 | 
						||
% =============================================================
 | 
						||
 | 
						||
\subsection{Utilitaires}
 | 
						||
 | 
						||
Commençons par quelques petits trucs pour nous faciliter la vie
 | 
						||
dans des domaines annexes,
 | 
						||
tels que l'interprétation d'arguments dans la ligne de commande ou un
 | 
						||
fichier de configuration.
 | 
						||
 | 
						||
\begin{lstlisting}
 | 
						||
int parse_WxH(char *str, int *pw, int *ph)
 | 
						||
int parse_double(char *str, double *dptr)
 | 
						||
\end{lstlisting}
 | 
						||
% XXX rjouter quelques explication, please !
 | 
						||
 | 
						||
La fonction \texttt{int format\_from\_extension(char *fname)} examine un
 | 
						||
nom de fichier tel que \texttt{lena.xxx}, et retourne, si la partie
 | 
						||
\texttt{xxx} est connue, un éventuel nombre positif, dont les valeurs sont
 | 
						||
déclarées dans floatimg.h
 | 
						||
le valeureux.
 | 
						||
Les extensions actuellement connues sont :
 | 
						||
fimg, png, pnm, pgm, fits et tiff. Le bmp est plus ou moins prévu\dots
 | 
						||
 | 
						||
To be continued\index{XXX}\dots
 | 
						||
 | 
						||
% =============================================================
 | 
						||
 | 
						||
\subsection{Effets}\index{sfx}
 | 
						||
 | 
						||
Quelques routines qui servent futilement à \textsl{brotcher} les images
 | 
						||
en tripotant les flux visuels chromatiques.
 | 
						||
 | 
						||
\begin{lstlisting}
 | 
						||
int fimg_killcolors_a(FloatImg *fimg, float fval);
 | 
						||
int fimg_killcolors_b(FloatImg *fimg, float fval);
 | 
						||
int fimg_colors_mixer_a(FloatImg *fimg, float fval);
 | 
						||
\end{lstlisting}
 | 
						||
 | 
						||
\subsection{Glitches}\index{glitch}
 | 
						||
 | 
						||
Un \textsl{glitch} peut-il être classé dans la catégorie des effets
 | 
						||
spéciaux ou non ? \textsc{Hmha}, non. un fx est paramétrable
 | 
						||
et surtout répétitif. Un glitch est quasiment souvent un phénomène
 | 
						||
aléatoire\index{drand48} et tout aussi paramétrable.
 | 
						||
 | 
						||
J'ai commencé à étudier ces objets étranges quand j'ai commencé
 | 
						||
à travailler sur l'interpolator\index{interpolator} à l'automne 2020.
 | 
						||
Hélas, j'ai vite réalisé que c'était assez délicat.
 | 
						||
Pour ce genre de \textsl{usecase}, le numérique est pitoyable si on
 | 
						||
le compare au (hélas défunt) \textsc{Betamax}\index{Betamax}.
 | 
						||
 | 
						||
% =============================================================
 | 
						||
 | 
						||
\subsection{Filtrages}\index{filtrage}
 | 
						||
 | 
						||
Pour commencer, il faut que je réfléchisse au traitement
 | 
						||
des bordures des images.
 | 
						||
Ensuite que je débuggue\index{bug} ces deux fonctions~:
 | 
						||
 | 
						||
\begin{lstlisting}
 | 
						||
int fimg_lissage_2x2(FloatImg *img);
 | 
						||
int fimg_killborders(FloatImg *img);
 | 
						||
\end{lstlisting}
 | 
						||
 | 
						||
Bon, oké, ça marche ? Passons à l'étape suivante. 
 | 
						||
La convolution avec une matrice 3x3, c'est possible.
 | 
						||
Et pas trop compliqué à faire.
 | 
						||
Bon, il reste le souci avec les bordures, souci qui ne peut
 | 
						||
être que temporaire, mais ésotérique à fixer.
 | 
						||
 | 
						||
Passons maintenant aux choses sérieuses, et définissons la
 | 
						||
description d'un filtre 3x3. 
 | 
						||
 | 
						||
\begin{lstlisting}
 | 
						||
typedef struct {
 | 
						||
        float                matrix[9];
 | 
						||
        float                mult;
 | 
						||
        float                offset;
 | 
						||
        } FimgFilter3x3;
 | 
						||
\end{lstlisting}
 | 
						||
 | 
						||
L'usage des champs \texttt{mult} et \texttt{offset} n'est pas
 | 
						||
clairement défini. Le prototype de la fonction de filtrage
 | 
						||
non plus, mais assez simple quand même. Source et destination
 | 
						||
ne peuvent désigner la même image, et le champ \texttt{matrix}
 | 
						||
du filtre doit contenir des valeurs cohérentes.
 | 
						||
 | 
						||
\begin{lstlisting}
 | 
						||
int fimg_filter_3x3(FloatImg *src, FloatImg *dst, FimgFilter3x3 *filtr)
 | 
						||
\end{lstlisting}
 | 
						||
 | 
						||
Comme dans la plupart des cas, la gestion des valeurs négatives
 | 
						||
de pixel est laissé au hasard, qui fait souvent du portnawak.
 | 
						||
Quoique, il doit bien exister
 | 
						||
quelques solutions de contournement :
 | 
						||
valeur absolue, clamping ou shiftup ?
 | 
						||
 | 
						||
\textsl{To be continued\index{XXX}\dots}
 | 
						||
 | 
						||
%		----------------------------------
 | 
						||
 | 
						||
\subsection{Exemple de fonction}\index{exemple}\label{exemplefunc}
 | 
						||
 | 
						||
Nous allons maintenant écrire une fonction intégrable dans
 | 
						||
le répertoire \texttt{funcs/}.
 | 
						||
Elle aura donc accès aux \textsl{internals}%
 | 
						||
\footnote{que je peux décider de changer n'importe quand}
 | 
						||
de \textsc{FloatImg},
 | 
						||
une chose qui est en principe interdite aux programmes
 | 
						||
\textsl{enduser}. Soyez donc prudents.
 | 
						||
 | 
						||
Cette fonction va faire quelque chose
 | 
						||
à partir d'une image source et d'une valeur, et écrire le
 | 
						||
résultat dans une image de destination.
 | 
						||
Pour simplifier les choses, nous n'allons traiter que les
 | 
						||
images de type \textsc{FIMG\_TYPE\_RGB}, de loin le plus
 | 
						||
répandu par les temps qui courent.
 | 
						||
 | 
						||
\begin{lstlisting}
 | 
						||
int fimg_example(FloatImg *s, FloatImg *d, float value)
 | 
						||
{
 | 
						||
int     size, index;
 | 
						||
 | 
						||
if ( s->type!=FIMG_TYPE_RGB || d->type!=FIMG_TYPE_RGB) {
 | 
						||
        perror("fimg_example");
 | 
						||
        return -1;
 | 
						||
        }
 | 
						||
 | 
						||
size = s->width * s->height;
 | 
						||
for (idx=0; idx<size; idx++) {
 | 
						||
        d->R[idx] = s->R[idx] - value;
 | 
						||
        d->G[idx] = s->G[idx] - value;
 | 
						||
        d->B[idx] = s->B[idx] - value;
 | 
						||
        }
 | 
						||
 | 
						||
return 0;
 | 
						||
}
 | 
						||
\end{lstlisting}
 | 
						||
 | 
						||
Je vous laisse imaginer les dégats que peut faire cette 
 | 
						||
fonction en utilisation réelle. Mieux, je vous propose
 | 
						||
d'essayer par vous-même, vous allez voir, c'est assez créatif.
 | 
						||
En particulier tout le reste du code qui suppose qu'un pixel
 | 
						||
ne peut \textbf{pas} être négatif va peut-être exploser de rire.
 | 
						||
Vous pouvez aussi remarquer qu'il n'y a pas de controle
 | 
						||
de cohérence sur les dimensions des deux images, malgré l'existence
 | 
						||
de fonctions prévues à cet effet, mais il fallait rester simple\dots
 | 
						||
 | 
						||
 | 
						||
% ===================================================================
 | 
						||
\section{Les outils}\label{outils}
 | 
						||
 | 
						||
\textsf{3615mavie} : pour des projets comme celui-ci, qui travaillent
 | 
						||
\textit{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 des compilations.}
 | 
						||
et construire
 | 
						||
des briques de base qui mettent en action le code primitif pour
 | 
						||
partir sur des bases stables, documentées (ahem\dots), et
 | 
						||
directement utilisables.
 | 
						||
 | 
						||
Ces cliwares\index{cliware} ont en commun quelques options bien pratiques~:
 | 
						||
\texttt{-h} pour avoir un résumé des options disponibles,
 | 
						||
\texttt{-v} qui augmente la puissance de bavardage, et
 | 
						||
\texttt{-K nn.nn} pour un paramètre flottant.
 | 
						||
Dans un avenir incertain, il existera des pages de man\index{man}.
 | 
						||
 | 
						||
%		---------------------
 | 
						||
 | 
						||
\subsection{mkfimg}\index{mkfimg}\label{mkfimg}
 | 
						||
 | 
						||
Propose la création d'un fichier contenant une image de « teinte »
 | 
						||
constante (ou pas).
 | 
						||
Cette notion de teinte est assez inconsistante pour le moment,
 | 
						||
mais ça n'est pas si grave que ça.
 | 
						||
 | 
						||
\begin{verbatim}
 | 
						||
tth@debian:~/Devel/FloatImg/tools$ ./mkfimg -h
 | 
						||
Usage:  mkfimg [options]  quux.fimg width height
 | 
						||
        -k N.N  give a float parameter
 | 
						||
        -t type         howto make the pic
 | 
						||
                        black, drand48...
 | 
						||
        -v      increase verbosity
 | 
						||
\end{verbatim}
 | 
						||
 | 
						||
Il y a deux syntaxes possibles pour les dimensions de l'image générée~:
 | 
						||
deux nombres séparés ou la notation \texttt{WIDTHxHEIGHT}.
 | 
						||
 | 
						||
La plupart des types d'image générée prennent un paramètre flottant qui
 | 
						||
devra être donné avec l'option \texttt{-k F.F} avec une valeur par défaut
 | 
						||
à $1.0$, ce qui n'est pas toujours une bonne valeur, ymmv\index{ymmv}.
 | 
						||
 | 
						||
\begin{description}	\index{XXX}
 | 
						||
\item [black/gray/grey:] efface avec 0.0 (black) ou avec la valeur
 | 
						||
		\texttt{-k} (niveau de gris).
 | 
						||
\item [drand48:] beaucoup de bruit dans chacun des canaux.
 | 
						||
\item [hdeg/vdeg:] dégradé du noir au blanc (relatif à \texttt{-k}).
 | 
						||
\end{description}
 | 
						||
 | 
						||
%		---------------------
 | 
						||
 | 
						||
\subsection{png2fimg}\index{png2fimg}\label{png2fimg}
 | 
						||
 | 
						||
Grosse panne\index{bug} à 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 peut-être envisager le passage à \texttt{libpng}\index{libpng},
 | 
						||
la bibliothèque actuellement utilisée (\texttt{pnglite}) ayant tendance
 | 
						||
à borker en lecture sur certains fichiers pourtant corrects.
 | 
						||
 | 
						||
%		---------------------
 | 
						||
 | 
						||
\subsection{fimgstats}\index{fimgstats}\label{fimgstats}
 | 
						||
 | 
						||
Affichage de quelques valeurs calculées à partir du contenu d'un fichier
 | 
						||
\texttt{.fimg}\index{.fimg}.
 | 
						||
 | 
						||
\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
 | 
						||
en première approche, alors commençont par le plus simple,
 | 
						||
les valeurs moyennes de chaque composante.
 | 
						||
 | 
						||
Puis nous rajouterons\footnote{Les patchs sont les bienvenus}
 | 
						||
le calcul de la variance\index{variance}. Les compétences
 | 
						||
de \texttt{schmod777} sont attendues au dd2\index{dd2}.
 | 
						||
 | 
						||
%		---------------------
 | 
						||
 | 
						||
\subsection{fimgfx}\index{fimgfx}\label{fimgfx}
 | 
						||
 | 
						||
Ce programme, \textit{en cours de création\index{XXX}}, applique
 | 
						||
un effet spécial à une image.
 | 
						||
À l'heure actuelle\footnote{janvier 2019, vers 13:37}, nous avons
 | 
						||
déja quelques ajustements basiques de contraste, qui ne tiennent
 | 
						||
pas vraiment compte du contenu de l'image.
 | 
						||
 | 
						||
\begin{verbatim}
 | 
						||
tth@daubian:~/Devel/FloatImg/tools$ ./fimgfx -v -h
 | 
						||
--- fimg special effects ---
 | 
						||
        cos01 cos010 pow2 sqrt gray0 cmixa xper desat
 | 
						||
\end{verbatim}
 | 
						||
 | 
						||
Certaines de ces opérations ont besoin d'un paramètre flottant.
 | 
						||
Celui-ci peut être fixé avec l'option \texttt{-k}.
 | 
						||
Une liste détaillée des opérations possibles
 | 
						||
sera lisible avec le sélecteur \texttt{-L}.
 | 
						||
 | 
						||
\begin{description}
 | 
						||
\item [Ajustements de contraste:] cos01 cos010 pow2 sqrt
 | 
						||
\item [Distorsions chromatiques:] gray0
 | 
						||
\item [Déformations géométriques:] r90
 | 
						||
\end{description}
 | 
						||
 | 
						||
Et pour les aventureux, la commande \texttt{xper} (abréviation
 | 
						||
de \textsl{expérimental}) permet de tester la plus récente tentative
 | 
						||
de friture du moment. D'autre part un set bien plus complet d'effets
 | 
						||
àlc est disponible dans les logiciels de flou temporel, décrits
 | 
						||
plus loin dans ce document.
 | 
						||
 | 
						||
%		---------------------
 | 
						||
 | 
						||
\subsection{fimgops}\index{fimgops}\label{fimgops}
 | 
						||
 | 
						||
Quelques opérations diverses entre deux images, qui doivent être
 | 
						||
de la même taille, et uniquement du type \textsl{RGB}. Certaines
 | 
						||
de ces opérations peuvent avoir un effet étrange sur vos images,
 | 
						||
par exemple si un pixel se retrouve avec une valeur négative.
 | 
						||
 | 
						||
\begin{verbatim}
 | 
						||
usage:
 | 
						||
        fimgops [options] A.fimg B.fimg operator D.fimg
 | 
						||
operators:
 | 
						||
        add             1
 | 
						||
        sub             2
 | 
						||
        mix             3
 | 
						||
        mul             4
 | 
						||
        mini            5
 | 
						||
        maxi            6
 | 
						||
options:
 | 
						||
        -g              convert output to gray
 | 
						||
        -k N.N          set float value
 | 
						||
        -v              increase verbosity
 | 
						||
        -X              explosive action
 | 
						||
\end{verbatim}
 | 
						||
 | 
						||
Pour des operateurs paramétrable (comme \texttt{mix}), le paramêtre
 | 
						||
flottant doit être fourni en utilisant l'option \texttt{-k}.
 | 
						||
La véracité mathématique n'est pas garantie. Et n'oubliez pas que
 | 
						||
les valeurs négatives peuvent être la cause de \textsl{glitches}
 | 
						||
de qualitay.
 | 
						||
 | 
						||
La liste des opérations est susceptible d'être agrémenté de quelques
 | 
						||
possibilités bien féroces\footnote{Stay tuned, flim at 11.}.
 | 
						||
 | 
						||
%		-------------------------
 | 
						||
 | 
						||
\subsection{fimg2png, fimg2pnm, fimg2tiff, fimg2fits}
 | 
						||
		\index{fimg2png}\label{fimg2png}
 | 
						||
		\index{fimg2pnm}\label{fimg2pnm}
 | 
						||
		\index{fimg2tiff}\label{fimg2tiff}
 | 
						||
		\index{fimg2fits}\label{fimg2fits}
 | 
						||
 | 
						||
Quelques petits proggies pour exporter notre format\index{.fimg} secret
 | 
						||
vers des choses plus directement utilisables. À condition que le
 | 
						||
code soit écrit et documenté.
 | 
						||
 | 
						||
D'un autre coté, écrire un greffon d'import/export pour
 | 
						||
Gimp\index{Gimp} ou ImageMagick\index{ImageMagick} ou Krita\index{krita}
 | 
						||
ne devrait pas être trop difficile. Des volontaires ?
 | 
						||
 | 
						||
D'ailleurs, pourquoi $N$ logiciels indépendants alors q'un
 | 
						||
seul devrait être nécessaire ?, ce qui me conduit à envisager
 | 
						||
un \textsl{exporter} universel, mais dont l'ergonomie et les
 | 
						||
paramètres possibles doivent être réfléchis avec vigueur et nonchalance.
 | 
						||
 | 
						||
%		-------------------------
 | 
						||
 | 
						||
\subsection{fimg2text}
 | 
						||
 | 
						||
Voici donc quelque chose qui retourne vers la bonne vieille
 | 
						||
tradition Unix\index{Unix} et permet de traiter des images
 | 
						||
flottantes avec des outils classiques comme l'injustement
 | 
						||
méconnu \texttt{Awk}\index{Awk}.
 | 
						||
Dans le comportement par défaut (le seul actuellement) cet outil
 | 
						||
sort, pour chaque pixel, cinq valeurs~:
 | 
						||
 | 
						||
\begin{itemize}
 | 
						||
   \item Les coordonnées entières $x,y$ du pixel
 | 
						||
   \item Les valeurs flottantes des composantes \textsc{rgb}
 | 
						||
\end{itemize}
 | 
						||
 | 
						||
On peut même espérer qu'un jour, il soit possible de faire 
 | 
						||
la transformation inverse. Quelle joie de générer des images
 | 
						||
flottantes avec un programme écrit en \textit{gw-basic} :)
 | 
						||
 | 
						||
\begin{verbatim}
 | 
						||
tth@fubar:~/Devel/FloatImg/doc$ fimg2text -h
 | 
						||
usage:
 | 
						||
        fimg2text [options] foo.fimg > bar.csv
 | 
						||
options:
 | 
						||
        -v              increase verbosity
 | 
						||
        -n 3.14         normalize picture
 | 
						||
        -s N            steps on x & y
 | 
						||
\end{verbatim}
 | 
						||
 | 
						||
Vous voulez un petit exemple ?
 | 
						||
 | 
						||
\begin{verbatim}
 | 
						||
tth@fubar:~/Devel/FloatImg/doc$ mkfimg -t drand48 quux.fimg 4 2
 | 
						||
tth@fubar:~/Devel/FloatImg/doc$ fimg2text -s 1 quux.fimg
 | 
						||
0 0 142.518127 84.036987 20.688946
 | 
						||
1 0 164.273315 68.397079 138.501587
 | 
						||
2 0 45.887970 25.905518 93.683243
 | 
						||
3 0 53.292942 222.000000 111.711548
 | 
						||
0 1 82.289795 113.054855 180.530014
 | 
						||
1 1 42.051765 114.543625 4.249123
 | 
						||
2 1 71.826775 96.219109 63.222294
 | 
						||
3 1 160.535675 136.104919 204.020691
 | 
						||
tth@fubar:~/Devel/FloatImg/doc$ 
 | 
						||
\end{verbatim}
 | 
						||
 | 
						||
Et maintenant, vous voulez un gros exemple ? Bah, ça doit demander
 | 
						||
l'utilisation de Povray\index{Povray}.
 | 
						||
 | 
						||
 | 
						||
%		-------------------------
 | 
						||
 | 
						||
%   beaucoup trop de maths approximative dans ce passage.
 | 
						||
 | 
						||
\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,
 | 
						||
voire même tenter de les faire se rencontrer, se combiner et
 | 
						||
s'influencer mutuellement.
 | 
						||
 | 
						||
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.
 | 
						||
\index{procrastination}
 | 
						||
Et face à l'incertitude du choix, j'ai reporté l'écriture de ce
 | 
						||
logiciel aux calendes grecques, voire même plus tard,
 | 
						||
après la grande pandémie\dots
 | 
						||
 | 
						||
%		-------------------------
 | 
						||
 | 
						||
\subsection{cumulfimgs}\index{cumulfimgs}\label{cumulfimgs}
 | 
						||
 | 
						||
Cet outil accumule\index{cumul} une quantité d'images flottantes
 | 
						||
(de même taille et de même type) afin d'obtenir
 | 
						||
un flou temporel de meilleure qualité.
 | 
						||
Aucune mise à l'échelle n'etant
 | 
						||
effectuée, les pixels de sortie peuvent atteindre des valeurs
 | 
						||
considérables\footnote{Faut-il prévoir une gestion des \textsf{overflows} ?}
 | 
						||
 | 
						||
\begin{verbatim}
 | 
						||
tth@delirium:~/Devel/FloatImg/tools$ ./cumulfimgs -h
 | 
						||
usage :
 | 
						||
        cumulfimgs a.fimg b.fimg c-fimg ...
 | 
						||
cumulator options :
 | 
						||
        -v      increase verbosity
 | 
						||
        -o      name of output file
 | 
						||
        -g      convert to gray level
 | 
						||
\end{verbatim}
 | 
						||
 | 
						||
Le nom par défaut du fichier résultant est \texttt{out.fimg}.
 | 
						||
L'exportation « multiformat » est enfin fonctionnelle, dans la
 | 
						||
mesure des formats connus.
 | 
						||
 | 
						||
% ===================================================================
 | 
						||
\section{Debug}\index{Debug}
 | 
						||
 | 
						||
\textit{Et quand plus rien ne fonctionne normalement ?}
 | 
						||
 | 
						||
Ayant une attirance marquée pour la méthode de développement dite
 | 
						||
de \textsl{larache}, que je pratique intensément, j'ai quand même
 | 
						||
besoin de m'équiper de quelques garde-fous. Avec l'expérience, j'ai
 | 
						||
découvert quelques méthodes bien utile quand on est à court de
 | 
						||
poudre verte.
 | 
						||
 | 
						||
\subsection{À la compilation}
 | 
						||
 | 
						||
Première de cordée, la méthode \texttt{DEBUG\_LEVEL}\index{DEBUG\_LEVEL}.
 | 
						||
Elle me sert
 | 
						||
essentiellement à tracer les appels de fonctions, et les paramètres
 | 
						||
qu'elles reçoivent. Ça fait vraiment partie de la création
 | 
						||
des \textsl{boiler-plates}.
 | 
						||
C'est une valeur numérique entière définie dans chaque
 | 
						||
\texttt{Makefile}\index{Makefile}
 | 
						||
qui sera ensuite utilisée
 | 
						||
par le préprocesseur afin de rajouter ce genre de code dans l'exécutable~:
 | 
						||
 | 
						||
\begin{verbatim}
 | 
						||
int fimg_export_picture(FloatImg *pic, char *fname, int flags)
 | 
						||
{
 | 
						||
int		filetype, foo;
 | 
						||
#if DEBUG_LEVEL
 | 
						||
fprintf(stderr, ">>> %s ( %p '%s' 0x%X )\n", __func__, pic, fname, flags);
 | 
						||
#endif
 | 
						||
...
 | 
						||
\end{verbatim}
 | 
						||
 | 
						||
Le principe est simple, n'est-il pas, alors pourquoi s'en priver ?
 | 
						||
Bien entendu, la même constante peut être utilisée plus agressivement
 | 
						||
avec une condition comme \texttt{\#if DEBUG\_LEVEL > 2} permettant
 | 
						||
de générer encore plus de messages traçants.
 | 
						||
 | 
						||
Ensuite, pour les cas les plus graves, qui nécessiteront l'utilisation
 | 
						||
du dévermineur \texttt{gdb}\index{gdb}, il y a la directive
 | 
						||
\texttt{MUST\_ABORT} qui est bien plus violente, mais parfois bien
 | 
						||
pratique. Voici le cas classique d'utilisation~:
 | 
						||
 | 
						||
\begin{verbatim}
 | 
						||
foo = fimg_strange_function(&picture, 13.37);
 | 
						||
if (foo) {
 | 
						||
        fprintf(stderr, "epic fail %d in %s\n", foo, __func__);
 | 
						||
#if MUST_ABORT
 | 
						||
        abort();
 | 
						||
#endif
 | 
						||
...
 | 
						||
\end{verbatim}
 | 
						||
 | 
						||
À condition d'avoir bien réglé votre ulimit pour la génération d'un coredump,
 | 
						||
vous aurez sous la main un fichier \texttt{core} qui vous permettra
 | 
						||
de, par exemple, remonter la pile d'appel avec la commande \texttt{back} de
 | 
						||
gdb. Mais pour le moment, juste une infime partie du code est instrumentée
 | 
						||
avec ce dispositif.
 | 
						||
 | 
						||
 | 
						||
\subsection{À l'exécution}
 | 
						||
 | 
						||
De l'utilisation des nombres magiques dans la détection des structures
 | 
						||
corrompues par un pointeur ayant perdu le nord\dots
 | 
						||
 | 
						||
De l'utilisation des variables d'environnement pour transformer des warnings
 | 
						||
en erreurs fatales\dots
 | 
						||
 | 
						||
% ===================================================================
 | 
						||
\section{TODO}\index{TODO}\label{TODO}\
 | 
						||
		\index{XXX}
 | 
						||
 | 
						||
Il reste plein de choses à faire pour que ce soit vraiment utilisable,
 | 
						||
surtout dans un contexte artistique à grande porosité.
 | 
						||
C'est par ces frottements de techniques ayant du sens que les
 | 
						||
choses seront acquises, pour le pire, le meilleur et la
 | 
						||
techno-futilité du monde futur..
 | 
						||
 | 
						||
\begin{itemize} 
 | 
						||
\item	Import/export au format \textsc{tiff}\index{TIFF} à continuer.
 | 
						||
\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. \textbf{Urgent}.
 | 
						||
\item	Faire une passe complète de Valgrind\index{valgrind}.
 | 
						||
\item	Intégrer la fonderie, l'interpolator et le singlepass.
 | 
						||
\item	Vérifier le gestion des images mono-canal et de la transparence.
 | 
						||
\end{itemize}
 | 
						||
 | 
						||
% ===================================================================
 | 
						||
\section{Exemples pour yusers}\index{exemple}
 | 
						||
 | 
						||
Nous allons \textsl{essayer d'improviser} un exemple presque réel,
 | 
						||
avec un peu de rache\index{rache} dedans, et beaucoup de simplification.
 | 
						||
Ce qui est autorisé dans les exemples, mais dans la vrai vie, il ne faut
 | 
						||
jamais négliger le traitement des éventuelles erreurs.
 | 
						||
 | 
						||
Nous savons générer une image contenant des pixels aux valeurs
 | 
						||
probablement aléatoires, avec la commande \texttt{mkfimg},
 | 
						||
qui utilise le \texttt{drand48}\index{drand48} de \textsc{posix}\index{POSIX}.
 | 
						||
Maintenant, posons-nous une question de statisticien : que se passe-t-il si 
 | 
						||
nous faisons la somme de plusieurs centaines de ces images ?
 | 
						||
 | 
						||
\begin{lstlisting}
 | 
						||
#!/bin/bash
 | 
						||
ACCU="quux.fimg"
 | 
						||
TMPF="tmp.fimg"
 | 
						||
DIMS="320 240"
 | 
						||
mkfimg $ACCU $DIMS
 | 
						||
for i in {0..1000}
 | 
						||
do
 | 
						||
        mkfimg -t drand48 ${TMPF} ${DIMS}
 | 
						||
        fname=$( printf "xx%04d.pnm" $i )
 | 
						||
        fimgops $ACCU $TMPF add $ACCU
 | 
						||
        fimg2pnm -v -g $ACCU $fname
 | 
						||
done
 | 
						||
convert -delay 10 xx*.pnm foo.gif
 | 
						||
\end{lstlisting}
 | 
						||
 | 
						||
Voilà, si les choses se passent mal, vous allez découvrir
 | 
						||
que votre \texttt{drand48} n'est pas si "drand" que ça. 
 | 
						||
Et ce n'est pas à moi d'en tirer les conclusions...
 | 
						||
 | 
						||
\subsection{Scripts}\index{scripts}\label{scripts}
 | 
						||
 | 
						||
Le script bash\index{bash} \texttt{scripts/shoot.sh} est un front-end
 | 
						||
encore un peu rudimentaire
 | 
						||
vers le programme de capture d'image décrit page \pageref{grabvidseq}.
 | 
						||
Il utilise deux fichiers dans le répertoire de travail~:
 | 
						||
\textit{reglages} et \textit{compteur}. Le premier est, en fait,
 | 
						||
un bout de shell affectant quelques variables, ou plutôt, les surchargeant.
 | 
						||
 | 
						||
Voici un exemple de réglage~:
 | 
						||
 | 
						||
\begin{lstlisting}
 | 
						||
OPTIONS="${OPTIONS} -v -c pow2 "
 | 
						||
SHOW="yes"
 | 
						||
NBRE=1000
 | 
						||
PERIOD=0
 | 
						||
OFORMAT="p_%04d.png"
 | 
						||
\end{lstlisting}
 | 
						||
 | 
						||
La première ligne demande, en plus des options par défaut, plus de
 | 
						||
bavardage, et un changement de contraste. La seconde demande
 | 
						||
l'affichage de la photo. Les deux suivantes demandent la
 | 
						||
capture de 1000 images à la cadence méga-blast.
 | 
						||
La dernière est moins simple~: \texttt{man sprintf}\index{printf}
 | 
						||
pour comprendre.
 | 
						||
 | 
						||
Quand au second fichier, il contient un compteur (stocké en ascii) qui
 | 
						||
est incrémenté après chaque capture réussie. Et ce compteur est
 | 
						||
utilisable par la variable \texttt{OFORMAT} que nous avons
 | 
						||
vue quelques lignes plus haut. 
 | 
						||
 | 
						||
\lstinputlisting[language=sh]{../scripts/shoot.sh}
 | 
						||
 | 
						||
\subsection{Fonderie}\index{fonderie}\label{fonderie}
 | 
						||
 | 
						||
Ce projet externe\footnote{... pour le moment, j'ai des soucis sur
 | 
						||
l'architecture du \textbf{pipdeprod} à adopter\dots} est destiné à la confection
 | 
						||
de films flous\index{film} à partir de photos floues.
 | 
						||
Le script \texttt{scripts/echomix.sh} est une première expérimentation
 | 
						||
en bash, utilisant deux outils en \textsc{cli},
 | 
						||
le premier pouvant salement brotcher une image, et le second capable de
 | 
						||
mélanger harmonieusement deux images, la balance est équilibrée.
 | 
						||
 | 
						||
Il s'agit donc d'un petit programme écrit en Bash\index{bash}, un langage
 | 
						||
dont la connaissance est, pour moi, indispensable à qui veut faire des
 | 
						||
images kitchies\index{kitchy}. Mais ne vous inquiétez pas, c'est en
 | 
						||
fait assez simple à comprendre. Et comprendre, c'est apprendre.
 | 
						||
 | 
						||
Voici donc le script, décomposé et expliqué :
 | 
						||
 | 
						||
\begin{verbatim}
 | 
						||
#!/bin/bash
 | 
						||
 | 
						||
SRCDIR="Fist"
 | 
						||
DSTDIR="Pong"
 | 
						||
FTMP="/dev/shm/tmp.fimg"
 | 
						||
FDST="/dev/shm/foo.fimg"
 | 
						||
 | 
						||
# count the nomber of picz in the source directory
 | 
						||
NBRE=$(ls -1 ${SRCDIR}/*.fimg | wc -l)
 | 
						||
# compute the echo picz offset
 | 
						||
OFFS=$(( NBRE / 4 ))
 | 
						||
\end{verbatim}
 | 
						||
 | 
						||
 | 
						||
Dans ce préliminaire logiciel, nous avons nommé le répertoire
 | 
						||
\textsc{srcdir} contenant les captures d'image au format fimg, le répertoire
 | 
						||
\textsc{dstdir} dans lequel seront rangées les images calculées,
 | 
						||
et l'emplacement de deux fichiers de travail, placés dans ce qui
 | 
						||
peut être vu comme un \textsl{ramdisk}\index{ramdisk}\index{/dev/shm/}
 | 
						||
et qui accélère un peu les opérations.
 | 
						||
 | 
						||
Les quelques lignes suivantes, qui semble bien magiques, ne sont en fait
 | 
						||
que de la magie Unix\index{Unix}. Elles nous permettent d'avoir
 | 
						||
\textsc{nbre}, le nombre d'images à traiter, et \textsc{offs}, un décalage
 | 
						||
dépendant du nombre d'image. Muni de toutes ces informations, nous
 | 
						||
pouvons rentrer dans le lard du sujet, la boucle qui travaille.
 | 
						||
 | 
						||
 | 
						||
\begin{verbatim}
 | 
						||
#                                             MAIN LOOP
 | 
						||
for idx in $(seq 0 $NBRE)
 | 
						||
do
 | 
						||
        # build the two input filenames ...
 | 
						||
        #
 | 
						||
        imgA=$(printf "$SRCDIR/%04d.fimg" $idx)
 | 
						||
        vb=$(( $(( idx + OFFS )) % NBRE))
 | 
						||
        imgB=$(printf "$SRCDIR/%04d.fimg" $vb)
 | 
						||
 | 
						||
        #        ... and the output filename
 | 
						||
        #
 | 
						||
        dst=$(printf "%s/%05d.png" ${DSTDIR} $idx)
 | 
						||
\end{verbatim}
 | 
						||
 | 
						||
Dans cette première partie de la boucle nous avons construit plusieurs
 | 
						||
noms de fichier à partir du rang de la boucle en cours d'exécution,
 | 
						||
des deux valeurs \textsc{nbre} et \textsc{offs} calculées en préambule.
 | 
						||
 | 
						||
\begin{verbatim}
 | 
						||
        # trying to autocompute the mixing coefficient
 | 
						||
        #
 | 
						||
        compute=" s(${idx} / 16) "
 | 
						||
        K=$(echo $compute | bc -l)
 | 
						||
        printf " %25s  =>  %8.3f\n" "$compute" $K
 | 
						||
\end{verbatim}
 | 
						||
 | 
						||
Cette seconde partie sert à calculer avec la commande
 | 
						||
\texttt{bc}\index{bc}%
 | 
						||
\footnote{\texttt{bc}, c'est vraiment un truc à découvrir.}
 | 
						||
un coefficient variable en fonction du temps :
 | 
						||
$sin(idx/16)$ afin d'avoir une oscillation du coefficient entre 
 | 
						||
-1.0 et 1.0, deux valeurs probablement glitchantes.
 | 
						||
 | 
						||
\begin{verbatim}
 | 
						||
        #        do the hard floating computation
 | 
						||
        #
 | 
						||
        fimgfx   -v cos010 ${imgB} ${FTMP}
 | 
						||
        fimgops  -k ${K} ${FTMP} ${imgA} mix ${FDST}
 | 
						||
\end{verbatim}
 | 
						||
 | 
						||
Étape suivante, étape cruciale : le brassage d'une multitude de
 | 
						||
pixels flottants. 
 | 
						||
 | 
						||
Tout d'abord, nous faisons subir à l'image-echo
 | 
						||
(\texttt{imgB}, définie au début du script) un distorsion
 | 
						||
chromatique de type \textsl{cos010}, le résultat étant écrit
 | 
						||
dans un fichier temporaire. Ensuite, nous mixons l'image 
 | 
						||
primaire et son echo en utilisant le rapport de mixage
 | 
						||
calculé quelques lignes plus haut.
 | 
						||
 | 
						||
 | 
						||
\begin{verbatim}
 | 
						||
        #        write the output as PNG for video encoding
 | 
						||
        #
 | 
						||
        fimg2png ${FDST} ${dst}
 | 
						||
done
 | 
						||
\end{verbatim}
 | 
						||
 | 
						||
Et en fin de boucle, nous convertissons le résultat de nos
 | 
						||
savants calculs au format PNG, et nous écrivons le fichier dans le
 | 
						||
répertoire de destination fixé au début. 
 | 
						||
C'est le moment de passer la main à ffmpeg\index{ffmpeg}.
 | 
						||
 | 
						||
C'est juste une POC\index{POC}, et une implémentation bien plus
 | 
						||
complète écrite en \textbf{C}\index{C} est déja en chantier,
 | 
						||
avec une complexité prévue à un niveau assez réjouissant.
 | 
						||
 | 
						||
% ===================================================================
 | 
						||
%
 | 
						||
%	V4L2 is a trap.
 | 
						||
%
 | 
						||
\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 ?}
 | 
						||
sur la provenance de ces données prétendant être des images.
 | 
						||
 | 
						||
En fait, notre désir secret (enfin, surtout le mien) 
 | 
						||
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 évolution (vraiment trop) lente, qui permet déja
 | 
						||
la capture d'images en
 | 
						||
\textsl{longue pose} selon la méthode du cumul\index{cumul}, et
 | 
						||
devrait bientôt retrouver sa capacité à enregistrer des
 | 
						||
séquences d'images. (\textsl{workaround}~: écrire une boucle en shell)
 | 
						||
 | 
						||
\begin{verbatim}
 | 
						||
tth@debian:~/Devel/FloatImg/v4l2$ ./grabvidseq -h
 | 
						||
options :
 | 
						||
        -c quux         contrast adjustement
 | 
						||
        -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         delay between frames
 | 
						||
        -r 90           mode portrait
 | 
						||
        -s WxH          size of capture
 | 
						||
        -u              try upscaling...
 | 
						||
        -v              increase verbosity
 | 
						||
        -X arg          Xperiment option
 | 
						||
\end{verbatim}
 | 
						||
 | 
						||
La plupart de ces options ont un usage quasi-évident.
 | 
						||
L'option \texttt{-s} doit correspondre à une des
 | 
						||
résolutions possibles de votre capteur. Le type du
 | 
						||
fichier en sortie (option \texttt{-o}) est déterminé par
 | 
						||
l'extension du nom.
 | 
						||
Actuellement 
 | 
						||
seulement \texttt{.fimg}, \texttt{.pnm}, \texttt{.fits},
 | 
						||
\texttt{.tiff} et \texttt{.png}
 | 
						||
sont reconnus.
 | 
						||
 | 
						||
La conversion en gris (option \texttt{-g}) mérite un
 | 
						||
peu plus de travail, et une paramétrisation plus facile.
 | 
						||
L'ajustement de contraste (option\texttt{-c}) est
 | 
						||
vaguement expliqué page \pageref{contraste}.
 | 
						||
 | 
						||
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
 | 
						||
(ou même moyen) terme.
 | 
						||
 | 
						||
\subsubsection{Upscaling}\index{upscaling}\label{upscaling}
 | 
						||
 | 
						||
La fonction que j'ai appelée \textsl{upscaling} est un petit
 | 
						||
hack qui permet de doubler artificiellement la résolution
 | 
						||
de l'image, en profitant du fait que l'on est capable
 | 
						||
de prendre $N$ images en rafale.
 | 
						||
 | 
						||
Pour être rigoureux dans la prise de vue, ce $N$ doit
 | 
						||
ê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.
 | 
						||
 | 
						||
\textbf{Là, il manque un schéma\dots}
 | 
						||
 | 
						||
\subsection{video-infos}\index{video-infos}\label{video-infos}
 | 
						||
 | 
						||
Que contient, que peut faire mon périphérique \textsl{àlc} ?
 | 
						||
Quelles sont ses possibilités de réglage ?
 | 
						||
 | 
						||
\begin{verbatim}
 | 
						||
tth@debian:~/Devel/FloatImg$ v4l2/video-infos -h
 | 
						||
Options :
 | 
						||
        -d              select the video device
 | 
						||
        -K nnn          set the K parameter
 | 
						||
        -l              list video devices
 | 
						||
        -T bla          add a title
 | 
						||
        -v              increase verbosity
 | 
						||
\end{verbatim}
 | 
						||
 | 
						||
Je me sens obligé 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
 | 
						||
des choses essentielles comme la liste des résolutions disponibles.
 | 
						||
 | 
						||
\subsection{nc-camcontrol}
 | 
						||
 | 
						||
Ajustement \textsl{Brightness Contrast Saturation Hue\dots}
 | 
						||
 | 
						||
Probablement pilotable au joystick\index{joystick} et surtout
 | 
						||
par OSC (Open Sound Control).
 | 
						||
 | 
						||
% ===================================================================
 | 
						||
\section{À l'extérieur}
 | 
						||
 | 
						||
Il existe une foultitude de logiciels (composants ou end-yuser) et
 | 
						||
il est souvent nécessaire de pouvoir communiquer facilement
 | 
						||
avec eux. Nous avons déja quelques possibilité d'exportation,
 | 
						||
mais passer par cette étape intermédiaire est parfois délicat
 | 
						||
à gérer dans un \textsl{pipedeprod} autrement bien huilé.
 | 
						||
De même, nos capacités d'importation sont vraiment trop
 | 
						||
réduites, Jpeg et PNG étant les deux priorités.
 | 
						||
 | 
						||
\subsection{ImageMagick}\index{ImageMagick}
 | 
						||
 | 
						||
Pour afficher notre format .fimg exotique avec \texttt{display}, un
 | 
						||
des éléments du package ImageMagick, vous
 | 
						||
devez mettre ce bout de XML\index{XML} dans le fichier
 | 
						||
\texttt{\$HOME/.magick/delegates.xml}~:
 | 
						||
 | 
						||
\begin{lstlisting}
 | 
						||
<?xml version="1.0" encoding="UTF-8"?>
 | 
						||
<delegatemap>
 | 
						||
    <delegate decode="fimg" command="fimg2png '%i' '%o'"/>
 | 
						||
</delegatemap>
 | 
						||
\end{lstlisting}
 | 
						||
 | 
						||
C'est juste un hack rapide, qui ne fonctionne pas très bien avec
 | 
						||
d'autres commande de IM, comme \texttt{identify}\index{identify},
 | 
						||
qui a tendance à
 | 
						||
raconter un peu n'importe quoi, puisqu'elle se base sur le
 | 
						||
résultat de la conversion.
 | 
						||
Je compte donc sur le bouquin de \textsl{Brunus}\index{Brunus}
 | 
						||
pour avancer\dots
 | 
						||
 | 
						||
\subsection{Gimp}\index{Gimp}
 | 
						||
 | 
						||
Mmmmm... Ça semble un peu plus compliqué.
 | 
						||
La documentation à ce sujet me semble ésotérique.
 | 
						||
D'un autre coté, il
 | 
						||
faut faire ça en \textbf{C}, ce qui ne peut pas être totalement négatif.
 | 
						||
Sauf pour les riiRistes.
 | 
						||
 | 
						||
\subsection{ffmpeg}\index{ffmpeg}
 | 
						||
 | 
						||
Un petit aide-mémoire pour encoder vos superbes
 | 
						||
timelapses\index{timelapse} :
 | 
						||
 | 
						||
\begin{lstlisting}
 | 
						||
ffmpeg  -nostdin                                \
 | 
						||
        -y -r 30 -f image2 -i stereo/S%04d.png  \
 | 
						||
        -c:v libx264                            \
 | 
						||
        -pix_fmt yuv420p                        \
 | 
						||
        -tune film                              \
 | 
						||
        -metadata artist='---[ tTh ]---'        \
 | 
						||
        -metadata title='awesome video'         \
 | 
						||
        stereo.mp4
 | 
						||
\end{lstlisting}
 | 
						||
 | 
						||
Il existe environ un gazillion d'options pour encoder avec ffmpeg.
 | 
						||
Bon courage pour toutes les explorer, voire même juste les comprendre.
 | 
						||
 | 
						||
\subsection{Et encore ?}\index{krita}\index{geeqie}
 | 
						||
 | 
						||
Il y a d'autres logiciels pour lesquels écrire une fonction d'importation
 | 
						||
serait bien~: \textsl{Geeqie}, un visualiseur d'image fort pratique, ou
 | 
						||
\textsl{Krita} qui semble avoir les faveurs de
 | 
						||
dessinateurs de talent.
 | 
						||
Ce qui nous conduit à une question importante~: quels sont les logiciels 
 | 
						||
qui gèrent le chargement d'image par un système de
 | 
						||
\textsl{plugin}\index{plugin},
 | 
						||
parce que recompiler tout Gimp juste pour ça, c'est un peu overkill.
 | 
						||
 | 
						||
% ===================================================================
 | 
						||
\section{Le flou temporel}
 | 
						||
 | 
						||
\textit{\hspace{7em}Et si nous jouions sur l'axe du temps ?}
 | 
						||
 | 
						||
Nous avons déja plus ou moins la magie du cumul sur la prise de vue
 | 
						||
d'\textbf{image} en enchainant plusieurs captures d'image accumulées
 | 
						||
en une seule.
 | 
						||
Maintenant, voyons ce que l'on peut faire à partir de plusieurs images.
 | 
						||
On peut d'abord penser faire une moyenne (ou la somme, en fait) de toutes
 | 
						||
ces images. Mais ce n'est qu'une façon déguisée de faire du cumul.
 | 
						||
C'est à ce moment que nous changeons l'axe de vue du défi.
 | 
						||
 | 
						||
Par ailleurs, il m'a semblé pertinent d'inclure dans le projet une
 | 
						||
foultitude d'effets spéciaux%
 | 
						||
\footnote{\textsl{aka} IBM\index{IBM} (image brotching module)}.
 | 
						||
Qui manquent cruellement de possibilités de paramétrage.
 | 
						||
Mais peuvent être enchainés dans ce que j'appelle des
 | 
						||
\textsl{filter-chains}~: ces effets seront appliqués dans
 | 
						||
l'ordre aux image traitées soit en entrée soit en sortie.
 | 
						||
Je pense qu'un schéma\footnote{omg, apprendre un nouveau truc en
 | 
						||
\LaTeX, quel challenge étourdissant !} s'impose.
 | 
						||
 | 
						||
 | 
						||
\subsection{\texttt{./fonderie} : \textsl{moving average}}
 | 
						||
 | 
						||
Basé sur la moyenne mobile, avec une structure de
 | 
						||
fifo\index{fifo} particulièrement mal conçue.
 | 
						||
Qui, en fait, n'est pas vraiment un fifo, mais plutôt un buffer
 | 
						||
circulaire. Pour chaque image source, elle est lue, passe dans la chaine de
 | 
						||
filtre d'entrée et est insérée dans ce buffer.
 | 
						||
Ensuite on calcule la moyenne des images contenues dans ce buffer. 
 | 
						||
Et pour conclure, cette image moyennée passe au travers de la
 | 
						||
chaine de filtre de sortie, avant d'être enregistrée en PNG\index{PNG}
 | 
						||
dans le répertoire de destination.
 | 
						||
 | 
						||
\begin{verbatim}
 | 
						||
*** fonderie compiled Jan 23 2023, 10:43:56, pid 23366
 | 
						||
options:
 | 
						||
        -E      input:filter:chain
 | 
						||
        -F      output:filter:chain
 | 
						||
        -I      input glob pattern
 | 
						||
        -L      list available filters
 | 
						||
        -O      output directory
 | 
						||
        -T      fifo size
 | 
						||
        -v      increase verbosity
 | 
						||
\end{verbatim}
 | 
						||
 | 
						||
Euh, c'est quoi un '\textsl{input glob pattern}' ?
 | 
						||
 | 
						||
C'est ce qui vous permet
 | 
						||
de sélectionner un peu les images que vous voulez traiter, exactement
 | 
						||
comme vous pourriez le faire avec un shell classique.
 | 
						||
Par exemple pour choisir une image sur dix, le glob-pattern sera
 | 
						||
'\texttt{frames/????0.fimg}', et vous trouverez les explications détaillées
 | 
						||
dans le manuel~: \texttt{glob(7)}, et \texttt{glob(3)} pour la
 | 
						||
fonction utilisée.
 | 
						||
 | 
						||
% -------------------------------------------------------------------
 | 
						||
 | 
						||
\subsection{Interpolator}\index{interpolator}
 | 
						||
 | 
						||
Pour le moment, juste des calculs pas si simple que ça.
 | 
						||
Je pense qu'il faudra
 | 
						||
se lancer dans des calculs splinesques pour améliorer les choses dans
 | 
						||
la création des images intermédiaires.
 | 
						||
Voyons d'abord le principe actuel.
 | 
						||
 | 
						||
Nous avons une série de centaines, voire de milliers, de photos.
 | 
						||
En parcourant cette liste, nous allons en prélever une sur $N$,
 | 
						||
et entre celle-ci et la
 | 
						||
précédente prélevée, nous allons calculer par interpolation
 | 
						||
\textbf{linéaire} $N - 1$ images intermédiaires, et les
 | 
						||
intercaler entre nos deux sélections pour générer le
 | 
						||
flux de sortie,
 | 
						||
ce qui devrait nous donner un ralenti de bon aloi.
 | 
						||
 | 
						||
\begin{verbatim}
 | 
						||
usage:
 | 
						||
        interpolator [options] <inglob> <outdir> <nbsteep>
 | 
						||
options:
 | 
						||
        -E i:bla:k      input  filter chain
 | 
						||
        -F name:j       output filter chain
 | 
						||
        -n              make negative
 | 
						||
        -S nn           mysterious sort
 | 
						||
        -L              list available filters
 | 
						||
        -v              increase verbosity
 | 
						||
\end{verbatim}
 | 
						||
 | 
						||
L'option « mysterious sort » mérite bien son nom. Cette friture a
 | 
						||
été écrite il y a bien longtemps pour un projet précis, et les
 | 
						||
résultats ont été décevants. Je pense qu'il est toxique de
 | 
						||
l'utiliser pour le moment\footnote{Ou le repenser différent ?}.
 | 
						||
 | 
						||
% -------------------------------------------------------------------
 | 
						||
 | 
						||
 | 
						||
\subsection{Singlepass}
 | 
						||
 | 
						||
Ce programme \texttt{singlepass} prétend vous permettre de tester
 | 
						||
tous les filtres disponibles, et dont on peut avoir la liste
 | 
						||
avec l'option \texttt{-L}\footnote{liste hélas peu machinable.}
 | 
						||
 | 
						||
\begin{verbatim}
 | 
						||
usage:
 | 
						||
        -F      define:the:filter:chain
 | 
						||
        -g      input glob pattern
 | 
						||
        -L      list available filters
 | 
						||
        -O      /output/directory   (default ./p8)
 | 
						||
        -r N    repetiiing factor
 | 
						||
        -v      spit more messages
 | 
						||
\end{verbatim}
 | 
						||
 | 
						||
Il n'y a pas de moyenne mobile, pas d'interpolation, mais un facteur de
 | 
						||
répétition qui permet de dupliquer $N$ fois une image dans le flux de
 | 
						||
sortie. Si vous globez \texttt{rush/????[02468]}, vous prenez
 | 
						||
en compte une image sur deux de la séquence capturée,
 | 
						||
alors un facteur de répétition à $2$ conservera
 | 
						||
la 'vitesse' de la séquence, mais avec une petite saccade régulière
 | 
						||
de bon aloi \textit{:)}
 | 
						||
 | 
						||
% -------------------------------------------------------------------
 | 
						||
 | 
						||
\subsection{Déviance dans le flou ?}
 | 
						||
 | 
						||
Là, nous tombons dans de la \textsl{troiD}\index{3d} de haut niveau,
 | 
						||
avec plein de maths compliquées à l'intérieur.
 | 
						||
Et surtout quelque chose qui n'est encore qu'une idée abstraite,
 | 
						||
mais il y aura du zbuffer\index{zbuffer} dedans.
 | 
						||
 | 
						||
% ===================================================================
 | 
						||
 | 
						||
\section{Expérimentations} \index{experimental}
 | 
						||
 | 
						||
Il m'arrive parfois d'avoir de vagues idées d'image, et donc de logiciel,
 | 
						||
qui tournent dans un coin de la tête.
 | 
						||
Parfois je songe à une fonction qui me
 | 
						||
serait bien utile, mais j'ai des doutes sur son 
 | 
						||
\textsc{api}\footnote{Application Programming Interface}\index{api}
 | 
						||
qui soit  à la fois simple et complète. Je fais donc des essais.
 | 
						||
Parfois j'imagine confusément un algorithme\index{algorithme} tordu
 | 
						||
et sans but précis. Je le \textit{runne} et je le \textit{re-runne}
 | 
						||
un gazillion de fois dans mon cerveau processique.
 | 
						||
Quel va être son facteur $O$ ? Je fais donc des essais.
 | 
						||
 | 
						||
\subsection{movepixels}
 | 
						||
 | 
						||
\subsection{muxplanes}
 | 
						||
 | 
						||
% ===================================================================
 | 
						||
 | 
						||
\section{Et pour la suite ?}
 | 
						||
 | 
						||
En fait, je fait de la photo par la méthode du « cumul »\index{cumul}
 | 
						||
depuis plusieurs années, au début avec vgrabbj et convert,
 | 
						||
puis avec floatimg et ses satellites.
 | 
						||
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
 | 
						||
 | 
						||
L'idée est donc de construire un appareil autonome, basé sur un Raspi et
 | 
						||
une webcam \textsc{usb}\index{USB}, pilotable par \textsc{lirc}\index{LIRC},
 | 
						||
alimenté par une (grosse) batterie et permettant d'aller
 | 
						||
faire des images au bord d'un lac ou dans la campagne du Gers%
 | 
						||
\footnote{Aux Bourtoulots, par exemple.}.
 | 
						||
Et comme le dit la sagesse populaire : « fimg at 11 ».
 | 
						||
 | 
						||
% -------------------------------------------------------------------
 | 
						||
 | 
						||
%                 XXX
 | 
						||
% maintenant, comment faire un index sur trois colonnes ?
 | 
						||
%
 | 
						||
 | 
						||
\printindex
 | 
						||
 | 
						||
\end{document}
 |