IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Images Discussion :

Ralentissement boucle for lors de la lecture d'un fichier binaire avec fread


Sujet :

Images

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2011
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2011
    Messages : 13
    Points : 6
    Points
    6
    Par défaut Ralentissement boucle for lors de la lecture d'un fichier binaire avec fread
    Bonjour,

    J'essaye actuellement d'optimiser un code afin que son exécution soit plus rapide. Malheureusement, je me retrouve confronté à un problème dont je n'arrive pas à déterminer a cause. Je m'explique :

    Le but de mon code est de lire un fichier contenant une séquence d'image, d'en extraire une en particulier, de réaliser un traitement puis de passer à l'image suivante et ainsi de suite jusqu’à la dernière image (en simplifier).

    J'ai donc réaliser une boucle for pour réaliser cela.

    Ce qui est étrange c'est que lors de la lecture des premières images, la boucle est relativement rapide, et qu'arrivé à une certaine image, le temps passé pour une itération est multiplié par 10...

    Voici la partie de mon code contenant la boucle dont je vous parle, ainsi que le code me permettant d'extraire une image de la séquence d'image (ReadSML) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    for nbr = 1 : nbrImages
     
        cd(pathRef);
        [a, dataRef, a] = ReadSML(nomRefSML,nbr);
     
        cd(pathAdj);
        [a, dataAdj, a] = ReadSML(nomAdjSML,nbrImages - nbr + 1);
     
        energieTopo = energieTopo + ((dataRef.^2) .* (dataAdj.^2));
        gradTopo = gradTopo  + ((dataRef) .* (dataAdj));
     
    end
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    function [header, data, maxData, minData] = ReadSML(filename,image)
     
    file = fopen(filename,'rb');
     
    fseek(file,4,'cof');
    header.NbX = fread(file,1,'int');
    header.NbZ = fread(file,1,'int');
    header.NbY = fread(file,1,'int');
    header.NbPasTemporel = fread(file,1,'int');
    fseek(file,56,'cof');
    header.PasSpatial = fread(file,1,'float');
    header.PasTemporel = fread(file,1,'float');
    fseek(file,3478,'cof');
    header.PasImages = fread(file,1,'int');
    fseek(file,94,'cof');
    header.NbImages = fread(file,1,'int');
    fseek(file,8,'cof');
     
    deplacement = (image-1)*(header.NbX*header.NbY+1)*4;
     
    fseek(file,deplacement,'cof');
     
    data = fread(file,[header.NbY, header.NbX],'float');
    data = data';
     
    minData = min(min(data));
    maxData = max(max(data));
     
     
    fclose(file);


    Je vous remercie d'avance pour votre aide!

  2. #2
    Rédacteur/Modérateur

    Avatar de Jerome Briot
    Homme Profil pro
    Freelance mécatronique - Conseil, conception et formation
    Inscrit en
    Novembre 2006
    Messages
    20 302
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Freelance mécatronique - Conseil, conception et formation

    Informations forums :
    Inscription : Novembre 2006
    Messages : 20 302
    Points : 52 882
    Points
    52 882
    Par défaut
    Pourquoi ouvrir et fermer les fichiers à chaque itération ?

    Dans un premier temps, je ferais plutôt ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    fidRef = fopen(fullfile(pathRef,nomRefSML,'rb');
    fidAdj = fopen(fullfile(pathAdj,nomAdjSML,'rb');
     
    for nbr = 1 : nbrImages
     
        [a, dataRef, a] = ReadSML(fidRef,nbr);
     
        [a, dataAdj, a] = ReadSML(fidAdj,nbrImages - nbr + 1);
     
        energieTopo = energieTopo + ((dataRef.^2) .* (dataAdj.^2));
        gradTopo = gradTopo  + ((dataRef) .* (dataAdj));
     
    end
     
    fclose(fidRef);
    fclose(fidAdj);
    et dans la fonction ReadSML :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    function [header, data, maxData, minData] = ReadSML(file,img)
    
    fseek(file,4,'bof');
    header.NbX = fread(file,1,'int');
    header.NbZ = fread(file,1,'int');
    header.NbY = fread(file,1,'int');
    header.NbPasTemporel = fread(file,1,'int');
    fseek(file,56,'cof');
    header.PasSpatial = fread(file,1,'float');
    header.PasTemporel = fread(file,1,'float');
    fseek(file,3478,'cof');
    header.PasImages = fread(file,1,'int');
    fseek(file,94,'cof');
    header.NbImages = fread(file,1,'int');
    fseek(file,8,'cof');
    
    deplacement = (img-1)*(header.NbX*header.NbY+1)*4;
    
    fseek(file,deplacement,'cof');
    
    data = fread(file,[header.NbY, header.NbX],'float');
    data = data';
    
    minData = min(min(data));
    maxData = max(max(data));
    Il faut ensuite chercher à optimiser la fonction de lecture.
    Il ne faut lire que les données correspondant à header.NbX et header.NbY avec FREAD et utiliser FSEEK pour passer les autres sans les lire.

    Note qu'il est préférable de ne pas utiliser image comme nom de variable car c'est déjà le nom d'une fonction MATLAB.
    Ingénieur indépendant en mécatronique - Conseil, conception et formation
    • Conception mécanique (Autodesk Fusion 360)
    • Impression 3D (Ultimaker)
    • Développement informatique (Python, MATLAB, C)
    • Programmation de microcontrôleur (Microchip PIC, ESP32, Raspberry Pi, Arduino…)

    « J'étais le meilleur ami que le vieux Jim avait au monde. Il fallait choisir. J'ai réfléchi un moment, puis je me suis dit : "Tant pis ! J'irai en enfer" » (Saint Huck)

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2011
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2011
    Messages : 13
    Points : 6
    Points
    6
    Par défaut
    Merci pour ta réponse rapide.

    Pour l'ouverture du fichier à chaque itération je suis d'accord. D'ailleurs j'ai déjà essayé d'ouvrir qu'une seule fois le fichier, mais quand j'envois fidRef par exemple à la fonction ReadSML, cette dernière n'arrive pas à lire le fichier :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Invalid file identifier.  Use fopen to generate a valid file identifier.
    Pourrais-tu m'expliciter à quoi sert 'fullfile', je n'ai pas réussi à obtenir de réponse claire dans la doc, surtout dans le cas du 'fopen'.

    En ce qui concerne l'optimisation que tu proposes, à moins que je n'ai pas compris ce qui tu veux me dire, il me semble que c'est ce que je fait déjà :

    la variable 'deplacement' indique l'emplacement en nombre de 'bits' de l'image d'interêt, 'fseek' deplace le curseur, et je ne lis que les header.NbX*header.NbY valeurs.


    Je te remercie encore pour ton aide!

  4. #4
    Rédacteur/Modérateur

    Avatar de Jerome Briot
    Homme Profil pro
    Freelance mécatronique - Conseil, conception et formation
    Inscrit en
    Novembre 2006
    Messages
    20 302
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Freelance mécatronique - Conseil, conception et formation

    Informations forums :
    Inscription : Novembre 2006
    Messages : 20 302
    Points : 52 882
    Points
    52 882
    Par défaut
    J'ai fait une petite erreur dans le code ci-dessus :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    fidRef = fopen(fullfile(pathRef,nomRefSML),'rb');
    fidAdj = fopen(fullfile(pathAdj,nomAdjSML),'rb');
    Pour l'intérêt de la fonction FULLFILE, je te renvoie vers la : Comment concaténer le nom d'un fichier et celui d'un répertoire ?

    Sinon pour l'optimisation de ReadSML, il est inutile de relire les paramètres en entête du fichier à chaque itération.

    Tu devrait pouvoir faire ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    fidRef = fopen(fullfile(pathRef,nomRefSML),'rb');
    fidAdj = fopen(fullfile(pathAdj,nomAdjSML),'rb');
     
    fseek(file,4,'bof');
     
    Nb = fread(file,3,'int');
     
    for nbr = 1 : nbrImages
     
        dataRef = ReadSML(fidRef,nbr,Nb(1),Nb(3));
     
        dataAdj = ReadSML(fidAdj,nbrImages - nbr + 1,Nb(1),Nb(3));
     
        energieTopo = energieTopo + ((dataRef.^2) .* (dataAdj.^2));
        gradTopo = gradTopo  + ((dataRef) .* (dataAdj));
     
    end
     
    fclose(fidRef);
    fclose(fidAdj);
    et dans ReadSML :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    function data = ReadSML(file,img,NbX,NbY)
    
    deplacement = (img-1)*(NbX*NbY+1)*4+N;
    
    fseek(file,deplacement,'bof');
    
    data = fread(file,[NbY, NbX],'float').';
    Où N correspond à la taille de l'entête en octets.

    Enfin c'est l'idée...
    Ingénieur indépendant en mécatronique - Conseil, conception et formation
    • Conception mécanique (Autodesk Fusion 360)
    • Impression 3D (Ultimaker)
    • Développement informatique (Python, MATLAB, C)
    • Programmation de microcontrôleur (Microchip PIC, ESP32, Raspberry Pi, Arduino…)

    « J'étais le meilleur ami que le vieux Jim avait au monde. Il fallait choisir. J'ai réfléchi un moment, puis je me suis dit : "Tant pis ! J'irai en enfer" » (Saint Huck)

  5. #5
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2011
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2011
    Messages : 13
    Points : 6
    Points
    6
    Par défaut
    Oui j'avais vu l'oubli de la parenthèse, cependant j'ai la même erreur...

    Pour l'entête je suis d'accord; je viens de faire la modification.

    Tes idées pour optimiser le codes sont très bonnes mais ne corrige pas mon problème initiale qui est qu'a partir d'un certain nombre d'itération, chaque itération prend un temps plus important pour s'effectuer.

    Cela arrive d'un coup en plus. Cette augmentation aurait été progressive je me serait dit que c'était dût au temps de déplacer le "curseur" à l'image d’intérêt (les fichiers à lire font plusieurs dizaines de Go), mais ce n'est pas le cas...

Discussions similaires

  1. Réponses: 6
    Dernier message: 30/12/2011, 22h14
  2. Réponses: 8
    Dernier message: 20/09/2007, 19h44
  3. Problème lors de la lecture d'un fichier xml avec XMLBeans
    Par oscar78 dans le forum Format d'échange (XML, JSON...)
    Réponses: 1
    Dernier message: 07/09/2007, 14h04
  4. Réponses: 15
    Dernier message: 31/03/2007, 16h32
  5. Réponses: 3
    Dernier message: 06/07/2004, 10h21

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo