2019-08-07 20:10:12 +11:00
|
|
|
\documentclass[a4paper,11pt]{article}
|
2019-05-20 17:47:13 +11:00
|
|
|
|
|
|
|
% \listfiles % pour le debug
|
|
|
|
|
|
|
|
\usepackage[french]{babel}
|
|
|
|
\usepackage[utf8]{inputenc}
|
|
|
|
\usepackage[T1]{fontenc}
|
|
|
|
% XXX \usepackage{lipsum}
|
|
|
|
\usepackage{makeidx}
|
|
|
|
\usepackage{listings}
|
|
|
|
% \usepackage{color}
|
|
|
|
% \usepackage{url}
|
|
|
|
\usepackage{xspace}
|
|
|
|
\usepackage[verbose]{layout}
|
|
|
|
|
|
|
|
\makeindex
|
|
|
|
% -------------------------------------------------------------------
|
2019-08-02 13:22:48 +11:00
|
|
|
\title{Floating images processing}
|
2019-05-20 17:47:13 +11:00
|
|
|
\author{tTh}
|
|
|
|
|
|
|
|
\begin{document}
|
|
|
|
\maketitle
|
2019-08-02 13:22:48 +11:00
|
|
|
|
|
|
|
\section{Image flottante ?}
|
|
|
|
|
|
|
|
De quoi parle-t-on exactement ?
|
2019-08-03 23:27:21 +11:00
|
|
|
\vspace{1em}
|
|
|
|
|
|
|
|
Traditionnellement, les valeurs des pixels dans les images
|
|
|
|
informatiques sont mémorisées sur 8 bits, un octet\index{octet},
|
|
|
|
soit 256 valeurs différentes.
|
|
|
|
Ceci dit, on trouve parfois des images codées sur 16 bits par
|
|
|
|
composante, mais c'est loin d'être le cas général.
|
|
|
|
J'ai donc souhaité aller plus loin, et coder chaque canal de
|
|
|
|
chaque pixel en virgule flottante sur 32bits, le type
|
|
|
|
\texttt{float}\index{float} du langage C.
|
2019-08-02 13:22:48 +11:00
|
|
|
|
|
|
|
% -------------------------------------------------------------------
|
|
|
|
|
2019-05-20 17:47:13 +11:00
|
|
|
\tableofcontents
|
2019-08-03 23:27:21 +11:00
|
|
|
\pagebreak
|
2019-05-20 17:47:13 +11:00
|
|
|
|
2019-08-02 13:22:48 +11:00
|
|
|
% -------------------------------------------------------------------
|
2019-08-07 20:52:04 +11:00
|
|
|
\section{Example}\index{example}\label{example}
|
2019-05-20 17:47:13 +11:00
|
|
|
|
2019-08-07 20:10:12 +11:00
|
|
|
Pour commencer par quelques 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.
|
|
|
|
|
|
|
|
Tout d'abord, nous devons déclarer et garnir quelques variables
|
|
|
|
pour gérer la machinerie interne.
|
|
|
|
|
|
|
|
\begin{verbatim}
|
|
|
|
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;
|
|
|
|
\end{verbatim}
|
|
|
|
|
|
|
|
Ensuite, nous enchainerons trois étapes : création de l'image
|
|
|
|
en mémoire centrale, initialisations des valeurs de pixel à 0.0,
|
|
|
|
et pour conclure, enregistrement dans un fichier.
|
|
|
|
|
|
|
|
\begin{verbatim}
|
|
|
|
foo = fimg_create(&fimg, width, height, 3);
|
|
|
|
if (foo) {
|
|
|
|
fprintf(stderr, "create floatimg -> %d\n", foo);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
fimg_clear(&fimg);
|
|
|
|
foo = fimg_dump_to_file(&fimg, fname, 0);
|
|
|
|
if (foo) {
|
|
|
|
fprintf(stderr, "dump fimg -> %d\n", foo);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
\end{verbatim}
|
|
|
|
|
|
|
|
|
|
|
|
Une fois ce code enrobé dans un \texttt{main()}, compilé et exécuté,
|
|
|
|
nous pouvons entrevoir, grâce au logiciel
|
|
|
|
\texttt{fimgstats} (voir page \pageref{fimgstats}),
|
|
|
|
le résultat sous forme de chiffres divers, et/ou inutiles~:
|
|
|
|
|
|
|
|
\begin{verbatim}
|
|
|
|
$ ./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}
|
|
|
|
|
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
|
|
|
|
sous formes d'outils en ligne de commande, décrits page \pageref{outils}.
|
|
|
|
|
2019-08-03 23:27:21 +11:00
|
|
|
% -------------------------------------------------------------------
|
2019-08-07 20:10:12 +11:00
|
|
|
\section{Installation}
|
2019-08-03 23:27:21 +11:00
|
|
|
|
|
|
|
Pour le moment, la procédure d'installation est un peu rude,
|
|
|
|
pour ne pas dire clairement sommaire.
|
|
|
|
Un script \texttt{build.sh} permet de construire approximativement
|
|
|
|
le bouzin. Il est loin d'être parfait.
|
2019-08-07 06:22:12 +11:00
|
|
|
\vspace{1em}
|
2019-08-03 23:27:21 +11:00
|
|
|
|
2019-08-07 06:22:12 +11:00
|
|
|
Si le résultat vous semble correct, vous pouvez copier
|
2019-08-07 20:52:04 +11:00
|
|
|
les deux fichiers \texttt{floatimg.h} et \texttt{libfloatimg.a}
|
|
|
|
dans un emplacement
|
2019-08-07 06:22:12 +11:00
|
|
|
approprié, par exemple
|
|
|
|
\texttt{/usr/local/include} et \texttt{/usr/local/lib}.
|
2019-08-03 23:27:21 +11:00
|
|
|
|
2019-08-02 13:22:48 +11:00
|
|
|
% -------------------------------------------------------------------
|
2019-08-07 20:10:12 +11:00
|
|
|
\section{Utilisation}
|
|
|
|
|
|
|
|
Classiquement, il y a un fichier à inclure, \texttt{floatimg.h},
|
|
|
|
contenant un certain nombre de
|
|
|
|
définition de structures, de macros,
|
|
|
|
de constantes\footnote{À l'ancienne, via le pré-processur}
|
|
|
|
et les prototypes des fonctions utilisables.
|
2019-08-07 20:52:04 +11:00
|
|
|
\vspace{1em}
|
2019-08-07 20:10:12 +11:00
|
|
|
|
|
|
|
Au niveau du code source, ces fonctions sont approximativement
|
|
|
|
classées en deux catégories : \texttt{lib/} et \texttt{funcs/}.
|
|
|
|
La première contient les choses qui sont relativement figées,
|
|
|
|
et la seconde celles qui risquent de bouger. Cette classification
|
|
|
|
est en fait arbitraire.
|
|
|
|
|
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
|
|
|
|
de données (certains appelent ça des \textsl{metadats}) regroupées
|
|
|
|
dans une jolie structure que nous allons examiner dès maintenant.
|
|
|
|
|
2019-08-09 02:16:20 +11:00
|
|
|
\begin{verbatim}
|
2019-08-11 03:37:52 +11:00
|
|
|
/* in memory descriptor */
|
2019-08-09 02:16:20 +11:00
|
|
|
typedef struct {
|
|
|
|
int width;
|
|
|
|
int height;
|
|
|
|
int type;
|
|
|
|
float fval;
|
|
|
|
int count;
|
|
|
|
float *R, *G, *B, *A;
|
|
|
|
int reserved;
|
|
|
|
} FloatImg;
|
|
|
|
\end{verbatim}\index{FloatImg}
|
|
|
|
|
2019-08-11 03:37:52 +11:00
|
|
|
Les deux premiers champs sont \textsl{obvious}.
|
|
|
|
Le troisième est le type d'image : pour le moment, il y en a trois
|
|
|
|
qui sont définis\footnote{et plus ou moins bien gérés\dots} :
|
|
|
|
gris, rgb et rgba\index{rgba}.
|
|
|
|
|
|
|
|
\begin{verbatim}
|
|
|
|
#define FIMG_TYPE_GRAY 1
|
|
|
|
#define FIMG_TYPE_RGB 3
|
|
|
|
#define FIMG_TYPE_RGBA 4
|
|
|
|
\end{verbatim}
|
|
|
|
|
2019-08-24 22:24:01 +11:00
|
|
|
Un peu plus loin, nous avons les pointeurs vers les
|
|
|
|
différents \textsl{pixmaps} de l'image. En principe l'organisation
|
|
|
|
interne de ces zones est improbable, puisque qu'elle dérive
|
|
|
|
d'idées approximatives.
|
|
|
|
\vspace{1em}
|
2019-08-11 03:37:52 +11:00
|
|
|
|
2019-08-24 22:24:01 +11:00
|
|
|
Les deux champs suivants (fval et count) sont à la disposition du
|
|
|
|
\textsl{yuser}
|
|
|
|
qui peut jouer avec à loisir pour faire, par exemple, ce genre de
|
|
|
|
chose. Imaginons un périphérique de capture qui nous fournisse des
|
|
|
|
images en gris sur 4 bits. Et que nous voulions cumuler\index{cumul}
|
|
|
|
quelques images...
|
|
|
|
\vspace{1em}
|
2019-08-11 03:37:52 +11:00
|
|
|
|
2019-08-24 22:24:01 +11:00
|
|
|
Le champ \textsl{count} sera mis à 0 et
|
|
|
|
le champ \textsl{fval} sera initialisé à 15.0
|
|
|
|
(valeur maximale renvoyée par le capteur).
|
|
|
|
Ensuite, dans la boucle capture/cumul, \textsl{count} sera
|
|
|
|
incrémenté à chaque passe, et nous aurons donc, en finale,
|
|
|
|
toutes les informations nécéssaire pour exploiter au mieux la dynamique
|
|
|
|
de notre image dans les étapes ultérieures.
|
2019-08-11 03:37:52 +11:00
|
|
|
|
|
|
|
|
|
|
|
|
2019-08-09 02:16:20 +11:00
|
|
|
|
2019-08-07 20:10:12 +11:00
|
|
|
\subsection{lib/}\index{lib/}
|
|
|
|
|
2019-08-07 20:52:04 +11:00
|
|
|
Première chose, la gestion dynamique de la mémoire occupées
|
|
|
|
par tous ces pixels flottants est faite par ces deux fonctions~:
|
2019-08-07 20:10:12 +11:00
|
|
|
|
|
|
|
\begin{verbatim}
|
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);
|
|
|
|
\end{verbatim}
|
|
|
|
|
2019-08-07 20:52:04 +11:00
|
|
|
Les types d'images actuellement gérés sont les trois grands
|
|
|
|
classiques : gray, rgb et rgba. Il y a les constantes adéquates
|
2019-08-11 03:37:52 +11:00
|
|
|
dans \texttt{floatimg.h}. Les codes d'erreur sont disparates
|
|
|
|
et non documenté.
|
|
|
|
\vspace{1em}
|
|
|
|
|
|
|
|
|
|
|
|
Bon, vous avez une image latente, et
|
|
|
|
vous souhaité dessiner dessus (ou dedans ?) avec vos encres
|
|
|
|
flottantes ?
|
2019-08-07 20:52:04 +11:00
|
|
|
|
2019-08-24 22:24:01 +11:00
|
|
|
\subsection{funcs/}\index{funcs/}\label{funcs}
|
2019-08-07 20:10:12 +11:00
|
|
|
|
2019-08-11 03:37:52 +11:00
|
|
|
Une bonne partie de ces fonctions est indéterministe. Ce qui
|
|
|
|
veut dire, en langage de tous les soirs, que ça risque de ne
|
|
|
|
pas être la même chose dans l'avenir.
|
2019-08-07 20:10:12 +11:00
|
|
|
|
|
|
|
% -------------------------------------------------------------------
|
|
|
|
\section{Les outils}\label{outils}
|
2019-05-20 17:47:13 +11:00
|
|
|
|
2019-08-03 23:27:21 +11:00
|
|
|
\textsl{3615mavie} : sur des projets comme celui-ci, qui travaillent
|
|
|
|
in-fine sur des objets que l'on peut considérer comme « physiques »,
|
|
|
|
il est important de passer à une utilisation
|
|
|
|
normale\footnote{Il y a une vie en dehors de git.} et construire
|
|
|
|
des trucs qui mettent en action le code primitif.
|
2019-08-11 03:37:52 +11:00
|
|
|
\vspace{1em}
|
|
|
|
|
|
|
|
Ces machins ont en commun deux options bien pratiques~:
|
|
|
|
\texttt{-h} pour avoir un résumé des options disponibles
|
|
|
|
et \texttt{-v} qui augmente la puissance de bavardage.
|
|
|
|
Dans un avenir incertain, il existera des pages de man\index{man}.
|
2019-08-03 23:27:21 +11:00
|
|
|
|
|
|
|
|
|
|
|
\subsection{mkfimg}\index{mkfimg}\label{mkfimg}
|
|
|
|
|
2019-08-24 22:24:01 +11:00
|
|
|
Création d'un fichier contenant une image de « teinte » constante.
|
|
|
|
Cette notion de teinte est assez inconsistante pour le moment,
|
|
|
|
puisqu'il n'y a que la valeur par defaut : \textbf{0.0} que
|
|
|
|
l'on peut assimiler à un noir absolu\index{absolu}.
|
2019-08-03 23:27:21 +11:00
|
|
|
|
|
|
|
\subsection{fimgstats}\index{fimgstats}\label{fimgstats}
|
|
|
|
|
|
|
|
Affichage de quelques valeurs calculées à partir d'un fichier
|
|
|
|
\texttt{.fimg}\index{.fimg}.
|
|
|
|
|
2019-08-24 22:24:01 +11:00
|
|
|
\subsection{fimg2png, fimg2pnm, fimg2tiff}
|
2019-08-11 03:37:52 +11:00
|
|
|
\index{fimg2png}\label{fimg2png}
|
|
|
|
\index{fimg2pnm}\label{fimg2pnm}
|
2019-08-24 22:24:01 +11:00
|
|
|
\index{fimg2tiff}\label{fimg2tiff}
|
|
|
|
|
|
|
|
Quelques petits proggies pour exporter notre format\index{.fimg} secret
|
|
|
|
vers des choses plus directement utilisables. À condition que le
|
|
|
|
code soit écrit et documenté en page \pageref{funcs}.
|
2019-08-11 03:37:52 +11:00
|
|
|
|
2019-08-24 22:24:01 +11:00
|
|
|
\subsection{fimg2gray}\index{fimg2gray}\label{fimg2gray}
|
|
|
|
|
|
|
|
Nous avons vu dans ce document que chaque image flottante pouvait
|
|
|
|
avoir plusieurs plans de réalité. Il ne faut en négliger aucun.
|
|
|
|
\vspace{1em}
|
2019-08-11 03:37:52 +11:00
|
|
|
|
2019-08-24 22:24:01 +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.
|
2019-08-11 03:37:52 +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.
|
2019-08-11 03:37:52 +11:00
|
|
|
\vspace{1em}
|
|
|
|
|
|
|
|
En fait, notre désir secret est la découverte des choses cachées du
|
|
|
|
monde qui nous entoure. Nous voulons des images du \textbf{réel} et
|
|
|
|
pour cela, l'outil le plus commun, le plus répandu,
|
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
|
|
|
|
|
|
|
% -------------------------------------------------------------------
|
|
|
|
\section{Et pour la suite ?}
|
|
|
|
|
2019-08-24 22:24:01 +11:00
|
|
|
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
|
2019-08-07 06:22:12 +11:00
|
|
|
|
2019-05-20 17:47:13 +11:00
|
|
|
% -------------------------------------------------------------------
|
|
|
|
|
|
|
|
\printindex
|
|
|
|
|
|
|
|
\end{document}
|