FloatImg/lib/fimg-math.c

292 lines
6.5 KiB
C
Raw Normal View History

2019-03-04 02:22:55 +11:00
/*
* fimg-core.c
*
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
2019-08-08 02:30:16 +11:00
#include <string.h>
2020-03-02 11:19:57 +11:00
#include <float.h> /* for FLT_MAX */
2019-08-08 02:30:16 +11:00
#include <math.h>
2019-03-04 02:22:55 +11:00
#include "../floatimg.h"
extern int verbosity; /* must be declared around main() */
/* ---------------------------------------------------------------- */
float fimg_get_maxvalue(FloatImg *head)
{
float maxval;
int foo;
2019-08-26 11:35:17 +11:00
if (head->type != FIMG_TYPE_RGB && head->type != FIMG_TYPE_GRAY) {
2019-08-08 02:30:16 +11:00
fprintf(stderr, "%s : type %d invalide\n",
__func__, head->type);
return nanf("wtf ?");
}
2019-03-04 02:22:55 +11:00
maxval = 0.0; /* no negative values allowed */
2019-08-26 11:35:17 +11:00
switch (head->type) {
case FIMG_TYPE_RGB:
for (foo=0; foo<(head->width*head->height); foo++) {
if (head->R[foo] > maxval) maxval = head->R[foo];
if (head->G[foo] > maxval) maxval = head->G[foo];
if (head->B[foo] > maxval) maxval = head->B[foo];
}
case FIMG_TYPE_GRAY:
for (foo=0; foo<(head->width*head->height); foo++) {
if (head->R[foo] > maxval) maxval = head->R[foo];
}
2019-03-04 02:22:55 +11:00
}
return maxval;
}
/* ---------------------------------------------------------------- */
2020-03-02 11:19:57 +11:00
/*
* mmval[0] <- min(R) mmval[1] <- max(R)
*/
int fimg_get_minmax_rgb(FloatImg *head, float mmvals[6])
{
int idx, surface;
float fval;
if (head->type != FIMG_TYPE_RGB) {
fprintf(stderr, "%s : type %d invalide\n",
__func__, head->type);
return -2;
}
surface = head->width * head->height;
mmvals[0] = FLT_MAX; mmvals[1] = -FLT_MAX;
mmvals[2] = FLT_MAX; mmvals[3] = -FLT_MAX;
mmvals[4] = FLT_MAX; mmvals[5] = -FLT_MAX;
for (idx=0; idx<surface; idx++) {
fval = head->R[idx];
if (fval < mmvals[0]) mmvals[0] = fval;
else if (fval > mmvals[1]) mmvals[1] = fval;
fval = head->G[idx];
if (fval < mmvals[2]) mmvals[2] = fval;
else if (fval > mmvals[3]) mmvals[3] = fval;
fval = head->B[idx];
if (fval < mmvals[4]) mmvals[4] = fval;
else if (fval > mmvals[5]) mmvals[5] = fval;
}
#if 0
for (foo=0; foo<6; foo++) {
fprintf(stderr, "%3d %g\n", foo, mmvals[foo]);
}
#endif
return -0;
}
/* ---------------------------------------------------------------- */
2019-03-04 02:22:55 +11:00
int fimg_meanvalues(FloatImg *head, float means[4])
{
int idx, surface;
2019-09-29 08:45:51 +11:00
double accus[4];
2019-03-04 02:22:55 +11:00
surface = head->width * head->height;
if (surface < 1) return -1;
2019-09-29 08:45:51 +11:00
memset(accus, 0, 4*sizeof(double));
2019-03-04 02:22:55 +11:00
for (idx=0; idx<surface; idx++) {
2019-09-29 08:45:51 +11:00
accus[0] += head->R[idx];
2019-03-04 02:22:55 +11:00
if (head->type > 2) {
2019-09-29 08:45:51 +11:00
accus[1] += head->G[idx];
accus[2] += head->B[idx];
2019-03-04 02:22:55 +11:00
}
}
2019-09-29 08:45:51 +11:00
for (idx=0; idx<4; idx++) {
means[idx] = (float)(accus[idx]/(double)surface);
}
2019-03-04 02:22:55 +11:00
return 0;
}
2019-09-29 22:45:33 +11:00
/* ---------------------------------------------------------------- */
2019-10-19 16:03:47 +11:00
/* d'après Wikipedia Fr :
| c = 0
| s = x1
| pour j de 2 à n
| s = s+xj
| c = c+(j xj s)2/(j(j1))
| renvoyer c/n
Mais c,a ne semble pas etre la bonne methode. Il faut aller voir :
https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance
2019-09-29 22:45:33 +11:00
*/
2019-03-04 02:22:55 +11:00
/* ---------------------------------------------------------------- */
2019-08-27 18:19:25 +11:00
/*
* more elaborate functions are in fimg-2gray.c
*/
2019-03-04 02:22:55 +11:00
int fimg_to_gray(FloatImg *head)
{
float add;
int foo;
2019-08-08 02:30:16 +11:00
if (head->type != FIMG_TYPE_RGB) {
fprintf(stderr, "%s : type %d invalide\n",
__func__, head->type);
return -3;
}
2019-03-04 02:22:55 +11:00
for (foo=0; foo<(head->width*head->height); foo++) {
add = head->R[foo];
add += head->G[foo];
add += head->B[foo];
2019-09-17 22:14:33 +11:00
head->R[foo] = head->G[foo] = head->B[foo] = add / 3.0;
2019-03-04 02:22:55 +11:00
}
return -1;
}
/* ---------------------------------------------------------------- */
void fimg_add_cste(FloatImg *fi, float value)
{
int nbre, idx;
2019-08-08 02:30:16 +11:00
if (fi->type != FIMG_TYPE_RGB) {
fprintf(stderr, "%s : type %d invalide\n",
__func__, fi->type);
return;
}
2019-03-04 02:22:55 +11:00
nbre = fi->width * fi->height * fi->type;
#if DEBUG_LEVEL
fprintf(stderr, "%s, nbre is %d\n", __func__, nbre);
#endif
2019-09-10 10:31:48 +11:00
for (idx=0; idx<nbre; idx++) {
2019-03-04 02:22:55 +11:00
fi->R[idx] += value;
}
}
/* ---------------------------------------------------------------- */
2019-09-25 18:21:00 +11:00
int fimg_count_negativ(FloatImg *fi)
{
int nbre, idx;
int count;
if (fi->type != FIMG_TYPE_RGB) {
fprintf(stderr, "%s : type %d invalide\n",
__func__, fi->type);
return -1;
}
nbre = fi->width * fi->height * fi->type;
count = 0;
for (idx=0; idx<nbre; idx++) {
if (fi->R[idx] < 0.0) count++;
}
2020-03-01 06:01:11 +11:00
return count;
}
/* ---------------------------------------------------------------- */
/* nouveau 29 fevrier 2020 */
int fimg_clamp_negativ(FloatImg *fi)
{
int nbre, idx;
int count;
if (fi->type != FIMG_TYPE_RGB) {
fprintf(stderr, "%s : type %d invalide\n",
__func__, fi->type);
return -1;
}
nbre = fi->width * fi->height * fi->type;
count = 0;
for (idx=0; idx<nbre; idx++) {
if (fi->R[idx] < 0.0) {
fi->R[idx] = 0.0;
count++;
}
}
2019-09-25 18:21:00 +11:00
return count;
}
/* ---------------------------------------------------------------- */
2019-09-10 10:31:48 +11:00
void fimg_mul_cste(FloatImg *fi, float value)
{
int nbre, idx;
2020-01-10 22:01:12 +11:00
if ( (fi->type != FIMG_TYPE_RGB) && (fi->type != FIMG_TYPE_GRAY) ) {
2019-09-10 10:31:48 +11:00
fprintf(stderr, "%s : type %d invalide\n",
__func__, fi->type);
return;
}
nbre = fi->width * fi->height * fi->type;
#if DEBUG_LEVEL
fprintf(stderr, "%s, nbre of datum is %d\n", __func__, nbre);
#endif
2019-09-10 10:31:48 +11:00
for (idx=0; idx<nbre; idx++) {
fi->R[idx] *= value;
}
}
/* ---------------------------------------------------------------- */
int fimg_normalize(FloatImg *fi, double maxima, int notused)
{
double coef;
if (fi->type != FIMG_TYPE_RGB) {
fprintf(stderr, "%s : type %d invalide\n",
__func__, fi->type);
return -99;
}
if (fi->count < 1) {
fprintf(stderr, "%s : count %d is invalid\n", __func__, fi->count);
return -98;
}
2020-01-09 19:28:23 +11:00
/*
* mmmm, is this real ?
2020-01-10 22:01:12 +11:00
* how to accuratly check the value of 'I.fval' ?
2020-01-09 19:28:23 +11:00
*/
coef = 1.0 / ((double)fi->count * (double)fi->fval);
if (verbosity) {
fprintf(stderr, "image @ %p\n", fi);
fprintf(stderr, "fval %f\n", fi->fval);
fprintf(stderr, "count %d\n", fi->count);
fprintf(stderr, "coef %f\n", coef);
}
fimg_mul_cste(fi, coef);
return 0;
}
/* ---------------------------------------------------------------- */
2019-03-04 02:22:55 +11:00
/* Warning: this function is _very_ slow */
void fimg_drand48(FloatImg *fi, float kmul)
{
int nbre, idx;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %g )\n", __func__, fi, kmul);
#endif
2019-09-02 19:07:56 +11:00
if (fi->type != FIMG_TYPE_RGB) {
fprintf(stderr, "%s : type %d invalide\n",
__func__, fi->type);
return;
}
nbre = fi->width * fi->height;
2019-03-04 02:22:55 +11:00
for (idx=0; idx<nbre; idx++) {
fi->R[idx] = drand48() * kmul;
2019-09-02 19:07:56 +11:00
fi->G[idx] = drand48() * kmul;
fi->B[idx] = drand48() * kmul;
2019-03-04 02:22:55 +11:00
}
}
/* ---------------------------------------------------------------- */