FloatImg4PythonBinding/doc/the_floatimg_hack.tex

1619 lines
57 KiB
TeX
Raw Normal View History

\documentclass[a4paper,10pt]{article}
2019-05-20 17:47:13 +11:00
% \listfiles % pour le debug
\usepackage[french]{babel}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{makeidx}
\usepackage{listings}
2020-02-21 22:54:50 +11:00
% \lstset{frame=single} % dessin d'un cadre autour du listing
\lstset{basicstyle=\ttfamily\small}
2021-04-19 20:01:09 +11:00
\lstset{aboveskip=0.1em,belowskip=0.1em}
2020-02-21 22:54:50 +11:00
2021-04-18 09:46:45 +11:00
\usepackage{babel} % ?
2019-09-06 00:51:30 +11:00
2021-04-18 09:46:45 +11:00
\usepackage{graphicx} % for gnuplot ylabel rotate
2020-02-21 09:20:31 +11:00
2021-04-18 09:46:45 +11:00
\usepackage{pifont} % caractères rigolos
2019-09-06 00:51:30 +11:00
\usepackage{enumitem}
2020-02-14 06:44:22 +11:00
\setitemize[1]{label={\ding{87}}}
2019-09-06 00:51:30 +11:00
\frenchbsetup{CompactItemize=false}
2019-05-20 17:47:13 +11:00
% \usepackage{color}
% \usepackage{url}
\usepackage{xspace}
\usepackage[verbose]{layout}
2020-09-03 10:35:54 +11:00
\setlength \parskip {0.35em}
2020-02-12 03:33:38 +11:00
2020-02-21 20:38:01 +11:00
\makeatletter
2021-04-18 09:46:45 +11:00
% explication de ce truc ?
2020-02-21 20:38:01 +11:00
\def\verbatim@font{\normalfont\ttfamily\small}
\makeatother
2020-02-20 10:07:03 +11:00
\setlength{\hoffset}{0em}
2020-02-12 03:33:38 +11:00
\setlength{\textheight}{640pt}
\setlength{\textwidth}{422pt}
\setlength{\marginparwidth}{10pt}
2019-05-20 17:47:13 +11:00
\makeindex
2019-11-12 10:19:32 +11:00
% ------ a few new commands
\newcommand{\interparagraphe { \vspace{60pt} } }
2019-05-20 17:47:13 +11:00
% -------------------------------------------------------------------
2021-04-23 23:42:08 +11:00
\title{Floating images processing (for fun and profit ?)}
2019-05-20 17:47:13 +11:00
\author{tTh}
\begin{document}
\maketitle
2019-08-02 13:22:48 +11:00
2021-04-23 08:52:39 +11:00
\section*{Une image flottante ?}
2019-08-02 13:22:48 +11:00
2021-04-23 23:42:08 +11:00
\textsl{Mais de quoi parle-t-on exactement ?}
2019-11-12 10:19:32 +11:00
2020-02-20 03:08:33 +11:00
% XXX XXX XXX\vspace{1em}
2019-08-03 23:27:21 +11:00
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
2020-02-12 03:33:38 +11:00
\texttt{float}\index{float} du langage C. Ce qui correspond
à la norme IEEE 754-1985.
2019-11-12 10:19:32 +11:00
2020-02-20 03:08:33 +11:00
% XXX XXX XXX\vspace{1em}
2019-09-11 15:19:32 +11:00
2021-04-28 09:15:07 +11:00
\textbf{Attention !} tout le code que nous allons voir ensemble est en
2019-09-11 15:19:32 +11:00
perpétuelle évolution\footnote{voir page \pageref{TODO}},
2019-11-30 03:06:40 +11:00
et sa fiablité (surtout sur certains aspects mathématiques)
reste à démontrer\index{valgrind}.
2019-11-12 10:19:32 +11:00
Mais le service après-vente est assez réactif. Du moins
2019-11-30 03:06:40 +11:00
pour ceux qui suivent le canal \texttt{\#tetalab} sur le réseau
2019-11-12 10:19:32 +11:00
IRC de Freenode.
2019-08-02 13:22:48 +11:00
2020-02-21 20:38:01 +11:00
\textbf{Attention !} ce document commence par une bonne rafale
2021-04-28 09:15:07 +11:00
de technique parfois \textsl{hardue}.
2020-03-01 07:59:12 +11:00
Vous avez parfaitement le droit de sauter directement à
2020-02-21 20:38:01 +11:00
la page \pageref{outils} pour quelque chose de plus concret.
2019-08-02 13:22:48 +11:00
% -------------------------------------------------------------------
2021-04-28 09:15:07 +11:00
%
% 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 un 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.
\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 Trititron\footnote{Sony, u'r the best !} 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 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 pixels, pour concrétiser l'existence perceptuelles 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\footnote{\textsl{bik kudo 2 J Postel}}
mondial, je pourrais même vous donner l'url si vous me promettez de ne pas
la glissr dans le capitalisme de surveillance.
% ===================================================================
2019-08-02 13:22:48 +11:00
2020-02-20 03:08:33 +11:00
\setlength \parskip {0em}
2019-05-20 17:47:13 +11:00
\tableofcontents
2019-08-03 23:27:21 +11:00
\pagebreak
2020-02-20 03:08:33 +11:00
\setlength \parskip {0.40em}
2019-05-20 17:47:13 +11:00
2021-04-19 20:01:09 +11:00
\layout \pagebreak
2020-02-12 03:33:38 +11:00
2021-04-19 20:01:09 +11:00
% ===================================================================
2020-02-14 06:44:22 +11:00
\section{Théorie}\index{théorie}
Pour le moment, seule la quête de l'empirisme absolu a été
2020-02-20 03:08:33 +11:00
visée. Les justifications mathématiques attendront le retour
du schmod777. Ceci dit, rien ne nous empêche d'aller consulter
Wikipedia~:
\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}
Ce qui nous conduit à estimer qu'il est possible de cumuler environ
quelques milliers d'images standard à 256 niveaux, sans trop avoir
2020-02-20 10:07:03 +11:00
à se soucier des éventuelles pertes de précision. Mais ça demande
à être confirmé par des esprits supérieurs.
2020-02-14 06:44:22 +11:00
2020-03-02 11:19:57 +11:00
\subsection{Dynamique}\index{dynamique}
2021-04-23 23:42:08 +11:00
Dynamique, précision et \textsl{macheps} ? Peu de gens connaissent
la fourbitude des calculs en virgule flottante avec les ordinateurs.
Moi-même compris.
2020-03-02 11:19:57 +11:00
\subsection{Pixel négatif ?}
2020-07-23 01:10:42 +11:00
Il est très difficle d'imaginer une lumière négative. Sauf peut-être
2021-04-03 04:12:22 +11:00
si nous songeons à des coefficients d'absorption, ou un canal
\textsl{alpha} qui inverserait les valeurs ?
2020-03-02 11:19:57 +11:00
2021-04-19 20:01:09 +11:00
% ===================================================================
2020-02-14 06:44:22 +11:00
2020-02-12 03:33:38 +11:00
\section{Premier exemple}\index{exemple}\label{exemple}
2019-05-20 17:47:13 +11:00
2019-09-11 15:19:32 +11:00
\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
2019-11-12 10:19:32 +11:00
et sur disque. Ça a été imaginé de façon presque empirique,
mais nous sommes tous là pour améliorer les choses, dans
2020-02-20 10:07:03 +11:00
la mesure de nos moyens.
2020-02-20 12:31:06 +11:00
Nous allons donc directement rentrer au cœur du problème,
en écrivant quelques lignes de code.
2019-09-11 15:19:32 +11:00
2021-04-28 09:15:07 +11:00
\subsection{L'idée}
2020-02-20 12:31:06 +11:00
Pour commencer par quelque chose de simple,
2019-08-03 23:27:21 +11:00
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.
2021-04-23 08:52:39 +11:00
Enfin, non, il y a déja longtemps, avant la grande pandémie.
2019-08-03 23:27:21 +11:00
Tout d'abord, nous devons déclarer et garnir quelques variables
pour gérer la machinerie interne.
2020-02-22 08:31:22 +11:00
\begin{lstlisting}
2019-08-03 23:27:21 +11:00
int width = 640, height = 480;
2019-08-07 06:22:12 +11:00
char *fname = "exemple.fimg";
2019-08-03 23:27:21 +11:00
FloatImg fimg;
2020-02-22 08:31:22 +11:00
\end{lstlisting}
2019-08-03 23:27:21 +11:00
2021-04-18 09:46:45 +11:00
Ensuite, nous enchainerons trois étapes : la création de l'image
en mémoire centrale, l'initialisation des valeurs de chaque pixel à 0.0,
et pour conclure, l'enregistrement dans un fichier\footnote{Au format
2019-11-30 03:06:40 +11:00
ésotérique, mais très véloce.} binaire.
2019-08-03 23:27:21 +11:00
2020-02-22 08:31:22 +11:00
\begin{lstlisting}
2019-09-11 15:19:32 +11:00
foo = fimg_create(&fimg, width, height, FIMG_TYPE_RGB);
2019-08-03 23:27:21 +11:00
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);
}
2020-02-22 08:31:22 +11:00
\end{lstlisting}
2019-08-03 23:27:21 +11:00
Une fois ce code enrobé dans un \texttt{main()}, compilé et exécuté,
nous pouvons entrevoir, grâce au logiciel
\texttt{fimgstats} (voir page \pageref{fimgstats}),
le résultat sous forme de chiffres divers, et/ou inutiles~:
\begin{verbatim}
2019-09-11 15:19:32 +11:00
$ ./fimgstats quux.img
2019-08-03 23:27:21 +11:00
----------- 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
2021-04-23 08:52:39 +11:00
max value 0.000000
2019-08-03 23:27:21 +11:00
\end{verbatim}
2021-04-28 09:15:07 +11:00
\subsection{Action ?}
2021-04-23 08:52:39 +11:00
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.
2019-09-11 15:19:32 +11:00
La suite vers la page \pageref{codaz}.
2019-08-07 20:10:12 +11:00
Vous trouverez dans le répertoire \texttt{tools/}\index{tools/}
d'autres exemples de mise en œuvre des fonctions disponibles
2019-09-11 15:19:32 +11:00
sous formes d'outils en ligne de commande,
2021-04-23 08:52:39 +11:00
lesquels sont approximativement décrits en page \pageref{outils}.
2019-08-07 20:10:12 +11:00
2021-04-19 20:01:09 +11:00
% ===================================================================
2019-08-07 20:10:12 +11:00
\section{Installation}
2019-08-03 23:27:21 +11:00
2020-09-03 10:35:54 +11:00
Sauf indications contraires, ces instructions se réfèrent à
2021-04-23 08:52:39 +11:00
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.
\textit{Attention, ça va devenir un peu gore\dots}
2019-11-30 03:06:40 +11:00
\subsection{Prérequis}
2021-04-18 09:46:45 +11:00
Vous devez, en dehors des outils classiques (gcc, Awk, make\dots),
avoir quelques bibliothèques installées\footnote{Les \texttt{-dev}
2020-09-03 10:35:54 +11:00
en plus pour Debian et dérivées}~:
2020-08-07 16:39:22 +11:00
\textsf{
libv4l2, libpnglite, libtiff,
2020-05-29 22:30:37 +11:00
libnetpbm\footnote{package libnetpbm10-dev},
2020-08-07 16:39:22 +11:00
libz\footnote{package zlib1g-dev}, libcurses,
libcfitsio-dev
2020-09-03 10:35:54 +11:00
} % end of textsf
éventuellement avec le \textsf{-dev} correspondant,
et probablement d'autres choses.
2019-11-12 10:19:32 +11:00
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.
2020-03-01 07:59:12 +11:00
Il faut aussi savoir où trouver le code.
\subsection{Compilation}
2021-04-23 08:52:39 +11:00
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
2019-09-11 15:19:32 +11:00
le bouzin. Il est loin d'être parfait\footnote{Il doit être possible
de faire un Makefile récursif, mais\dots}.
2020-01-23 22:50:37 +11:00
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.
2019-11-12 10:19:32 +11:00
Pour le moment, la procédure d'installation est un peu rude,
pour ne pas dire clairement sommaire.
2019-12-21 23:50:15 +11:00
Si le résultat de l'étape compilation vous semble correct,
2020-04-02 23:49:10 +11:00
vous pouvez copier les deux fichiers \texttt{floatimg.h} et
\texttt{libfloatimg.a} dans un emplacement approprié, par exemple
2019-08-07 06:22:12 +11:00
\texttt{/usr/local/include} et \texttt{/usr/local/lib}.
2019-08-03 23:27:21 +11:00
2019-12-21 23:50:15 +11:00
Le script \texttt{install.sh}, à la racine du projet, est censé
faciliter un peu la chose. Il prend également en compte la copie
2020-03-02 11:19:57 +11:00
des divers binaires du dossier \texttt{tools/} (cf page \pageref{outils})
2021-04-18 09:46:45 +11:00
dans le répertoire prévu à cet effet~: \texttt{/usr/local/bin}.
2019-11-12 10:19:32 +11:00
2020-02-21 09:20:31 +11:00
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.
2020-02-12 03:33:38 +11:00
% =================================================================
2019-09-11 15:19:32 +11:00
\section{Utilisation coté codeur}\label{codaz}
2019-08-07 20:10:12 +11:00
2020-02-12 03:33:38 +11:00
Classiquement, il y a un fichier \texttt{.h} à inclure dans chacun
de vos codes source,
2019-12-21 23:50:15 +11:00
\texttt{floatimg.h}, généralement logé dans \texttt{/usr/local/include}
contenant un certain nombre de définition de structures, de macros,
2020-02-12 03:33:38 +11:00
de constantes\footnote{À l'ancienne, via le pré-processeur}
2019-12-21 23:50:15 +11:00
et les prototypes des fonctions utilisables par vos logiciels.
2019-08-07 20:10:12 +11:00
2021-04-23 08:52:39 +11:00
Au niveau du code source, ces fonctions sont très approximativement
2019-08-07 20:10:12 +11:00
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
2021-04-18 09:46:45 +11:00
est en fait indécement arbitraire.
2021-04-23 08:52:39 +11:00
D'autant plus qu'il y a aussi un répertoire nommé « experiemental ».
2019-08-07 20:10:12 +11:00
2019-08-09 02:16:20 +11:00
\subsection{Structures, macros\dots}
2019-08-11 03:37:52 +11:00
Les pixels flottants d'une image résidant en mémoire centrale
sont décrits par un ensemble
2019-12-21 23:50:15 +11:00
de données (certains appelent ça des \textsl{metadatas}) regroupées
2019-08-11 03:37:52 +11:00
dans une jolie structure que nous allons examiner dès maintenant.
2020-02-22 08:31:22 +11:00
\begin{lstlisting}
2019-08-11 03:37:52 +11:00
/* in memory descriptor */
2019-08-09 02:16:20 +11:00
typedef struct {
2021-04-18 09:46:45 +11:00
int magic;
2019-08-09 02:16:20 +11:00
int width;
int height;
int type;
float fval;
int count;
float *R, *G, *B, *A;
int reserved;
} FloatImg;
2020-02-22 08:31:22 +11:00
\end{lstlisting}\index{FloatImg}
2019-08-09 02:16:20 +11:00
2021-04-18 09:46:45 +11:00
Le premier champ, \texttt{magic}, servira un de ces jours à
robustifier l'ensemble du machin.
Les deux suivants sont \textsl{obvious}.
2020-09-03 10:35:54 +11:00
Le troisième est le type d'image : pour le moment, il y en a % trois
un certain nombre
2019-08-11 03:37:52 +11:00
qui sont définis\footnote{et plus ou moins bien gérés\dots} :
2021-03-17 20:55:34 +11:00
gris, rgb et rgba/rgbz\index{rgba}\index{rgbz}.
2021-04-23 08:52:39 +11:00
Les constantes adéquates sont déclarées dans \texttt{floatimg.h}~:
2019-08-11 03:37:52 +11:00
2020-02-22 08:31:22 +11:00
\begin{lstlisting}
2019-08-11 03:37:52 +11:00
#define FIMG_TYPE_GRAY 1
#define FIMG_TYPE_RGB 3
#define FIMG_TYPE_RGBA 4
2020-02-12 03:33:38 +11:00
#define FIMG_TYPE_RGBZ 99
2020-02-22 08:31:22 +11:00
\end{lstlisting}
2019-08-11 03:37:52 +11:00
Un peu plus loin, nous avons les pointeurs vers les
différents \textsl{pixmaps} de l'image. En principe l'organisation
2019-12-21 23:50:15 +11:00
interne de ces zones est improbable, puisque elle dérive
2020-02-12 03:33:38 +11:00
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.
2019-12-21 23:50:15 +11:00
2020-02-12 03:33:38 +11:00
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
2019-12-21 23:50:15 +11:00
chose : imaginons un périphérique de capture qui nous fournisse des
2020-09-03 10:35:54 +11:00
images en gris sur 4 bits (et linéaire).
Et que nous voulions cumuler\index{cumul}
quelques images...
2019-12-21 23:50:15 +11:00
Le champ \textsl{count} sera mis à 0 et
le champ \textsl{fval} sera initialisé à 15.0
2021-04-18 09:46:45 +11:00
(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,
2019-08-29 06:08:59 +11:00
toutes les informations nécessaires pour exploiter au mieux la dynamique
2019-12-21 23:50:15 +11:00
de notre image dans les étapes ultérieures, puisque la valeur
maximale théorique est égale à $fval * count$.
2019-08-11 03:37:52 +11:00
2020-03-02 11:19:57 +11:00
La fonction \texttt{fimg\_printhead(FloatImg *h)} affiche
sommairement le contenu de ce descripteur,
et \texttt{fimg\_describe(FloatImg *head, char *txt)} propose
2021-04-18 09:46:45 +11:00
un affichage plus détaillé. Ça peut parfois aider.
2020-03-02 11:19:57 +11:00
2020-02-12 03:33:38 +11:00
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
2021-04-18 09:46:45 +11:00
pas être la même chose dans l'avenir. Mais après tout, ce n'est
2021-04-23 08:52:39 +11:00
encore qu'un concept en devenir, n'est-il pas ?
2019-12-21 23:50:15 +11:00
2020-02-12 03:33:38 +11:00
% ----------------------------------
2019-08-11 03:37:52 +11:00
2020-02-12 03:33:38 +11:00
\subsection{Les fondations}\index{lib/}
2019-08-07 20:10:12 +11:00
2020-02-20 12:31:06 +11:00
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,
2021-04-23 08:52:39 +11:00
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~:
2019-08-07 20:10:12 +11:00
2020-02-22 08:31:22 +11:00
\begin{lstlisting}
2019-08-07 20:52:04 +11:00
int fimg_create(FloatImg *fimg, int w, int h, int type);
2019-08-07 20:10:12 +11:00
int fimg_destroy(FloatImg *fimg);
2020-02-22 08:31:22 +11:00
\end{lstlisting}
2019-08-07 20:10:12 +11:00
2020-02-12 03:33:38 +11:00
L'appelant doit lui-même gérer le descripteur d'image (une structure
2020-02-20 12:31:06 +11:00
C décrite plus haut) en le considérant comme un type semi-opaque dont
2021-04-23 08:52:39 +11:00
la forme \emph{peut} varier, mais qu'il convient de mettre à zéro
avant le moindre usage\footnote{\texttt{man 3 memset}}.
2021-04-18 09:46:45 +11:00
Certains membres de cette structure sont
2020-02-12 03:33:38 +11:00
documentés dans ce document, et les autres sont dangereux à
toucher. Les types d'images actuellement gérés sont les trois grands
classiques : gray, rgb et rgba. et expliquées quelques lignes plus haut.
2020-04-02 23:49:10 +11:00
Comme vous allez le voir plus loin, il y a plein de fonctions qui
prennent en argument deux images: une source et une destination.
2020-04-07 05:09:11 +11:00
Et dans la plupart des cas, ces deux images doivent être compatibles,
c'est à dire même type et mêmes dimensions.
2020-04-02 23:49:10 +11:00
\begin{lstlisting}
2020-04-07 05:09:11 +11:00
/* return 0 if compatible */
int fimg_images_not_compatible(FloatImg *a, FloatImg *b);
2020-04-02 23:49:10 +11:00
\end{lstlisting}
2021-04-23 08:52:39 +11:00
C'est bien beau d'être enfin une image résidente en mémoire centrale, mais
2020-02-12 03:33:38 +11:00
pouvoir aussi exister à long terme en étant stocké dans la matrice
2021-04-23 08:52:39 +11:00
est tout aussi pertinent.
Il y a deux opérations qui supportent le reste des transits ram/ps.
2020-07-23 01:10:42 +11:00
Le format des fichiers est décrit page \pageref{formatfimg}.
2020-02-12 03:33:38 +11:00
2020-02-22 08:31:22 +11:00
\begin{lstlisting}
2020-02-12 03:33:38 +11:00
int fimg_dump_to_file(FloatImg *fimg, char *fname, int notused);
int fimg_load_from_dump(char *fname, FloatImg *where);
2020-02-22 08:31:22 +11:00
\end{lstlisting}
2020-02-12 03:33:38 +11:00
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 ram doit être
2020-02-20 12:31:06 +11:00
pré-allouée. On peut connaitre ces valeurs en appelant
\texttt{int fimg\_fileinfos(char *fname, int datas[3])}.
2020-02-12 03:33:38 +11:00
2020-02-20 03:08:33 +11:00
Si tout s'est bien passé (valeur retournée égale à 0),
2020-02-20 10:07:03 +11:00
on va trouver la largeur dans \texttt{datas[0]},
2020-02-20 12:31:06 +11:00
la hauteur dans \texttt{datas[1]} et le type dans
\texttt{datas[2]}\footnote{La fonction
2020-02-21 09:20:31 +11:00
\texttt{fimg\_type\_is\_valid(int type)} peut vous aider\dots}.
2020-02-20 12:31:06 +11:00
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 :
2020-02-22 08:31:22 +11:00
\begin{lstlisting}
2020-02-20 12:31:06 +11:00
FloatImg head;
memset(&head, 0, sizeof(FloatImg));
foo = fimg_create_from_dump("lena.fimg", &head);
2020-02-22 08:31:22 +11:00
\end{lstlisting}
2020-02-20 10:07:03 +11:00
2020-02-21 09:20:31 +11:00
Si la valeur retournée est différente de 0, c'est que quelque
2020-10-04 22:05:28 +11:00
chose s'est probablement mal passé.
2020-07-23 01:10:42 +11:00
Certains messages sont parfois explicites.
2020-02-12 03:33:38 +11:00
% _________
\subsection{Dessiner}
2019-09-01 03:06:09 +11:00
Bon, vous avez une image latente, et vous souhaitez dessiner dessus
(ou dedans ?) avec vos encres flottantes ?
2020-02-12 03:33:38 +11:00
Il y a des fonctions pour ça, par exemple~:
2019-08-07 20:52:04 +11:00
2020-02-22 08:31:22 +11:00
\begin{lstlisting}
2020-02-21 09:20:31 +11:00
int fimg_plot_rgb(FloatImg *head, int x, int y, float r, float g, float b);
2020-02-22 08:31:22 +11:00
\end{lstlisting}
2019-10-19 16:03:47 +11:00
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},
2020-02-12 03:33:38 +11:00
qui ajoute du rgb à un pixel, laquelle fonction a d'ailleurs été
2020-01-23 22:50:37 +11:00
à la base de la seconde génération de la
2019-11-30 03:06:40 +11:00
photographie\index{photographie} en cumul\index{cumul}.
2020-02-21 09:20:31 +11:00
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.
2020-02-12 03:33:38 +11:00
2020-07-23 01:10:42 +11:00
Quand au canal \textsl{alpha}\index{alpha}, il est pour le moment
2020-09-03 10:35:54 +11:00
superbement ignoré. Ceci dit, on vient de me faire remarquer qu'il
peut être utilisable aussi pour faire du
2021-04-18 09:46:45 +11:00
\textsl{z-buffer}\index{z-buffer}\index{rgbz}\dots
2020-07-23 01:10:42 +11:00
2020-02-12 03:33:38 +11:00
% ----------------------------------
\subsection{Contraste}\index{contraste}\label{contraste}
2019-11-30 03:06:40 +11:00
Certaines opérations d'ajustement du contraste d'une image
2020-09-03 10:35:54 +11:00
semblent cohérentes avec la notion d'image flottante.
Certaines d'entre elles, les plus simples, sont disponibles.
2020-02-20 10:07:03 +11:00
Les autres sont à imaginer.
2019-11-30 03:06:40 +11:00
2020-03-08 01:24:31 +11:00
\begin{figure}[h]
2020-02-21 09:20:31 +11:00
\input{cos01.tex} % XXX XXX XXX
\caption{Correcteur cos01}
\end{figure}
2019-11-30 03:06:40 +11:00
Ils prennent chacun trois paramètres, d'abord les images
2020-09-03 10:35:54 +11:00
source et destination (\texttt{* FloatImg}),
ensuite le troisième
qui est un nombre en double précision donnant la valeur
2020-02-20 10:07:03 +11:00
maximale \textsl{supposée} de l'image source,
valeur qui peut être déterminée de plusieurs manières.
2019-11-30 03:06:40 +11:00
2020-02-22 08:31:22 +11:00
\begin{lstlisting}
2019-11-30 03:06:40 +11:00
/* 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);
2020-01-11 03:22:58 +11:00
int fimg_cos_010(FloatImg *s, FloatImg *d, double maxval);
2020-02-22 08:31:22 +11:00
\end{lstlisting}
2019-11-30 03:06:40 +11:00
2020-02-21 09:20:31 +11:00
Si vous souhaitez rajouter votre propre méthode de modification
de contraste, il y a quelques explication en page \pageref{exemplefunc}.
2021-03-17 20:55:34 +11:00
Mais rien ne vous oblige à le faire. Sauf vos envies.
2020-02-21 09:20:31 +11:00
2020-03-08 01:24:31 +11:00
\begin{figure}[h]
2020-02-21 09:20:31 +11:00
\input{cos010.tex} % XXX XXX XXX
\caption{Correcteur cos010}
2020-02-20 10:07:03 +11:00
\end{figure}
2019-11-30 03:06:40 +11:00
Rappelons qu'il est possible pour un logiciel applicatif
2020-03-02 11:19:57 +11:00
comme \texttt{grabvidseq} (cf page \pageref{grabvidseq})
2019-11-30 03:06:40 +11:00
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.
2020-01-11 03:22:58 +11:00
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.
2019-11-30 06:35:23 +11:00
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
2020-03-02 11:19:57 +11:00
prévue pour ça de façon sommaire.
C'est actuellement la méthode utilisée par l'outil qui
2020-01-11 03:22:58 +11:00
sert à faire les modifications de contraste (page \pageref{fimgfx}).
2020-03-02 11:19:57 +11:00
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.
2019-11-30 06:35:23 +11:00
2019-11-30 03:06:40 +11:00
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}
2020-07-23 01:10:42 +11:00
de pixel flottant. \textsl{Et c'est pas gagné...}
2019-10-19 16:03:47 +11:00
2020-02-12 03:33:38 +11:00
% ----------------------------------
2019-08-07 20:10:12 +11:00
2020-02-14 06:44:22 +11:00
\subsection{Géométrie}\index{géométrie}\label{geometrie}
Très prochainement, le retour du blitter\index{blitter}.
2020-03-01 07:59:12 +11:00
Et pour attendre, un truc improbable, voire même
2020-03-02 11:19:57 +11:00
inutile, en fait l'inverse de l'upscaling.
2020-02-14 06:44:22 +11:00
2020-02-22 08:31:22 +11:00
\begin{lstlisting}
2020-02-14 06:44:22 +11:00
int fimg_halfsize_0(FloatImg *src, FloatImg *dst, int notused);
2021-04-18 09:46:45 +11:00
int fimg_halfsize_1(FloatImg *src, FloatImg *dst, int notused);
2020-02-22 08:31:22 +11:00
\end{lstlisting}
2020-02-14 06:44:22 +11:00
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.
2021-04-18 09:46:45 +11:00
La première propose un résultat très moyen : il n'y a pas d'interpolation,
alors que la seconde semble bien mieux.
2020-02-14 06:44:22 +11:00
2020-03-01 07:59:12 +11:00
\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}
2020-03-24 21:45:09 +11:00
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).
2020-07-23 01:10:42 +11:00
% ----------------------------------
\subsection{Format du fichier \textsc{fimg}}\index{format}\label{formatfimg}
D'un design très empirique, c'est certainement à revoir pour l'avenir.
Tout d'abord pour normaliser l'endianess et le packing\dots
\begin{lstlisting}
typedef struct {
char magic[8];
int w, h, t;
} FimgFileHead;
\end{lstlisting}
\dots Mais aussi pour faciliter l'ajout de métadonnées, telles que
la valeur maximale, la date de création, une longueur d'onde,
et bien plus encore.
2021-04-23 08:52:39 +11:00
Le champ \texttt{magic[8]} doit contenir une valeur magique~:
les quatre premier octets doivent contenir les quatre caractères
\texttt{'FIMG'}, et les quatre dernier doivent être à 0.
2021-04-18 09:46:45 +11:00
Le champ \texttt{t} (le type de l'image) doit avoir les trois octets
2021-04-23 08:52:39 +11:00
de poids fort à 0. Vous trouverez les constantes de type dans le
fichier \texttt{floatimg.h}, et quelques informations
(non-)essentielles.
2020-07-23 01:10:42 +11:00
2020-02-14 06:44:22 +11:00
% ----------------------------------
2020-02-20 12:31:06 +11:00
\subsection{Exportation \& Importation}\index{export}\label{export}
2019-11-30 06:35:23 +11:00
2020-02-12 03:33:38 +11:00
Notre format de fichier étant totalement inconnu, 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.
2020-02-20 12:31:06 +11:00
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
dans ce domaine\dots
2020-02-20 03:08:33 +11:00
2020-02-12 03:33:38 +11:00
\subsubsection{Vers PNM}\index{PNM}
2020-02-21 09:20:31 +11:00
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
2020-02-20 12:31:06 +11:00
d'une taille énorme sur les fichiers. D'un autre coté,
2020-02-12 03:33:38 +11:00
l'utilisation du codage \textsc{ascii}\index{ascii}
2020-02-20 12:31:06 +11:00
(alors qu'on pourrait mettre du binaire, plus compact) y est
pour quelque chose.
2020-02-12 03:33:38 +11:00
2020-02-22 08:31:22 +11:00
\begin{lstlisting}
2020-02-12 03:33:38 +11:00
int fimg_save_as_pnm(FloatImg *head, char *fname, int flags);
2020-02-22 08:31:22 +11:00
\end{lstlisting}
2019-08-29 06:08:59 +11:00
2020-02-12 03:33:38 +11:00
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.
2019-08-07 20:10:12 +11:00
2020-02-20 12:31:06 +11:00
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.
2020-02-12 03:33:38 +11:00
Les autres bits ne sont pas utilisés et doivent être à zéro.
\subsubsection{Vers PNG}\index{PNG}
2020-09-03 10:35:54 +11:00
Actuellement, on peut enregistrer uniquement en mode RGB,
8 bits par composante,
2020-02-20 10:07:03 +11:00
mais on a quand même une bonne compression, ça compense.
2020-02-20 12:31:06 +11:00
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.
2020-03-01 07:59:12 +11:00
On peut aussi songer à l'export de metadatas.
2020-02-20 03:08:33 +11:00
2020-02-22 08:31:22 +11:00
\begin{lstlisting}
2020-02-20 10:07:03 +11:00
int fimg_save_as_png(FloatImg *src, char *outname, int flags);
2020-02-22 08:31:22 +11:00
\end{lstlisting}
2020-02-12 03:33:38 +11:00
2020-03-01 07:59:12 +11:00
Tous les flags doivent être à zéro. Sinon, ça foire parfois.
2021-03-17 20:55:34 +11:00
Et en fait (mars 2021) je ne suis pas très content de
\texttt{pnglite}, donc un de ces jours\footnote{Rendez-nous notre
Mixou !}, je prendrais cinq jours pour régler le souci.
2020-02-20 12:31:06 +11:00
2020-09-03 10:35:54 +11:00
\subsubsection{Vers TIFF}\index{TIFF}
2020-02-12 03:33:38 +11:00
2020-02-20 12:31:06 +11:00
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
2020-02-21 09:20:31 +11:00
classique proposé par les gros scanners corporates.
2020-02-20 12:31:06 +11:00
2020-09-03 10:35:54 +11:00
\begin{lstlisting}
2021-04-18 09:46:45 +11:00
int fimg_write_as_tiff(FloatImg *src, char *outname, int flags);
2020-09-03 10:35:54 +11:00
\end{lstlisting}
2021-04-18 09:46:45 +11:00
Tous les flags doivent être à zéro. Pour le moment.
2020-09-03 10:35:54 +11:00
2020-02-12 03:33:38 +11:00
2020-02-20 12:31:06 +11:00
\subsubsection{Vers FITS}\index{FITS}
2020-03-01 07:59:12 +11:00
Ce format est essentiellement utilisé pour stocker des images
2020-07-23 01:10:42 +11:00
d'astronomie, donc il peut aussi servir pour des images floues.
2020-07-25 19:42:55 +11:00
Cette partie est basée sur la bibliothèque \texttt{cfitsio} de
la NASA.
2020-02-20 12:31:06 +11:00
2020-07-25 19:42:55 +11:00
\begin{lstlisting}
int fimg_save_R_as_fits(FloatImg *src, char *outname, int flags);
2020-08-07 16:39:22 +11:00
int fimg_save_G_as_fits(FloatImg *src, char *outname, int flags);
int fimg_save_B_as_fits(FloatImg *src, char *outname, int flags);
2020-07-25 19:42:55 +11:00
\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.
2020-02-20 12:31:06 +11:00
2020-02-12 03:33:38 +11:00
\subsection{Utilitaires}
2020-02-20 12:31:06 +11:00
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.
2020-02-22 08:31:22 +11:00
\begin{lstlisting}
2020-02-12 03:33:38 +11:00
int parse_WxH(char *str, int *pw, int *ph)
int parse_double(char *str, double *dptr)
2020-02-22 08:31:22 +11:00
\end{lstlisting}
2020-02-12 03:33:38 +11:00
2020-02-20 12:31:06 +11:00
La fonction \texttt{int format\_from\_extension(char *fname)} examine un
2020-07-23 01:10:42 +11:00
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
2020-02-20 12:31:06 +11:00
le valeureux.
2020-07-23 01:10:42 +11:00
Les extensions actuellement connues sont : fimg, png, pnm, fits et tiff.
2020-02-20 12:31:06 +11:00
2020-03-01 07:59:12 +11:00
To be continued\index{XXX}\dots
2020-02-12 03:33:38 +11:00
\subsection{Effets}\index{sfx}
2020-07-23 01:10:42 +11:00
Quelques routines qui servent futilement à \textsl{brotcher} les images
en tripotant les flux visuels chromatiques.
2020-02-13 22:13:07 +11:00
2020-02-22 08:31:22 +11:00
\begin{lstlisting}
2020-02-13 22:13:07 +11:00
int fimg_killcolors_a(FloatImg *fimg, float fval);
int fimg_killcolors_b(FloatImg *fimg, float fval);
2020-07-23 01:10:42 +11:00
int fimg_colors_mixer_a(FloatImg *fimg, float fval);
2020-02-22 08:31:22 +11:00
\end{lstlisting}
2020-02-12 03:33:38 +11:00
2020-11-16 07:31:02 +11:00
\subsection{Glitches}\index{glitch}
2020-02-12 03:33:38 +11:00
2020-11-16 07:31:02 +11:00
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
2021-04-23 08:52:39 +11:00
et surtout répétitif. Un glitch est quasiment souvent un phénomène
2020-11-16 07:31:02 +11:00
aléatoire\index{drand48} et tout aussi paramétrable.
J'ai commencé à étudier ces objets étranges quand j'ai commencé
2021-04-23 08:52:39 +11:00
à 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 \textsc{Betamax}\index{Betamax}.
2020-02-12 03:33:38 +11:00
% ----------------------------------
\subsection{Filtrages}\index{filtrage}
Pour commencer, il faut que je réfléchisse au traitement
des bordures des images.
2020-03-01 07:59:12 +11:00
Ensuite que je débuggue\index{bug} ces deux fonctions~:
2020-02-12 03:33:38 +11:00
\begin{lstlisting}
int fimg_lissage_2x2(FloatImg *img);
2020-03-01 07:59:12 +11:00
int fimg_killborders(FloatImg *img);
\end{lstlisting}
2020-02-12 03:33:38 +11:00
2021-04-19 20:01:09 +11:00
Bon, oké, ça marche ? Passons à l'étape suivante.
2020-03-01 07:59:12 +11:00
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.
2020-03-24 21:45:09 +11:00
\begin{lstlisting}
2020-03-01 07:59:12 +11:00
typedef struct {
float matrix[9];
float mult;
float offset;
} FimgFilter3x3;
2020-03-24 21:45:09 +11:00
\end{lstlisting}
2020-03-01 07:59:12 +11:00
L'usage des champs \texttt{mult} et \texttt{offset} n'est pas
clairement défini. Le prototype de la fonction de filtrage
2021-04-19 20:01:09 +11:00
non plus, mais assez simple quand même. Source et destination
2020-03-01 07:59:12 +11:00
ne peuvent désigner la même image, et le champ \texttt{matrix}
du filtre doit contenir des valeurs cohérentes.
2020-03-24 21:45:09 +11:00
\begin{lstlisting}
2020-03-01 07:59:12 +11:00
int fimg_filter_3x3(FloatImg *src, FloatImg *dst, FimgFilter3x3 *filtr)
2020-03-24 21:45:09 +11:00
\end{lstlisting}
2020-03-01 07:59:12 +11:00
Comme dans la plupart des cas, la gestion des valeurs négatives
de pixel est laissé au hasard. Quoique, il doit bien exister
quelques solutions de contournement : clamping ou shift ?
\textsl{To be continued\index{XXX}\dots}
2020-02-12 03:33:38 +11:00
% ----------------------------------
2020-02-21 09:20:31 +11:00
\subsection{Exemple de fonction}\index{exemple}\label{exemplefunc}
2019-11-01 01:02:27 +11:00
2020-02-20 10:07:03 +11:00
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 interdit aux programmes
\textsl{enduser}. Soyez prudents.
Cette fonction va faire quelque chose
2019-11-01 01:02:27 +11:00
à 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
2020-02-20 10:07:03 +11:00
répandu par les temps qui courent.
2019-11-01 01:02:27 +11:00
2020-02-22 08:31:22 +11:00
\begin{lstlisting}
2019-11-01 01:02:27 +11:00
int fimg_example(FloatImg *s, FloatImg *d, float value)
{
int size, index;
if ( s->type!=FIMG_TYPE_RGB || d->type!=FIMG_TYPE_RGB) {
2020-02-20 10:07:03 +11:00
perror("fimg_example");
2019-11-01 01:02:27 +11:00
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;
}
2020-02-22 08:31:22 +11:00
\end{lstlisting}
2019-11-01 01:02:27 +11:00
Je vous laisse imaginer les dégats que peut faire cette
2020-09-03 10:35:54 +11:00
fonction en utilisation réelle. Mieux, je vous propose
2021-04-23 08:52:39 +11:00
d'essayer par vous-même, vous allez voir, c'est assez créatif.
2019-11-01 01:02:27 +11:00
En particulier tout le reste du code qui suppose qu'un pixel
2020-09-03 10:35:54 +11:00
ne peut \textbf{pas} être négatif va peut-être exploser de rire.
2019-11-01 01:02:27 +11:00
Vous pouvez aussi remarquer qu'il n'y a pas de controle
2020-01-15 04:00:10 +11:00
de cohérence sur les dimensions des deux images, malgré l'existence
2021-04-23 08:52:39 +11:00
de fonctions prévues à cet effet\dots
2019-11-01 01:02:27 +11:00
2021-04-19 20:01:09 +11:00
% ===================================================================
2019-08-07 20:10:12 +11:00
\section{Les outils}\label{outils}
2019-05-20 17:47:13 +11:00
2020-02-22 08:31:22 +11:00
\textsf{3615mavie} : sur des projets comme celui-ci, qui travaillent
2019-08-03 23:27:21 +11:00
in-fine sur des objets que l'on peut considérer comme « physiques »,
il est important de passer à une utilisation
normale\footnote{Il y a une vie en dehors de git.} et construire
des trucs qui mettent en action le code primitif.
2019-08-11 03:37:52 +11:00
2020-02-20 10:07:03 +11:00
Ces machins 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.
2019-08-11 03:37:52 +11:00
Dans un avenir incertain, il existera des pages de man\index{man}.
2019-08-03 23:27:21 +11:00
2020-02-12 03:33:38 +11:00
% ---------------------
2019-08-03 23:27:21 +11:00
\subsection{mkfimg}\index{mkfimg}\label{mkfimg}
2020-02-20 10:07:03 +11:00
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,
2020-02-12 03:33:38 +11:00
mais ça n'est pas si grave que ça.
2019-09-29 10:57:25 +11:00
\begin{verbatim}
2020-02-12 03:33:38 +11:00
tth@debian:~/Devel/FloatImg/tools$ ./mkfimg -h
2019-09-29 10:57:25 +11:00
Usage: mkfimg [options] quux.fimg width height
-k N.N give a float parameter
2020-02-13 22:13:07 +11:00
-t type howto make the pic
2019-09-29 10:57:25 +11:00
black, drand48...
-v increase verbosity
\end{verbatim}
2019-08-03 23:27:21 +11:00
2020-02-13 22:13:07 +11:00
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
2021-04-23 08:52:39 +11:00
à $1.0$, ce qui n'est pas toujours une bonne valeur.
2020-02-13 22:13:07 +11:00
2020-02-20 10:07:03 +11:00
\begin{description} \index{XXX}
2020-02-13 22:13:07 +11:00
\item [black/gray/grey:] efface avec 0.0 (black) ou avec la valeur
\texttt{-k} (gray).
\item [drand48:] beaucoup de bruit dans chacun des canaux.
\item [hdeg/vdeg:] dégradé du noir au blanc (relatif à \texttt{-k}).
\end{description}
2020-02-12 03:33:38 +11:00
% ---------------------
\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}
2019-12-21 23:50:15 +11:00
Il faut peut-être envisager le passage à \texttt{libpng}\index{libpng}.
2019-08-03 23:27:21 +11:00
\subsection{fimgstats}\index{fimgstats}\label{fimgstats}
2019-09-29 22:45:33 +11:00
Affichage de quelques valeurs calculées à partir du contenu d'un fichier
2019-08-03 23:27:21 +11:00
\texttt{.fimg}\index{.fimg}.
2019-09-11 15:19:32 +11:00
\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
2019-09-29 22:45:33 +11:00
en première approche, alors commençont par le plus simple,
les valeurs moyennes de chaque composante.
2019-11-01 01:02:27 +11:00
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}.
2020-02-12 03:33:38 +11:00
% ---------------------
2019-11-30 03:06:40 +11:00
2020-02-12 03:33:38 +11:00
\subsection{fimgfx}\index{fimgfx}\label{fimgfx}
2020-02-12 03:33:38 +11:00
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
2019-12-21 23:50:15 +11:00
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 ---
2020-10-04 00:52:27 +11:00
cos01 cos010 pow2 sqrt gray0 cmixa xper desat
\end{verbatim}
2020-02-12 03:33:38 +11:00
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}.
2020-02-13 22:13:07 +11:00
\begin{description}
\item [Ajustements de contraste:] cos01 cos010 pow2 sqrt
\item [Distorsions chromatiques:] gray0
\item [Déformations géométriques:] r90
\end{description}
2020-02-12 03:33:38 +11:00
2020-10-07 01:30:42 +11:00
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.
% ---------------------
2019-08-29 06:08:59 +11:00
\subsection{fimgops}\index{fimgops}\label{fimgops}
2019-11-30 03:06:40 +11:00
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.
2019-08-29 06:08:59 +11:00
2019-09-11 15:19:32 +11:00
\begin{verbatim}
2019-09-12 03:58:39 +11:00
usage:
2019-09-11 15:19:32 +11:00
fimgops [options] A.fimg B.fimg operator D.fimg
2019-09-12 03:58:39 +11:00
operators:
add 1
sub 2
mix 3
mul 4
2019-11-20 21:12:16 +11:00
mini 5
maxi 6
2019-09-12 03:58:39 +11:00
options:
-g convert output to gray
-k N.N set float value
-v increase verbosity
-X explosive action
2019-09-11 15:19:32 +11:00
\end{verbatim}
2019-08-29 06:08:59 +11:00
2019-11-20 21:12:16 +11:00
Pour des operateurs paramétrable (comme \texttt{mix}), le paramêtre
flottant doit être fourni en utilisant l'option \texttt{-k}.
2020-02-20 10:07:03 +11:00
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.
2019-08-29 06:08:59 +11:00
2020-03-01 07:59:12 +11:00
% -------------------------
2020-07-23 01:10:42 +11:00
\subsection{fimg2png, fimg2pnm, fimg2tiff, fimg2fits}
2019-08-11 03:37:52 +11:00
\index{fimg2png}\label{fimg2png}
\index{fimg2pnm}\label{fimg2pnm}
\index{fimg2tiff}\label{fimg2tiff}
2020-07-23 01:10:42 +11:00
\index{fimg2fits}\label{fimg2fits}
Quelques petits proggies pour exporter notre format\index{.fimg} secret
vers des choses plus directement utilisables. À condition que le
2020-02-12 03:33:38 +11:00
code soit écrit et documenté.
2019-11-12 10:19:32 +11:00
D'un autre coté, écrire un greffon d'import/export pour
2020-03-01 07:59:12 +11:00
Gimp\index{Gimp} ou ImageMagick\index{ImageMagick} ou Krita\index{krita}
2019-11-12 10:19:32 +11:00
ne devrait pas être trop difficile. Des volontaires ?
2019-08-11 03:37:52 +11:00
2020-07-23 01:10:42 +11:00
\textsl{D'ailleurs, pourquoi $N$ logiciels indépendants alors q'un
seul devrait être nécessaire ?}
2021-04-25 00:18:06 +11:00
% -------------------------
\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 ?
% -------------------------
\subsection{fimg2gray}\index{fimg2gray}\label{fimg2gray}
Nous avons vu dans ce document que chaque image flottante pouvait
2021-04-25 00:18:06 +11:00
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.
2019-08-11 03:37:52 +11:00
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.
2020-10-04 00:52:27 +11:00
\index{procrastination}
Et face à l'incertitude du choix, j'ai reporté l'écriture de ce
2021-04-25 00:18:06 +11:00
logiciel aux calendes grecques, voire même plus tard,
après la grande pandémie\dots
% -------------------------
2020-10-04 00:52:27 +11:00
\subsection{cumulfimgs}\index{cumulfimgs}\label{cumulfimgs}
Cet outil accumule\index{cumul} une quantité d'images flottantes
2021-04-23 08:52:39 +11:00
(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} ?}
2020-10-04 00:52:27 +11:00
\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}.
2021-04-19 20:01:09 +11:00
L'exportation « multiformat » est pour bientôt.
2019-08-11 03:37:52 +11:00
2021-04-23 08:52:39 +11:00
% ===================================================================
\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 \textsc{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
2021-04-19 20:01:09 +11:00
% ===================================================================
2020-10-04 00:52:27 +11:00
\section{TODO}\index{TODO}\label{TODO}\
\index{XXX}
2019-08-29 06:08:59 +11:00
2020-02-21 09:20:31 +11:00
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
2021-04-23 08:52:39 +11:00
choses seront acquises, pour le pire, le meilleur et la
futilité du monde futur..
2020-02-20 03:08:33 +11:00
2019-09-06 00:51:30 +11:00
\begin{itemize}
2021-04-23 08:52:39 +11:00
\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}).
2020-01-11 03:22:58 +11:00
\item Formaliser les codes d'erreur. \textbf{Urgent}.
2020-02-21 09:20:31 +11:00
\item Faire une passe complète de Valgrind\index{valgrind}.
2021-04-23 08:52:39 +11:00
\item Intégrer la fonderie, l'interpolator et le singlepass.
2020-10-04 00:52:27 +11:00
\item Vérifier le gestion des images mono-canal.
\end{itemize}
2019-08-29 06:08:59 +11:00
2021-04-19 20:01:09 +11:00
% ===================================================================
2020-02-12 03:33:38 +11:00
\section{Exemples pour yusers}\index{exemple}
2019-09-11 15:19:32 +11:00
2019-11-12 10:19:32 +11:00
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.
2019-11-12 10:19:32 +11:00
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 : ue se passe-t-il si
nous faisons la somme de plusieurs centaines de ces images ?
2019-11-12 10:19:32 +11:00
2020-02-21 22:54:50 +11:00
\begin{lstlisting}
2019-09-11 15:19:32 +11:00
#!/bin/bash
ACCU="quux.fimg"
TMPF="tmp.fimg"
2019-11-12 10:19:32 +11:00
DIMS="320 240"
mkfimg $ACCU $DIMS
for i in {0..1000}
2019-09-11 15:19:32 +11:00
do
mkfimg -t drand48 ${TMPF} ${DIMS}
2019-11-12 10:19:32 +11:00
fname=$( printf "xx%04d.pnm" $i )
fimgops $ACCU $TMPF add $ACCU
fimg2pnm -v -g $ACCU $fname
2019-09-11 15:19:32 +11:00
done
2019-11-12 10:19:32 +11:00
convert -delay 10 xx*.pnm foo.gif
2020-02-21 22:54:50 +11:00
\end{lstlisting}
2019-09-11 15:19:32 +11:00
2019-11-12 10:19:32 +11:00
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...
2019-11-30 06:35:23 +11:00
\subsection{Scripts}\index{scripts}\label{scripts}
2019-11-12 10:19:32 +11:00
2020-02-20 10:07:03 +11:00
Le script bash\index{bash} \texttt{scripts/shoot.sh} est un front-end
encore un peu rudimentaire
2020-02-13 22:13:07 +11:00
vers le programme de capture d'image décrit page \pageref{grabvidseq}.
Il utilise deux fichiers dans le répertoire de travail~:
2020-02-20 10:07:03 +11:00
\textit{reglages} et \textit{compteur}. Le premier est, en fait,
2020-07-23 01:10:42 +11:00
un bout de shell affectant quelques variables, ou plutôt, les surchargeant.
Voici un exemple de réglage~:
2020-02-20 10:07:03 +11:00
2020-02-21 22:54:50 +11:00
\begin{lstlisting}
2020-02-20 10:07:03 +11:00
OPTIONS="${OPTIONS} -v -c pow2 "
SHOW="yes"
NBRE=1000
PERIOD=0
OFORMAT="p_%04d.png"
2020-02-21 22:54:50 +11:00
\end{lstlisting}
2020-02-20 10:07:03 +11:00
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
2020-02-21 20:38:01 +11:00
vue quelques lignes plus haut.
2019-10-31 06:09:32 +11:00
2020-02-21 22:54:50 +11:00
\lstinputlisting[language=sh]{../scripts/shoot.sh}
2020-01-23 22:50:37 +11:00
\subsection{Fonderie}\index{fonderie}\label{fonderie}
2020-02-20 10:07:03 +11:00
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
2020-02-21 20:38:01 +11:00
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, indispendable à 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és 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.
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
2021-04-18 09:46:45 +11:00
\texttt{bc}\index{bc}%
\footnote{\texttt{bc}, c'est vraiment un truc à découvrir.}
2020-02-21 20:38:01 +11:00
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
2020-09-03 10:35:54 +11:00
savants calculs au format PNG, et écrivons le fichier dans le répertoire
2020-02-21 20:38:01 +11:00
de destination fixé au début.
C'est le moment de passer la main à ffmpeg\index{ffmpeg}.
2020-01-23 22:50:37 +11:00
2020-02-21 09:20:31 +11:00
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.
2021-04-19 20:01:09 +11:00
% ===================================================================
2019-08-03 23:27:21 +11:00
\section{Video for Linux}\index{v4l2}
2019-08-11 03:37:52 +11:00
Donc, maintenant, nous savons un peu tripoter ces images flottantes.
2019-08-03 23:27:21 +11:00
Et nous devons nous poser une question fondamentale\footnote{primitive ?}
2019-08-07 06:22:12 +11:00
sur la provenance de ces données prétendant être des images.
2020-02-20 03:08:33 +11:00
2020-07-23 01:10:42 +11:00
En fait, notre désir secret (enfin, surtout le mien)
est la découverte des choses cachées du
2019-08-11 03:37:52 +11:00
monde qui nous entoure. Nous voulons des images du \textbf{réel} et
pour cela, l'outil le plus commun, le plus répandu,
2019-08-12 10:53:17 +11:00
est la webcam\index{webcam}. L'universelle webcam. Et l'incontournable
v4l2.
2019-08-03 23:27:21 +11:00
\subsection{grabvidseq}\index{grabvidseq}\label{grabvidseq}
2020-03-02 11:19:57 +11:00
Un logiciel en évolution (trop ?) lente, qui permet déja la capture
d'images en
2019-11-12 10:19:32 +11:00
\textsl{longue pose} selon la méthode du cumul\index{cumul}, et
devrait bientôt retrouver sa capacité à enregistrer des
2020-03-02 11:19:57 +11:00
séquences d'images.
\begin{verbatim}
tth@debian:~/Devel/FloatImg/v4l2$ ./grabvidseq -h
options :
2020-01-23 22:50:37 +11:00
-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
2019-10-31 06:09:32 +11:00
-p NN.N delay between frames
2020-07-23 01:10:42 +11:00
-r 90 mode portrait
-s WxH size of capture
-u try upscaling...
-v increase verbosity
2019-11-12 10:19:32 +11:00
-X arg Xperiment option
\end{verbatim}
2019-11-01 01:02:27 +11:00
La plupart de ces options ont un usage quasi-évident.
2019-10-31 06:09:32 +11:00
L'option \texttt{-s} doit correspondre à une des
2019-11-01 01:02:27 +11:00
résolutions possibles de votre capteur. Le type du
fichier en sortie (option \texttt{-o}) est déterminé par
2020-09-03 10:35:54 +11:00
l'extension du nom.
Actuellement
seulement \texttt{.fimg}, \texttt{.pnm}, \texttt{.fits},
\texttt{.tiff} et \texttt{.png}
2020-02-20 03:08:33 +11:00
sont reconnus.
2019-11-12 10:19:32 +11:00
La conversion en gris (option \texttt{-g}) mérite un
peu plus de travail, et une paramétrisation plus facile.
2020-02-20 03:08:33 +11:00
L'ajustement de contraste (option\texttt{-c}) est
vaguement expliqué page \pageref{contraste}.
2019-11-12 10:19:32 +11:00
L'option \texttt{-X} me permet d'intégrer des \textit{fritures}
expérimentales dans le binaire, et ne doit donc pas être
2021-04-18 09:46:45 +11:00
utilisée dans des scripts si on a des visions à long (ou même)
2019-11-12 10:19:32 +11:00
terme.
2019-10-31 06:09:32 +11:00
\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
2019-11-30 03:06:40 +11:00
ê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.
2019-11-12 10:19:32 +11:00
\textbf{Là, il manque un schéma\dots}
2019-09-11 15:19:32 +11:00
\subsection{video-infos}\index{video-infos}\label{video-infos}
Que contient, que peut faire mon périphérique \textsl{àlc} ?
2019-10-31 06:09:32 +11:00
Quelles sont ses possibilités de réglage ?
\begin{verbatim}
tth@debian:~/Devel/FloatImg$ v4l2/video-infos -h
Options :
-d select the video device
2019-11-12 10:19:32 +11:00
-K nnn set the K parameter
2019-10-31 06:09:32 +11:00
-l list video devices
-T bla add a title
-v increase verbosity
\end{verbatim}
2020-01-23 22:50:37 +11:00
Je me sens obligé d'avouer qu'il reste quelques points mystérieux dans
2019-11-12 10:19:32 +11:00
l'\textsc{api} de \textsc{v4l2}, et donc, que ce que raconte
ce logiciel doit être pris avec des pincettes. En particulier
la liste des résolutions disponibles.
2019-09-11 15:19:32 +11:00
2020-03-08 01:24:31 +11:00
\subsection{nc-camcontrol}
Ajustement \textsl{Brightness Contrast Saturation Hue\dots}
2021-04-19 20:01:09 +11:00
% ===================================================================
2020-03-01 07:59:12 +11:00
\section{À l'extérieur}
\subsection{ImageMagick}\index{ImageMagick}
Pour afficher notre format .fimg exotique avec \texttt{display}, vous
devez mettre ce bout de XML\index{XML} dans le fichier
\texttt{\$HOME/.magick/delegates.xml}~:
2020-03-24 21:45:09 +11:00
\begin{lstlisting}
2020-03-01 07:59:12 +11:00
<?xml version="1.0" encoding="UTF-8"?>
<delegatemap>
2020-03-24 21:45:09 +11:00
<delegate decode="fimg" command="fimg2png '%i' '%o'"/>
2020-03-01 07:59:12 +11:00
</delegatemap>
2020-03-24 21:45:09 +11:00
\end{lstlisting}
2020-03-01 07:59:12 +11:00
C'est juste un hack rapide, qui ne fonctionne pas très bien avec
d'autres commande de IM, comme identify, qui a tendance à
2021-04-03 04:12:22 +11:00
raconter un peu n'importe quoi, puisqu'elle se base sur le
résultat de la conversion\dots
Je compte donc sur le bouquin de \textsl{Brunus} pour avancer\dots
2020-03-01 07:59:12 +11:00
\subsection{Gimp}\index{Gimp}
2020-09-03 10:35:54 +11:00
Mmmmm... Ça semble un peu plus compliqué.
La documentation à ce sujet me semble ésotérique.
D'un autre coté, il
2021-04-18 09:46:45 +11:00
faut faire ça en \textbf{C}, ce qui ne peut pas être négatif.
2020-03-01 07:59:12 +11:00
2020-09-03 10:35:54 +11:00
\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 \
stereo.mp4
\end{lstlisting}
2020-03-01 07:59:12 +11:00
\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
2021-04-18 09:46:45 +11:00
\textsl{Krita} qui semble avoir les faveurs de
dessinateurs de talent\footnote{Oui, David, c'est à toi que je pense.}.
2020-03-01 07:59:12 +11:00
2019-08-03 23:27:21 +11:00
% -------------------------------------------------------------------
2021-04-18 09:46:45 +11:00
% ===================================================================
\section{Le flou temporel}
Et si nous jouions sur l'axe du temps ?
Nous avons plus ou moins la magie du cumul sur la prise de vue
d'\textbf{image} en enchainant plusieurs capture d'image.
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.
2021-04-19 20:01:09 +11:00
Par ailleurs, il m'a semblé pertinent d'inclure dans le projet une
foultitude d'effets spéciaux.
\subsection{\textsl{moving average}}
2021-04-18 09:46:45 +11:00
2021-04-23 08:52:39 +11:00
\texttt{./fonderie} : Basé sur la moyenne mobile, avec une structure de
fifo\index{fifo} particulièrement mal conçue.
2021-04-18 09:46:45 +11:00
\subsection{Interpolator}\index{interpolator}
Juste des calculs pas si simple que ça.
2021-04-19 20:01:09 +11:00
\subsection{Singlepass}
Ce programme \texttt{singlepass} prétend vous permettre de tester
tous les filtres disponibles, dont on peut avoir la liste
avec l'option \texttt{-L}\footnote{liste hélas peu machinable.}
2021-04-18 09:46:45 +11:00
\subsection{Déviance}
2021-04-23 08:52:39 +11:00
Là, nous tombons dans de la \textsl{troiD}\index{3d} de haut niveau,
avec plein de maths compliquées
2021-04-18 09:46:45 +11:00
à l'intérieur.
2021-04-23 08:52:39 +11:00
Et surtout quelque chose qui n'est encore qu'une idée abstraite,
mais il y aura du zbuffer dedans.
2021-04-18 09:46:45 +11:00
% ===================================================================
2019-08-03 23:27:21 +11:00
\section{Et pour la suite ?}
En fait, je fait de la photo par la méthode du « cumul »\index{cumul}
2019-08-07 06:22:12 +11:00
depuis plusieurs années. Une webcam\index{webcam},
un Linux\index{Linux}, et ça \textsl{juste marche}.
Sauf que c'est quand même un peu galère à déplacer, il faut
2019-08-11 03:37:52 +11:00
avoir un shell pour déclencher, c'est pas facile à utiliser
en mode portnawak\dots
2020-02-20 03:08:33 +11:00
2019-08-29 06:08:59 +11:00
L'idée est donc de construire un appareil autonome, basé sur un Raspi et
2020-01-23 22:50:37 +11:00
une webcam \textsc{usb}\index{USB}, pilotable par \textsc{lirc}\index{LIRC},
alimenté par une (grosse) batterie et permettant d'aller
2019-11-30 03:06:40 +11:00
faire des images au bord d'un lac ou dans la campagne de l'Ariège.
2019-08-07 06:22:12 +11:00
2019-05-20 17:47:13 +11:00
% -------------------------------------------------------------------
2021-04-23 08:52:39 +11:00
% XXX
% maintenant, comment faire un index sur trois colonnes ?
%
2019-05-20 17:47:13 +11:00
\printindex
\end{document}