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

MATLAB Discussion :

[fread] Lecture matrice image [Débutant]


Sujet :

MATLAB

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Février 2009
    Messages
    76
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 76
    Par défaut [fread] Lecture matrice image
    Bonjour à tous,

    Un bout de code a été développé sous Matlab afin de lire un fichier binaire constitué d'un main header et d'images.

    Pour la lecture de la première image (l'offset a été correctement placé avec fseek), le code est le suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    s.m_data = fread(fid, [s.m_cols, s.m_rows],'uint16');
    où m_cols=340 et m_rows=240 (Résolution de l'image 320*240).

    Tout d'abord, pourquoi la lecture ne se fait pas comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    s.m_data = fread(fid, [s.m_rows, s.m_cols],'uint16');

    D'autre part j'essaie de lire cette première image en ne regardant que la première colonne et ensuite que la première ligne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    firstcol =  fread(fid, [240, 1],'uint16'); %read first col
    firstline = fread(fid, [1, 320],'uint16'); %read first line
    Pour la firstline, j'ai les meme résultats que firstcol mais classés dans 320 colonnes...

    Avez vous une idée pour lire la première ligne des 320 ou 240 colonnes?

    Merci de 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 317
    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 317
    Par défaut
    Les dimensions de l'image sont 320x240 soit un tableau de 320 lignes et 240 colonnes.

    Dans ton fichier, les données sont rangés sous forme d'un vecteur 1x(320x240) soit 1x76800.

    Maintenant, cela ne nous informe pas sur l'ordre d'écriture du tableau dans le fichier.
    Ce dernier a aussi bien pu être écrit ligne par ligne que colonne par colonne.

    Donc soit tu lis le vecteur 1x76800 par paquet de 320 lignes (donc colonne par colonne), soit par paquets de 240 colonnes (donc ligne par ligne)... à toi de voir selon le format de ton fichier.

    Maintenant, il y a un autre soucis... MATLAB stocke les tableaux colonne par colonne (voir ici : Gestion des matrices )

    Donc si ton fichier est écrit colonne par colonne, il n'y a pas de soucis. Mais si c'est ligne par ligne, il faudra transposer ton tableau une fois lu.

    Pour finir, si ton fichier est écrit ligne par ligne et que tu souhaites lire une colonne en particulier, il te faut utiliser l'argument skip de FREAD pour ne lire les valeurs que de la colonne qui t'intéresse.

    Tout ceci peut paraître obscur mais c'est très simple en réalité

    Fais un test avec un tableau de taille réduite 3x4 sur une feuille de papier.
    Mets les 12 valeurs sous forme de vecteur en les prenant ligne par ligne ou colonne par colonne et tu verras qu'il n'y a rien de magique dans tout ça

  3. #3
    Membre confirmé
    Inscrit en
    Février 2009
    Messages
    76
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 76
    Par défaut
    Tout d'abord merci pour ta réponse et tes explications (très claires!!)

    Un petit point aussi : quand la résolution d'une image est donnée comme 320*240, il me semble que l'on aura une matrice 240 lignes, 320 colonnes (dans mon cas, j'ai affiché les valeurs cols et rows pour être sur).

    Mais après tes explications, cette lecture [320,240] ne m'étonne plus. J'ai fait deux essais :

    pour la matrice 3x3:
    1728 1696 1712
    1760 1760 1712
    1712 1712 1712

    pour la matrice 4x4:
    1728 1760 1712 1728
    1760 1712 1712 1728
    1712 1712 1712 1728
    1696 1712 1712 1728

    On peut voir cette lecture par paquets (et oui, il y a bien transposée plus tard dans le code) de 240 colonnes, lecture ligne par ligne pour obtenir 320 lignes que l'on transposera pour retrouver les 320 colonnes. D'où cette
    inversion [320,240] et non [240,320] !!

    J'espère que mon raisonnement est juste!

    Merci beaucoup!

  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 317
    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 317
    Par défaut
    Citation Envoyé par superfunk Voir le message
    Un petit point aussi : quand la résolution d'une image est donnée comme 320*240, il me semble que l'on aura une matrice 240 lignes, 320 colonnes (dans mon cas, j'ai affiché les valeurs cols et rows pour être sur).
    J'ai toujours vu et utilisé l'inverse... mais bon il suffit juste de savoir de quoi on parle quand on est en train de manipuler l'image

    Sinon pour ton problème... la fonction FREAD fonctionne ainsi :

    Pour lire 50 données codées en uint16 et les stocker dans un vecteur 50x1 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    X = fread(fid,50,'uint16');
    Pour lire 50 données codées en uint16 et les stocker dans un vecteur 1x50 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    X = fread(fid,[1,50],'uint16');
    Pour lire 50 données codées en uint16 et les stocker dans un tableau 5x10 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    X = fread(fid,[5,10],'uint16');
    Il arrive généralement que lorsqu'on lit des données par paquets, pmar exemple ici par paquets de 5, on ne sache pas le nombre de paquet à lire. On ne peut donc pas déterminer à l'avance la seconde dimension du tableau X. On fait donc :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    X = fread(fid,[5,inf],'uint16');
    Et on obtient bien un tableau avec 5 lignes et un nombre de colonne fixé par le nombre d'élément lu. Et donc si au final on désirait non pas 5 lignes mais 5 colonnes, il faut transposer le résultat de la lecture :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    X = fread(fid,[5,inf],'uint16').';
    Donc pour revenir à ton problème, si l'image contient 320 lignes et 240 colonnes et que les données sont stockées colonne par colonne, soit par paquet de 320 données :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    X = fread(fid,[320,240],'uint16');
    Si l'image contient 320 lignes et 240 colonnes et que les données sont stockées ligne par ligne, soit par paquet de 240 données :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    X = fread(fid,[240,320],'uint16').';
    Encore une dernière chose, si tu procèdes comme ceci, la classe du tableau X sera Double (soit 64bits) alors que les données de départ sont en uint16 (soit 16bits).

    Si tu veux conserver la classe d'origine :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    X = fread(fif,[...],'uint16=>uint16');
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    X = fread(fif,[...],'*uint16');
    Voila j'espère que je ne suis pas trompé dans mes explications

  5. #5
    Membre confirmé
    Inscrit en
    Février 2009
    Messages
    76
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 76
    Par défaut
    Merci pour le détail de la fonction fread !

    Encore une dernière chose, si tu procèdes comme ceci, la classe du tableau X sera Double (soit 64bits) alors que les données de départ sont en uint16 (soit 16bits).
    Ceci va certainement beaucoup m'aider car je suis en train d'adapter la lecture de cette matrice sous Labview.

    Grâce à tes explications, j'arrive maintenant à lire la matrice dans le bon sens (stockage ligne par ligne par paquets de 320 données) et ainsi à retrouver les valeurs que donnait Matlab. Mais mon tableau 1D sous Labview a une taille beaucoup plus réduite (1x22528) que le vecteur 1x76800 de Matlab...
    Cela vient surement du fait que j'ai lu ces données en 16 bits plutôt qu'en 64 (la chose qui m'ennuie est qu'il n'y a pas un rapport 4 entre 22528 et 76800..)

    Je fais l'essai dans l'après-midi et je te tiens au courant. Encore merci pour ton aide.


    Edit : Je pensais pouvoir tester que plus tard mais j'ai pu le faire de suite.

    Malheureusement ce n'est pas la cause du problème sous Labview, il me faut absolument rester en uint16 pour avoir les mêmes valeurs que sous Matlab. Si je passe en double, les valeurs sont fausses et la taille du tableau n'augmente de toute manière pas.

    Encore merci de ton aide, c'est un autre mystère qu'il va falloir éclaircir ...

  6. #6
    Membre confirmé
    Inscrit en
    Février 2009
    Messages
    76
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 76
    Par défaut
    Re,

    Effectivement, les données sont en uint16 et cela n'empeche pourtant pas matlab de passer les 2^16 (65536), c'est donc bien que la classe de la matrice change.

    Et c'est exactement ce problème de byte stream type que je rencontre sous Labview. Cette "conversion" de type ne se fait pas automatiquement comme sous Matlab!

    Mystères éclairés !!

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Upload] droit lecture sur image uploadée
    Par Mitaka dans le forum Langage
    Réponses: 2
    Dernier message: 23/02/2006, 11h52
  2. Lecture d'images [jpg] [gif] [...]
    Par xenos dans le forum Langage
    Réponses: 2
    Dernier message: 10/10/2005, 13h00
  3. classe de lecture d'images
    Par suckthewindow dans le forum Bibliothèques
    Réponses: 7
    Dernier message: 16/09/2005, 16h06
  4. Probleme de lecture d'image
    Par NicolasR dans le forum Java ME
    Réponses: 13
    Dernier message: 28/07/2005, 14h47
  5. [débutant] problème de lecture d'image
    Par shura dans le forum OpenGL
    Réponses: 16
    Dernier message: 03/07/2004, 18h05

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