Compare commits

..

7 Commits

Author SHA1 Message Date
tth
711e54fe43 histocomputing boilerplate [done] 2020-09-03 02:00:32 +02:00
tth
951dc4450f working on histogram computation 2020-09-03 01:37:53 +02:00
tth
4b2d2c264f need proff reading 2020-09-03 01:35:54 +02:00
tth
a5cd02a261 ignore .tiff in v4l2/ 2020-09-02 12:45:41 +02:00
tth
fe22b0561e enhanced verbosity message 2020-08-31 17:51:12 +02:00
tth
3279d0dde8 oups... 2020-08-24 11:40:49 +02:00
tth
30347903ca half-fixed a memory leak 2020-08-23 23:55:36 +02:00
8 changed files with 177 additions and 26 deletions

1
.gitignore vendored
View File

@ -42,6 +42,7 @@ v4l2/*.o
v4l2/*.ppm
v4l2/*.png
v4l2/*.fits
v4l2/*.tiff
v4l2/video-infos
v4l2/nc-camcontrol

View File

@ -26,7 +26,7 @@
\usepackage{xspace}
\usepackage[verbose]{layout}
\setlength \parskip {0.333em}
\setlength \parskip {0.35em}
\makeatletter
% exlpication de ce truc ?
@ -204,19 +204,22 @@ lesquels sont décrits en page \pageref{outils}.
% -------------------------------------------------------------------
\section{Installation}
Sauf indications contraires, ces instructions se réfèrent à
une distribution Debian\index{Debian} récente.
\textit{Attention, ça devient un peu gore. Myrys, punk, toussa\dots}
\subsection{Prérequis}
Vous devez, en dehors des outils classiques (bash, gcc, make\dots),
avoir quelques bibliothèques installées\footnote{Les \texttt{-dev}
pour Debian et dérivées}~:
en plus pour Debian et dérivées}~:
\textsf{
libv4l2, libpnglite, libtiff,
libnetpbm\footnote{package libnetpbm10-dev},
libz\footnote{package zlib1g-dev}, libcurses,
libcfitsio-dev
} % en of textsf
} % end of textsf
éventuellement avec le \textsf{-dev} correspondant,
et probablement d'autres choses.
@ -293,7 +296,8 @@ typedef struct {
\end{lstlisting}\index{FloatImg}
Les deux premiers champs sont \textsl{obvious}.
Le troisième est le type d'image : pour le moment, il y en a trois
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\index{rgba}.
Les constantes adéquates sont dans \texttt{floatimg.h}
@ -317,7 +321,8 @@ 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}
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
@ -436,15 +441,17 @@ 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é.
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} \dots
% ----------------------------------
\subsection{Contraste}\index{contraste}\label{contraste}
Certaines opérations d'ajustement du contraste d'une image
semblent cohérents avec la notion d'image flottante.
Certains d'entre eux, les plus simples, sont disponibles.
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]
@ -453,8 +460,9 @@ Les autres sont à imaginer.
\end{figure}
Ils prennent chacun trois paramètres, d'abord les images
source et destination (\texttt{* FloatImg}), et le troisième
est un nombre en double précision donnant la valeur
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.
@ -469,6 +477,7 @@ int fimg_cos_010(FloatImg *s, FloatImg *d, double maxval);
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.
\begin{figure}[h]
@ -606,7 +615,8 @@ Les autres bits ne sont pas utilisés et doivent être à zéro.
\subsubsection{Vers PNG}\index{PNG}
Actuellement, on peut enregistrer uniquement en mode RGB, 8 bits par composante,
Actuellement, on peut enregistrer uniquement en mode RGB,
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.
@ -618,13 +628,18 @@ int fimg_save_as_png(FloatImg *src, char *outname, int flags);
Tous les flags doivent être à zéro. Sinon, ça foire parfois.
\subsubsection{Vers/depuis TIFF}\index{TIFF}
\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.
To be done\index{XXX}
\begin{lstlisting}
int fimg_write_as_png(FloatImg *src, char *outname, int flags);
\end{lstlisting}
Tous les flags doivent être à zéro.
\subsubsection{Vers FITS}\index{FITS}
@ -769,10 +784,10 @@ return 0;
\end{lstlisting}
Je vous laisse imaginer les dégats que peut faire cette
fontion en utilisation réelle. Mieux, je vous propose
fonction en utilisation réelle. Mieux, je vous propose
d'essayer par vous-même.
En particulier tout le reste du code qui suppose qu'un pixel
ne peut \textbf{pas} être négatif.
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..
@ -1129,7 +1144,7 @@ done
\end{verbatim}
Et en fin de boucle, nous convertissons le résultat de nos
savants au format PNG, et écrivons le fichier dans le répertoire
savants calculs au format PNG, et écrivons le fichier dans le répertoire
de destination fixé au début.
C'est le moment de passer la main à ffmpeg\index{ffmpeg}.
@ -1180,8 +1195,10 @@ 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, actuellement
seulement \texttt{.fimg}, \texttt{.pnm} et \texttt{.png}
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
@ -1256,9 +1273,25 @@ de \textsl{Brunus} pour avancer...
\subsection{Gimp}\index{Gimp}
Mmmmm... Ça semble un peu plus compliqué. D'un autre coté, il
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 être négatif.
\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}
\subsection{Et encore ?}\index{krita}\index{geeqie}
Il y a d'autres logiciels pour lesquels écrire une fonction d'importation

View File

@ -4,7 +4,7 @@ COPT = -Wall -fpic -g -no-pie -DDEBUG_LEVEL=0
DEPS = ../floatimg.h Makefile
OBJS = fimg-png.o fimg-tiff.o misc-plots.o filtrage.o utils.o \
fimg-libpnm.o rampes.o sfx0.o geometry.o rotate.o \
equalize.o fimg-fits.o saturation.o
equalize.o fimg-fits.o saturation.o histogram.o
#---------------------------------------------------------------
@ -45,6 +45,9 @@ rotate.o: rotate.c $(DEPS)
saturation.o: saturation.c $(DEPS)
gcc $(COPT) -c $<
histogram.o: histogram.c $(DEPS)
gcc $(COPT) -c $<
equalize.o: equalize.c $(DEPS)
gcc $(COPT) -c $<

76
funcs/histogram.c Normal file
View File

@ -0,0 +1,76 @@
/*
* FLOATIMG
* calculer un histogramme et l'afficher
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "../floatimg.h"
extern int verbosity;
/* --------------------------------------------------------------------- */
int fimg_calcul_histo(FloatImg *src, long *ghist, int sz)
{
float maxval;
int x, y, idx;
float rgb[3], moy;
fprintf(stderr, ">>> %s ( %p %p %d )\n", __func__, src, ghist, sz);
maxval = fimg_get_maxvalue(src);
fprintf(stderr, "maximum is %f\n", maxval);
for (y=0; y<src->height; y++) {
for(x=0; x<src->width; x++) {
fimg_get_rgb(src, x, y, rgb);
moy = (rgb[0]+rgb[1]+rgb[2]) / 3.0;
/* ok, here the had math part ... */
idx = (int)( (moy*sz) / maxval);
/* sanity check */
if (idx<0 || idx>=sz) {
fprintf(stderr, "idx = %d, error\n", idx);
abort();
}
ghist[idx]++;
}
}
return -66;
}
/* --------------------------------------------------------------------- */
#define NSLICES 999
int fimg_essai_histo(FloatImg *src, char *outpic, int k)
{
long histo[NSLICES];
int foo;
FILE *pipe;
fprintf(stderr, ">>> %s ( %p '%s' %d )\n", __func__, src, outpic, k);
memset(histo, 0, NSLICES*sizeof(long));
foo = fimg_calcul_histo(src, histo, NSLICES);
for (foo=0; foo<NSLICES; foo++) {
printf("%7d %ld\n", foo, histo[foo]);
}
pipe = popen("gnuplot", "w");
fprintf(pipe, "set term png size 1000,400\n");
fprintf(pipe, "set output \"histo.png\"\n");
fprintf(pipe, "plot 'toto' with lines\n");
fclose(pipe);
return -1;
}
/* --------------------------------------------------------------------- */

