2023-04-29 19:29:45 +02:00
|
|
|
/*
|
2023-07-01 00:48:50 +02:00
|
|
|
* Modeles Numeriques de Terrain -- UGLY CODE INSIDE !!
|
2023-04-29 19:29:45 +02:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <math.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdint.h>
|
2023-07-01 00:48:50 +02:00
|
|
|
#include <string.h>
|
2023-04-29 19:29:45 +02:00
|
|
|
|
|
|
|
#include "../floatimg.h"
|
|
|
|
|
|
|
|
int verbosity;
|
|
|
|
|
2023-07-07 10:08:57 +02:00
|
|
|
/* ------------------------------------------------------------------- */
|
|
|
|
/* for debug purpose */
|
|
|
|
int printf_histo_gray(char *fname, int histo[], int nbre)
|
|
|
|
{
|
|
|
|
FILE *fp;
|
|
|
|
int idx;
|
|
|
|
|
|
|
|
#if DEBUG_LEVEL
|
|
|
|
fprintf(stderr, ">>> %s ( '%s' %p %d )\n", __func__,
|
|
|
|
fname, histo, nbre);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (NULL == (fp = fopen(fname, "w"))) {
|
|
|
|
perror(fname);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
for (idx=0; idx<nbre; idx++) {
|
|
|
|
fprintf(fp, "%6d %8d\n", idx, histo[idx]);
|
|
|
|
}
|
|
|
|
fclose(fp);
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
2023-07-01 00:48:50 +02:00
|
|
|
/* ------------------------------------------------------------------- */
|
|
|
|
/* for debug purpose */
|
|
|
|
int calcul_histo_gray(FloatImg *img, char *fname, int nbslots, float *pmax)
|
|
|
|
{
|
|
|
|
int offset, nbpix, ival;
|
|
|
|
float pixel, minp, maxp;
|
|
|
|
int *counts;
|
|
|
|
|
|
|
|
#if DEBUG_LEVEL
|
|
|
|
fprintf(stderr, ">>> %s ( %p '%s' %d )\n", __func__,
|
|
|
|
img, fname, nbslots);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (FIMG_TYPE_GRAY != img->type) {
|
2023-07-05 16:47:43 +02:00
|
|
|
fprintf(stderr, "%s: image is not in greylevel\n", __func__);
|
2023-07-01 00:48:50 +02:00
|
|
|
return -2;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* allocate memory for histogram computation */
|
|
|
|
counts = calloc(nbslots, sizeof(int));
|
|
|
|
if (NULL == counts) {
|
|
|
|
fprintf(stderr, "malloc fail in %s\n", __func__);
|
|
|
|
abort();
|
|
|
|
}
|
|
|
|
|
|
|
|
nbpix = img->width * img->height;
|
2024-04-01 00:07:34 +02:00
|
|
|
minp = 1e30, maxp = -1e30;
|
2023-07-01 00:48:50 +02:00
|
|
|
|
|
|
|
for (offset=0; offset<nbpix; offset++) {
|
|
|
|
pixel = img->R[offset];
|
|
|
|
if (pixel < minp) minp = pixel;
|
|
|
|
if (pixel > maxp) maxp = pixel;
|
|
|
|
}
|
2024-04-01 00:07:34 +02:00
|
|
|
// fprintf(stderr, " values = %g < %g\n", minp, maxp);
|
2023-07-01 00:48:50 +02:00
|
|
|
|
|
|
|
*pmax = maxp; /* copy value for the caller */
|
|
|
|
|
|
|
|
/* calcul de l'histogramme avec scaling */
|
|
|
|
for (offset=0; offset<nbpix; offset++) {
|
|
|
|
pixel = img->R[offset];
|
|
|
|
ival = (int)((pixel * (float)nbslots) / maxp);
|
|
|
|
counts[ival]++;
|
|
|
|
// fprintf(stderr, "%6d %10.6f %i\n", offset, pixel, ival);
|
|
|
|
}
|
|
|
|
|
2023-07-07 10:08:57 +02:00
|
|
|
if (NULL != fname)
|
|
|
|
{
|
|
|
|
printf_histo_gray(fname, counts, nbslots);
|
2023-07-01 00:48:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* garbage collect stuff */
|
|
|
|
free(counts);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2023-04-29 19:29:45 +02:00
|
|
|
/* ------------------------------------------------------------------- */
|
|
|
|
/*
|
2023-07-01 00:48:50 +02:00
|
|
|
* Second try - ahem?
|
2023-04-29 19:29:45 +02:00
|
|
|
*/
|
|
|
|
int brotche_mnt_style(FloatImg *src, FloatImg *dst)
|
|
|
|
{
|
2023-07-01 00:48:50 +02:00
|
|
|
FloatImg tmp;
|
|
|
|
int x, y, foo;
|
2023-04-29 19:29:45 +02:00
|
|
|
int offset;
|
|
|
|
float z1, z2, z3, z4;
|
|
|
|
float a, b, c;
|
2023-07-01 00:48:50 +02:00
|
|
|
float pente, minp, maxp, seuil;
|
2023-04-29 19:29:45 +02:00
|
|
|
|
2023-07-01 00:48:50 +02:00
|
|
|
#if DEBUG_LEVEL
|
2023-04-29 19:29:45 +02:00
|
|
|
fprintf(stderr, ">>> %s ( %p %p )\n", __func__, src, dst);
|
2023-07-01 00:48:50 +02:00
|
|
|
#endif
|
2023-04-29 19:29:45 +02:00
|
|
|
|
2023-07-05 16:47:43 +02:00
|
|
|
/*
|
|
|
|
* trying some preprocessor filters
|
|
|
|
*/
|
|
|
|
foo = fimg_lissage_3x3(src);
|
2024-04-01 00:07:34 +02:00
|
|
|
if (foo) fprintf(stderr, " lissage 1 -> %d\n", foo);
|
|
|
|
foo = fimg_lissage_3x3(src);
|
|
|
|
if (foo) fprintf(stderr, " lissage 2 -> %d\n", foo);
|
|
|
|
|
2023-07-05 16:47:43 +02:00
|
|
|
foo = fimg_killborders(src);
|
|
|
|
if (foo) fprintf(stderr, " killborder -> %d\n", foo);
|
|
|
|
|
2023-04-29 19:29:45 +02:00
|
|
|
#define W (src->width)
|
|
|
|
#define DX 1.0
|
|
|
|
#define DY 1.0
|
|
|
|
|
2023-07-01 00:48:50 +02:00
|
|
|
/* allocate a graylevel image for storing la 'pente' */
|
|
|
|
memset(&tmp, 0, sizeof(FloatImg));
|
|
|
|
foo = fimg_create(&tmp, src->width, src->height, FIMG_TYPE_GRAY);
|
|
|
|
if (foo) {
|
|
|
|
fprintf(stderr, "create tmp pic --> %d\n", foo);
|
|
|
|
return foo;
|
|
|
|
}
|
2024-04-01 00:07:34 +02:00
|
|
|
|
2023-07-01 00:48:50 +02:00
|
|
|
/* calcul de la pente : a vérifier ! */
|
2023-04-29 19:29:45 +02:00
|
|
|
for (y=0; y<(src->height-1); y++) {
|
|
|
|
for (x=0; x<(src->width-1); x++) {
|
2023-07-01 00:48:50 +02:00
|
|
|
offset = (y * W) + x;
|
2023-04-29 19:29:45 +02:00
|
|
|
z1 = src->R[offset];
|
|
|
|
z2 = src->R[offset+1];
|
|
|
|
z3 = src->R[offset+W];
|
|
|
|
z4 = src->R[offset+W+1];
|
|
|
|
a = ( z1 + z2 + z3 + z4) / 4.0;
|
|
|
|
b = (-z1 + z2 - z3 + z4) / 2.0 / DX;
|
|
|
|
c = (-z1 - z2 + z3 + z4) / 2.0 / DY;
|
|
|
|
pente = atanf(sqrt(b*b + c*c));
|
2023-07-01 00:48:50 +02:00
|
|
|
tmp.R[offset] = pente;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
foo = calcul_histo_gray(&tmp, "histogramme.data", 499, &maxp);
|
|
|
|
if (foo) fprintf(stderr, "<<< calcul histo -> %d\n", foo);
|
2023-04-29 19:29:45 +02:00
|
|
|
|
2023-07-01 00:48:50 +02:00
|
|
|
minp = 1e10;
|
2023-07-05 16:47:43 +02:00
|
|
|
seuil = 0.700 * maxp;
|
|
|
|
fprintf(stderr, " seuil = %f\n", seuil);
|
2023-04-29 19:29:45 +02:00
|
|
|
|
2024-04-01 00:07:34 +02:00
|
|
|
/* ésotérisme, quand tu nous tiens... */
|
2023-07-01 00:48:50 +02:00
|
|
|
for (offset=0; offset<(src->width*src->height); offset++) {
|
|
|
|
pente = tmp.R[offset];
|
|
|
|
if (pente > seuil) {
|
|
|
|
if (pente < minp) minp = pente;
|
2023-04-29 19:29:45 +02:00
|
|
|
}
|
2023-07-01 00:48:50 +02:00
|
|
|
if (pente > maxp) maxp = pente;
|
2023-04-29 19:29:45 +02:00
|
|
|
}
|
2023-07-05 16:47:43 +02:00
|
|
|
// fprintf(stderr, " minp = %f maxp = %f\n", minp, maxp);
|
2023-07-01 00:48:50 +02:00
|
|
|
|
|
|
|
/* recopie dans l'image destination avec translation hauteur */
|
2024-04-01 00:07:34 +02:00
|
|
|
fimg_clear(dst);
|
2023-07-01 00:48:50 +02:00
|
|
|
for (offset=0; offset<(src->width*src->height); offset++) {
|
|
|
|
pente = tmp.R[offset] - minp;
|
2024-04-01 00:07:34 +02:00
|
|
|
if (pente < 0.0) {
|
|
|
|
dst->R[offset] = -pente;
|
|
|
|
dst->G[offset] = -pente;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
dst->B[offset] = pente;
|
|
|
|
dst->G[offset] = pente;
|
|
|
|
}
|
2023-07-01 00:48:50 +02:00
|
|
|
}
|
|
|
|
|
2023-07-05 16:47:43 +02:00
|
|
|
foo = fimg_killborders(dst);
|
|
|
|
if (foo) fprintf(stderr, " killborder -> %d\n", foo);
|
|
|
|
|
2023-07-01 00:48:50 +02:00
|
|
|
/* clean the memory */
|
|
|
|
fimg_destroy(&tmp);
|
2023-04-29 19:29:45 +02:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
/* ------------------------------------------------------------------- */
|
|
|
|
int main(int argc, char *argv[])
|
|
|
|
{
|
|
|
|
FloatImg src, dst;
|
|
|
|
char *infile, *outfile;
|
|
|
|
int foo;
|
|
|
|
|
2023-07-01 00:48:50 +02:00
|
|
|
verbosity = 1; /* FIXME */
|
|
|
|
|
2023-04-29 19:29:45 +02:00
|
|
|
if (3 != argc) {
|
2023-07-01 00:48:50 +02:00
|
|
|
fprintf(stderr, "'%s' need 2 args : infile & outfile\n", argv[0]);
|
2023-04-29 19:29:45 +02:00
|
|
|
fimg_print_version(0);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
infile = argv[1]; outfile = argv[2];
|
|
|
|
|
2023-07-01 00:48:50 +02:00
|
|
|
if (verbosity) fprintf(stderr,"*** MNT %s -> %s\n", infile, outfile);
|
2023-04-29 19:29:45 +02:00
|
|
|
|
|
|
|
foo = fimg_create_from_dump(infile, &src);
|
|
|
|
if (foo) {
|
|
|
|
fprintf(stderr, "err %d loading image '%s'\n", foo, infile);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
foo = fimg_clone(&src, &dst, 0);
|
|
|
|
if (foo) {
|
|
|
|
fprintf(stderr, "err %d cloning image\n", foo);
|
|
|
|
exit(1);
|
|
|
|
}
|
2023-07-01 00:48:50 +02:00
|
|
|
fimg_clear(&dst);
|
2023-04-29 19:29:45 +02:00
|
|
|
|
|
|
|
foo = brotche_mnt_style(&src, &dst);
|
|
|
|
if (foo) {
|
|
|
|
fprintf(stderr, "something weird happen %d\n", foo);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
foo = fimg_export_picture(&dst, outfile, 0);
|
|
|
|
if (foo) {
|
|
|
|
fprintf(stderr, "err %d exporting to %s\n", foo, outfile);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2023-07-01 00:48:50 +02:00
|
|
|
/* clean the memory */
|
|
|
|
fimg_destroy(&src);
|
|
|
|
fimg_destroy(&dst);
|
|
|
|
|
2023-04-29 19:29:45 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
/* ------------------------------------------------------------------- */
|