Aide algorithme NLMEANS

Langage C

L'auteur de ce sujet a trouvé une solution à son problème.
Auteur du sujet

Bonjour,

J’ai actuellement un projet de développement informatique où je dois faire fonctionner un algorithme et l’optimiser. Mais voilà, j’ai un problème : Je n’arrive pas à faire fonctionner l’algorithme. Je ne demande pas qu’on me fasse le projet mais seulement qu’on m’aiguille afin que je puisse comprendre. Voici le code :

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <math.h>

void* nlmeans(float* img, float* out, float h, int h_img, int w_img, int c_nbr);

int main()
{
    FILE* img = fopen("img.bmp", "rb+");
    FILE* cpyimg = fopen("cpyimg.bmp", "wb+");
    if(img == NULL || cpyimg == NULL)
        return -1;

    unsigned char infoFichier[54], temp;
    fread(infoFichier, sizeof(char), 54, img);

    int hauteur = *(int*)&infoFichier[18];
    int largeur = *(int*)&infoFichier[22];
    int poids = *(int*)&infoFichier[34];

    printf("Largeur : %d\n", largeur);
    printf("Hauteur : %d\n", hauteur);
    printf("Poids : %d\n", poids);

    float* dataMeans = malloc(sizeof(float)*poids);
    float* data = malloc(sizeof(float) * poids);
    fread(data, sizeof(float), poids, img);

    nlmeans(data, dataMeans, 10, hauteur, largeur, 10);

    fwrite(infoFichier, 1, 54, cpyimg);
    fwrite(dataMeans, 1, poids, cpyimg);

    return 0;
}

void *
nlmeans(float* img, float* out, float h, int h_img, int w_img, int c_nbr)
{
    //Parameters from Buades et al.
    int p_w = 3; //7x7 patches
    int omega_w = 10; //21x21 neighborhood search
    //nlmeans
    for(int y=0; y<h_img; y++)
    {
        for(int x=0; x<w_img; x++)
        {
            float sum2 = 0;
            //search window
            for(int i=-omega_w; i<=omega_w; i++)
            {
                for(int j=-omega_w; j<=omega_w; j++)
                {
                    int xx = x+j;
                    int yy = y+i;
                    if(xx<0 || yy <0 || xx>=w_img || yy>=h_img) continue;
                    int nb = 0;
                    float sum = 0;
                    //Distance between patches
                    for(int dx=-p_w; dx<=p_w; dx++)
                    {
                        for(int dy=-p_w; dy<=p_w; dy++)
                        {
                            int px = x+dx;
                            int py = y+dy;
                            int qx = xx+dx;
                            int qy = yy+dy;
                            if(px<0 || qx <0 || px>=w_img || qx>=w_img) continue;
                            if(py<0 || qy <0 || py>=h_img || qy>=h_img) continue;
                            float dist = 0;
                            for(int pd=0; pd<c_nbr; pd++)
                            {
                                float vp = img[py+px*h_img + pd*h_img*w_img];
                                float vq = img[qy+qx*h_img + pd*h_img*w_img];
                                dist += (vp-vq)*(vp-vq);
                            }
                            nb++;
                            sum += dist;
                        }
                    }
                    //Patch weighting
                    float dd = sum/nb;
                    float ww = exp(-(dd)/(h));
                    for(int pd=0; pd<dd; pd++) // d => h ou dd ?
                    {
                        out[y+x*h_img + pd*h_img*w_img] += ww*img[yy+xx*h_img + pd*h_img*w_img];
                    }
                    sum2 += ww;
                }
            }
            //Normalisation
            for(int pd=0; pd<c_nbr; pd++)
            {
                out[y+x*h_img + pd*h_img*w_img] /= sum2;
            }
        }
    }
    return 0;
}

`

Après un coup de debugger, je trouve que y+x*h_img + pd*h_img*w_img (ligne 89) est trop grand par rapport à la taille du tableau.

Je vous remercie d’avance pour votre aide.

Édité par qarcicault

+0 -0

Salut,

Je n’ai pas la réponse à ta question, mais je peux te dire ceci : les boucles, c’est comme les intéractions entre les médicaments, quand il y en a trois ou plus, on ne sait plus vraiment ce qui se passe. :p

Édité par Taurre

#JeSuisArius

+2 -0

Je suis du même avis que Taurre, sortir intelligemment le contenu de tes boucles dans des fonctions peut nettement améliorer la clarté du code.

De plus, je ne sais pas pour les autres mais personnellement je n’ai aucune idée de ce qu’est l’algo nlmeans. Expliquer rapidement ce qu’il fait et la fonction de poids choisi devrait permettre aux gens de mieux t’aider en plus de s’assurer que tu comprends bien toi-même l’algorithme.

+0 -0
Auteur du sujet

Il s’agit d’un algorithme permettant un débruitage de l’image (par patch). Voici un lien vers la description de l’algorithme : https://fr.wikipedia.org/wiki/Débruitage_par_patchs

Étant donné que je ne reconnais pas le résultat final, j’aimerais évité de modifier l’algorithme.

Pensez-vous que la méthode que j’utilise afin de récupérer les données de l’image est bonne ?

1
2
3
float* dataMeans = malloc(sizeof(float)*poids);
float* data = malloc(sizeof(float) * poids);
fread(data, sizeof(float), poids, img);
+0 -0

Pensez-vous que la méthode que j’utilise afin de récupérer les données de l’image est bonne ?

qarcicault

Du point de vue de la portabilité, si ce fichier n’est pas amené à être utilisé sur d’autres machines que celle qui l’a construit, oui. Dans le cas contraire, il est préférable de ne pas stocker des nombres flottants sous une autre forme que du texte (ou une composition d’entiers).

#JeSuisArius

+0 -0
Vous devez être connecté pour pouvoir poster un message.
Connexion

Pas encore inscrit ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte