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

C# Discussion :

Tableaux et pointeurs


Sujet :

C#

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    61
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 61
    Points : 32
    Points
    32
    Par défaut Tableaux et pointeurs
    Bonjour a tous je viens du C++ et je galère avec les pointeurs ou équivalent...

    voici un bout de code minimal:
    C'est la structures qui sera contenu dans les tableaux
    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
        public class pxl
        {
            public byte R;
            public byte V;
            public byte B;
     
            public pxl()
            {
                R = 0; V = 0; B = 0;
            }
            public pxl(byte _R, byte _V, byte _B)
            {
                R = _R; V = _V; B = _B;
            }
        }
    Je cherche a "relier" deux tableaux en faite:
    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
     
    public pxl[] bufferI;
    public pxl[,] bufferIJ;
     
    /..../
    //Allocation:
    bufferI = new pxl[nbPxls];
    bufferIJ = new pxl[dimX, dimY];
     
    //Initialisation:
     
    for (int i = 0; i < nbPxls; i++){
        bufferI[i] = new pxl();
        bufferI[i].R = 0;
        bufferI[i].V = 0;
        bufferI[i].B = 0;
    }
    for (int x=0; x < dimX; x++){
        for (int y=0; y < dimY; y++){
            bufferIJ[x, y] = bufferI[x+y];
        }
    }
    Je souhaite donc que lorsque je modifie les valeurs de bufferI celle-ci se répercute sur bufferIJ et vice-versa. Je sait le faire en C/C++ en passant par les pointeurs, mais en C# je suppose qu'il faut passer par des références mais je ne sait pas comment faire.

    Merci pour tout aide!

  2. #2
    Membre émérite
    Profil pro
    Mangeur de gauffre
    Inscrit en
    Octobre 2007
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Mangeur de gauffre

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 413
    Points : 2 498
    Points
    2 498
    Par défaut
    Salut

    J'allais dire
    Fais des liste de ta classe (List<T>)
    Tu peux faire des listes de listes
    Les listes contiennent des references a tes classes

    Mais OUPS ! je viens de capter que c'est pour faire du traitement d'image
    Il y a des methodes plus spécifique pour cela je te conseille de faire des recherche a ce sujet

    Petit conseil

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    for (int i = 0; i < nbPxls; i++){
        bufferI[i] = new pxl();
        bufferI[i].R = 0;
        bufferI[i].V = 0;
        bufferI[i].B = 0;
    }
    Pourquoi ne fais tu pas l'initialisation dans le constructeur de pxl ?

    Mais je te conseille vraiment de faire des recherches sur les methodes de traitement d'image a moins que tu souhaite réellement tout faire "a la main" a l'ancienne

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    61
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 61
    Points : 32
    Points
    32
    Par défaut
    BufferI et bufferIJ n'appartiennent pas à la même class. Dans ces condition je vois pas comment je peut initialiser buffer.. dans pxl.

    Et bien oui je veux pouvoir tout faire à la main moi même! Je pense que tu l'aura compris je me sert d'un bitmap pour ouvrir une image, après je récupère les datas de l'image et je me débrouille. Avec ces deux buffer je souhaite avoir deux mode d'accès au pixel : buffer[i,j] et buffer[i].

    Alors il n'est pas possible d'adresser une référence d'un tableau vers l'autre?
    (je n'est peut-être pas le bon vocabulaire). S'il y a une autre possibilité pourquoi pas?

  4. #4
    Membre émérite
    Profil pro
    Mangeur de gauffre
    Inscrit en
    Octobre 2007
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Mangeur de gauffre

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 413
    Points : 2 498
    Points
    2 498
    Par défaut
    Effectivement je pense qu'il y a un problème de vocabulaire et de compréhension

    BufferI et bufferIJ n'appartiennent pas à la même class. Dans ces condition je vois pas comment je peut initialiser buffer.. dans pxl.
    Personnelement je ne sais pas a quels classe ils appartiennent mais je vois clairement que ce sont des tableaux de ta classe pxl dont le constructeur par défaut fait déja ce que tu t'amuse a refaire dans ta boucle
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
            public pxl()
            {
                R = 0; V = 0; B = 0;
            }

    tu l'aura compris je me sert d'un bitmap pour ouvrir une image,
    Disons plutot que tu charge une image dans un BitMap !

    Et bien oui je veux pouvoir tout faire à la main moi même! Je pense que tu l'aura compris je me sert d'un bitmap pour ouvrir une image, après je récupère les datas de l'image et je me débrouille. Avec ces deux buffer je souhaite avoir deux mode d'accès au pixel : buffer[i,j] et buffer[i].
    Alors il n'est pas possible d'adresser une référence d'un tableau vers l'autre?
    (je n'est peut-être pas le bon vocabulaire). S'il y a une autre possibilité pourquoi pas

    As tu regardé les methodes GetPixel et SetPixel

    Pourquoi chercher simple quand on peut faire plus compliqué ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Color col = objBitmap.GetPixel( x, y );
    objBitmap.SetPixel( x, y, col );

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    61
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 61
    Points : 32
    Points
    32
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    Color col = objBitmap.GetPixel( x, y );
    objBitmap.SetPixel( x, y, col );
    Je cherche justement a éviter ce genre de méthode, car trop lente à l'exécution.
    je cherche justement a optimiser le temps d'exécution, et pour cela je souhaite passer par les pointeurs. J'ai donc du code unsafe dans mon programme. voici mon code complet pour exemple:

    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
    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
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
     
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Drawing.Imaging;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
     
    namespace Tri_Optique
    {
        public partial class Form1 : Form
        {
            private int[] pixelR0;
            private int[] pixelV0;
            private int[] pixelB0;
            private int[] pixel0;
            private int[] pixelRRef;
            private int[] pixelBRef;
            private int[] pixelVRef;
            private int[] pixelRef;
            private int[] tabB;
            private int[] tabR;
            private int[] tabV;
     
            public Form1()
            {
                InitializeComponent();
            }
     
            private void quitterToolStripMenuItem_Click(object sender, EventArgs e)
            {
                Close();
            }
     
            private void pToolStripMenuItem_Click(object sender, EventArgs e)
            {
                Config_Parametres fenetre = new Config_Parametres();
                fenetre.ShowDialog();
     
            }
     
            private void nouvelleConfigurationParApprentissageToolStripMenuItem_Click(object sender, EventArgs e)
            {
                Config_Apprentissage fenetre = new Config_Apprentissage();
                fenetre.ShowDialog();
     
            }
     
            private void button_Ouvrir_Click(object sender, EventArgs e)
            {
                Bitmap image = new Bitmap("E:\\images bouchons\\image31.bmp");
                pictureBox_Video.Image = image;
                Bitmap imageref = new Bitmap("E:\\images bouchons\\image_ref.bmp");
                pictureBox_imageRef.Image = imageref;
     
                //conversion de l'image en tableau pour exploitation
                int i, j;
                int dimX = image.Width;
                int dimY = image.Height;
                int nb = dimX * dimY;
                pixelR0 = new int[nb];
                pixelV0 = new int[nb];
                pixelB0 = new int[nb];
                pixel0 = new int[nb];
                BitmapData imageP = image.LockBits(new Rectangle(Point.Empty, image.Size), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
                // Récupération des plans R, V, B...
                unsafe
                {
                    Byte* pPixel = (Byte*)imageP.Scan0;
                    for (int y = 0; y < dimY; y++)
                    {
                        for (int x = 0; x < dimX; x++)
                        {
                            i = y * dimX + x; j = 3 * x;
                            pixelB0[i] = pPixel[j];
                            pixelV0[i] = pPixel[j + 1];
                            pixelR0[i] = pPixel[j + 2];
                        }
                        pPixel += imageP.Stride;
                    }
                }
                image.UnlockBits(imageP);
     
                //conversion de l'image de référence en tableau pour exploitation
                i = 0;
                j = 0;
                int dimXref = image.Width;
                int dimYref = image.Height;
                int nbref = dimXref * dimYref;
                pixelRRef = new int[nbref];
                pixelVRef = new int[nbref];
                pixelBRef = new int[nbref];
                pixelRef = new int[nbref];
                BitmapData imagePref = imageref.LockBits(new Rectangle(Point.Empty, imageref.Size), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
                // Récupération des plans R, V, B...
                unsafe
                {
                    Byte* pPixel = (Byte*)imagePref.Scan0;
                    for (int y = 0; y < dimYref; y++)
                    {
                        for (int x = 0; x < dimXref; x++)
                        {
                            i = y * dimXref + x; j = 3 * x;
                            pixelRRef[i] = pPixel[j];
                            pixelVRef[i] = pPixel[j + 1];
                            pixelBRef[i] = pPixel[j + 2];
                        }
                        pPixel += imagePref.Stride;
                    }
                }
                imageref.UnlockBits(imagePref);
     
     
                i=0;
                j=0;
                for (j=0; j<300; j++)
                { for (i=0; i<4096; i++)
                    tabB[4096*j+i]=pixelB0[4096*j+i]-pixelBRef[4096*j+i];
                    tabR[4096 * j + i] = pixelB0[4096 * j + i] - pixelBRef[4096 * j + i];
                    tabV[4096 * j + i] = pixelB0[4096 * j + i] - pixelBRef[4096 * j + i];
     
                 }
     
     
            }
     
        }
    }

  6. #6
    Membre émérite
    Profil pro
    Mangeur de gauffre
    Inscrit en
    Octobre 2007
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Mangeur de gauffre

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 413
    Points : 2 498
    Points
    2 498
    Par défaut
    Pour te mettre en confiance je te dirais que je suis aussi maniaque de la performance et du code optimisé

    .... Quand ca en vaut réellement la peine

    As tu déja VRAIMENT évalué le temps d'execution en acces "simplifié" GetPixel, SetPixel ?

    Et si VRAIMENT ca prends un temps rédhibitoire je pense que comme tu viens du C tu aurais alors intéret a ecrire ta propre dll en C qui fera tous les traitement low level nécessaire et que tu utilise C# pour l'embalage..., UI, etc..

  7. #7
    Membre émérite
    Profil pro
    Mangeur de gauffre
    Inscrit en
    Octobre 2007
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Mangeur de gauffre

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 413
    Points : 2 498
    Points
    2 498
    Par défaut
    J'ai trouvé un post récent ou Andreis a suggéré qq bons conseils

    http://www.developpez.net/forums/d84...8-bits-csharp/

  8. #8
    Expert confirmé

    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Septembre 2006
    Messages
    3 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Septembre 2006
    Messages : 3 580
    Points : 5 194
    Points
    5 194
    Par défaut
    Salut

    Olibara , GetPixel et SetPixel sont un gouffre en terme de performance

    Par exemple, une image 500*500, ou tu ferais un GetPixel() va te prendre bcp plus de temps que d'attaquer directement le buffer via le LockBit()

  9. #9
    Membre émérite
    Profil pro
    Mangeur de gauffre
    Inscrit en
    Octobre 2007
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Mangeur de gauffre

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 413
    Points : 2 498
    Points
    2 498
    Par défaut
    Salut TheMonz

    J'admet facilement que GetPixel et SetPixel sont un goufre

    Mais recreer des tableaux de classe pxl comme voulait le faire Natrio n'est certainement pas beaucoup plus efficace, voir pire !

    attaquer directement le buffer via le LockBit()
    C'est certainement une bien meilleure solution

    Et je me demande si deleguer tous le traitement bas niveau a une DLL C n'est pas encore plus efficace ?

  10. #10
    Nouveau membre du Club
    Inscrit en
    Décembre 2009
    Messages
    26
    Détails du profil
    Informations forums :
    Inscription : Décembre 2009
    Messages : 26
    Points : 29
    Points
    29
    Par défaut
    Je ne comprend pour quoi tu veux utiliser un tableau multidimensionnel 'bufferIJ = new pxl[dimX, dimY];' Tu peux simplement calculer l'index dans le tableau 'bufferI' comme idx = y*dimX+x.

    Si tu souhaite que tu aies un tableau de byte pour le transmettre à le constructeur de Bitmap (largeur, hauteur, format, donnés) il faut que tu faire l'allocation comme byte[] d = new byte[dimX * dimY * 4] et tu calcule l'index comme idx = (y*dimX+x)*4. Après il faut que tu fasse le 'marshalling' (je ne sais pas le mot en Français pour ça )

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    			byte[] data = new byte[256 * 256];
    			for (int i = 0; i < 256 * 256; ++i)
    				data[i] = (byte)(i % 256);
     
    			IntPtr ptr = System.Runtime.InteropServices.Marshal.AllocHGlobal(256 * 256);
    			System.Runtime.InteropServices.Marshal.Copy(data, 0, ptr, 256 * 256);
    			System.Runtime.InteropServices.Marshal.FreeHGlobal(ptr);
    Faire attention à l'alignement parce que les longueurs des rangées doivent être multiplies de 4.

  11. #11
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    61
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 61
    Points : 32
    Points
    32
    Par défaut
    j'ai utilisé une structure pxl pour simplifier l'accès au pxl. Par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    MyImage.bufferI[i].R = 0;
    en C++ j'arrive même a fair comme cela:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    MyImage(i)[0] = 0;
    Dans les deux accès au pixel i plan rouge. En C++ on passe par les pointeur. Je suis conscient que le faite de copier toutes les donné dans le bufferI est lent. Je cherche aussi un moyen de surcharger l'opérateur () et [], es-ce possible?
    Sinon je passerai par le C/C++.

  12. #12
    Nouveau membre du Club
    Inscrit en
    Décembre 2009
    Messages
    26
    Détails du profil
    Informations forums :
    Inscription : Décembre 2009
    Messages : 26
    Points : 29
    Points
    29
    Par défaut
    Oui, c'est possible de surcharger les opérateurs () et [] dans ta classe:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    public Color this[int x, int y]
    	{
    		get { return m_matrix[y * dimX + y]; }
    		set { m_matrix[y * dimX + x] = value; }
    	}

Discussions similaires

  1. tableaux de pointeurs sur tableaux
    Par Ashin dans le forum C++
    Réponses: 3
    Dernier message: 11/02/2009, 20h31
  2. Tableaux et pointeurs
    Par byonatane dans le forum C
    Réponses: 11
    Dernier message: 10/06/2007, 19h52
  3. Problème avec les tableaux de pointeurs
    Par TheDoci dans le forum C
    Réponses: 2
    Dernier message: 07/01/2007, 13h04
  4. allocation dynamique et tableaux de pointeurs
    Par gbardy dans le forum 4D
    Réponses: 3
    Dernier message: 06/07/2006, 11h08
  5. en COM Tableaux de pointeurs d'interface:
    Par Barahn dans le forum MFC
    Réponses: 11
    Dernier message: 30/09/2005, 16h42

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