View File

@ -401,7 +401,36 @@ fprintf(stderr, "save as png -> %d\n", foo);
return 0;
}
/* --------------------------------------------------------------------- */
enum nCmd { Equalize=1, Rotate, Sfx0, F3x3, MIRE, Wfits, Wpng, Wtiff };
/* func in histogram.c */
int fimg_essai_histo(FloatImg *src, char *outpic, int k);
int essai_histogramme(char *fname, int k)
{
FloatImg fimg;
int foo;
fprintf(stderr, ">>> %s ( '%s' %d )\n", __func__, fname, k);
foo = fimg_create_from_dump(fname, &fimg);
if (foo) {
fprintf(stderr, "%s: err load '%s'\n", __func__, fname);
return foo;
}
foo = fimg_essai_histo(&fimg, "out.png", k);
if (foo) {
fprintf(stderr, "essai_histo -> %d\n", foo);
return foo;
}
fprintf(stderr, "\\o/ end of %s\n", __func__);
return -1;
}
/* --------------------------------------------------------------------- */
enum nCmd { Equalize=1, Rotate, Sfx0, F3x3, MIRE, Wfits, Wpng, Wtiff,
Histo };
typedef struct {
char *name;
int Cmd;
@ -416,6 +445,7 @@ Command commands[] = {
{ "wfits", Wfits },
{ "wpng", Wpng },
{ "wtiff", Wtiff },
{ "histo", Histo },
{ NULL, 0 }
} ;
@ -455,7 +485,7 @@ int main(int argc, char *argv[])
int foo, opt;
char *filename, *command;
puts("++++++++ test des fonctions +++++++");
fprintf(stderr, "++++++++ test des fonctions pid=%d\n", getpid());
global_fvalue = 1.0;
@ -506,6 +536,9 @@ switch(opt) {
case Wtiff:
foo = essai_ecriture_tiff(filename);
break;
case Histo:
foo = essai_histogramme(filename, 0);
break;
default:
fprintf(stderr, "%s : bad command\n", command);
exit(1);

View File

@ -141,6 +141,8 @@ if (foo) {
exit(1);
}
fimg_destroy(&fimg);
return 0;
}
/* --------------------------------------------------------------------- */

View File

@ -240,7 +240,7 @@ else {
}
fimg_clear(&cumul);
cumul.fval = 255.0;
cumul.fval = 255.0; /* must be read from camera XXX */
cumul.count = 0;
to_save = &cumul;
@ -347,6 +347,8 @@ if (verbosity) fprintf(stderr, "saving cumul to '%s'\n", outfile);
maxvalue = cumul.fval * cumul.count;
if (verbosity) {
fprintf(stderr, "theorical maxvalue = %g\n", maxvalue);
fprintf(stderr, "computed max value = %g\n",
fimg_get_maxvalue(&cumul));
}
switch (contrast) {
case CONTRAST_NONE:
@ -398,6 +400,7 @@ switch (foo) {
break;
case FILE_TYPE_TIFF:
foo = fimg_write_as_tiff(to_save, outfile, 0);
break;
default:
fprintf(stderr, "can't save as %s\n", outfile);
break;