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 :

Analyse de la symétrie par photométrie d'une image [Débutant]


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2018
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2018
    Messages : 12
    Par défaut Analyse de la symétrie par photométrie d'une image
    Bonjour,

    Je me permets de poster ce message ici car je n'ai pas réussi à trouver une solution à mon souci à travers les différentes discussions et FAQ disponibles.

    Dans un cadre professionnel je dois à l'aide de Visual studio 2013 développer un logiciel qui me permettrait de réaliser les choses suivante:

    - Récupérer et lire une photo en niveaux de gris au format bitmap.

    - Placer un curseur qui pourrait être piloter par l'utilisateur et qui permettrait de déplacer un axe vertical sur l'image pour la scinder en deux parties.

    - "Scanner" ces deux parties en comptant le nombre de pixels allumés et le nombre de pixels éteints pour chaque partie.

    - Afficher le résultat.

    Je suis débutant et je n'ai jamais utiliser Visual studio dans ma scolarité. J'ai cependant suivi plusieurs tutoriels d'introduction (notamment celui ci http://www.yevol.com/vcsharp/Lesson15.htm) et je suis donc ouvert à toute forme d'aide la plus détaillée possible (code, lien, solutions etc..).

    Si ce message manque de clarté ou si vous avez besoins de plus d'explications n'hésitez pas à me les demander

    Je vous remercie de l'aide que vous pourrez m'apporter.

  2. #2
    Expert confirmé

    Homme Profil pro
    Responsable déploiement (SCCM, InTune, GPO)
    Inscrit en
    Juillet 2014
    Messages
    3 218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Responsable déploiement (SCCM, InTune, GPO)
    Secteur : Transports

    Informations forums :
    Inscription : Juillet 2014
    Messages : 3 218
    Par défaut
    Lire la couleur des pixels
    Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Bitmap myBitmap = new Bitmap(@"input.png");            
    for (int x = 0; x < myBitmap.Width; x++)
    {
    	for (int y = 0; y < myBitmap.Height; y++)
    	{                    
    		Color pixelColor = myBitmap.GetPixel(x, y);
    	}
    }


    Dessiner une ligne dans une PictureBox
    Code c# : 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
    public void drawline(PictureBox pb, Point p1, Point p2, float Bwidth,Color c1)
    {
    	//refresh the picture box
    	pb.Refresh(); 
    	//create a new Bitmap object
    	Bitmap map=(Bitmap)pb.Image;  
    	//create a graphics object
    	Graphics g = Graphics.FromImage(map);  
    	//create a pen object and setting the color and width for the pen
    	Pen p = new Pen(c1, Bwidth);  
    	//draw line between  point p1 and p2
    	g.DrawLine(p, p1, p2);  
    	pb.Image = map;  
    	//dispose pen and graphics object
    	p.Dispose();  
    	g.Dispose();
    }

  3. #3
    Membre Expert
    Homme Profil pro
    Développeur .Net / Delphi
    Inscrit en
    Juillet 2002
    Messages
    738
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Développeur .Net / Delphi
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2002
    Messages : 738
    Par défaut
    Bonjour,
    Petite remarque concernant :
    Citation Envoyé par ericlm128 Voir le message
    Dessiner une ligne dans une PictureBox
    Code c# : 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
    public void drawline(PictureBox pb, Point p1, Point p2, float Bwidth,Color c1)
    {
    	//refresh the picture box
    	pb.Refresh(); 
    	//create a new Bitmap object
    	Bitmap map=(Bitmap)pb.Image;  
    	//create a graphics object
    	Graphics g = Graphics.FromImage(map);  
    	//create a pen object and setting the color and width for the pen
    	Pen p = new Pen(c1, Bwidth);  
    	//draw line between  point p1 and p2
    	g.DrawLine(p, p1, p2);  
    	pb.Image = map;  
    	//dispose pen and graphics object
    	p.Dispose();  
    	g.Dispose();
    }
    Pour dessiner dans le pictureBox, mieux vaut le faire dans le paint du control :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    int SourisX = 0;
    private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
    {
        SourisX = e.X;
        pictureBox1.Invalidate();
    }
    private void pictureBox1_Paint(object sender, PaintEventArgs e)
    {
        using (Pen p = new Pen(Color.Black))
        {
            e.Graphics.DrawLine(p, new Point(SourisX, 0), new Point(SourisX, pictureBox1.Height));
        }         
    }

  4. #4
    Membre extrêmement actif
    Inscrit en
    Avril 2008
    Messages
    2 573
    Détails du profil
    Informations personnelles :
    Âge : 65

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 573
    Par défaut
    Bonjour
    En complement de la reponse donné par ericlm128,


    - Récupérer et lire une photo en niveaux de gris au format bitmap.
    Les images en niveau de gris sont en général au format de pixel "indexed" (indexé avec une palette intégré au fichier bitmap)
    On peut lire avec Bitmap.GetPixel(x,y) mais on ne peut setter un pixel avec Bitmap.SetPixel(x,y) !!!
    Pour ce faire il faut créer un nouveau bitmap à partir du bitmap source ,le nouveau bitmap est alors d'office au format de pixel Format32bppArgb ( soit 4 octets/pixel
    code exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    myBitmap = new Bitmap(myBitmap);
    - Placer un curseur qui pourrait être piloter par l'utilisateur et qui permettrait de déplacer un axe vertical sur l'image pour la scinder en deux parties.
    Le dessin d'un axe vertical qui sert de "repère séparateur" est trivial et peut se faire dans l’Évent Paint du pictureBox (cet Event est déclenché en appelant pictureBox.Invalidate() )...
    Mais ou l'appeler ?
    dans l’Évent MouseClick du pictureBox car on peut récupérer l'abscisse X de départ de notre axe "repère séparateur" ...

    code exemple (ici axe est une instance d'un Class perso désigné AxisVertical "armé de pied en cap") :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
            private AxisVertical axis = new AxisVertical();
            private void pictureBox1_MouseClick(object sender, MouseEventArgs e)
            {
                axis.Point1 = new Point(e.X, 0);
                axis.Point2 = new Point(e.X, pictureBox1.Height);
     
                pictureBox1.Invalidate();
            }
    Mais il subsiste une difficulté de taille : les points du pictureBox doivent correspondre "point par point" aux pixels de l'image..
    Cette condition est remplie si le pictureBox a sa prop SizeMode = PictureBoxSizeMode.AutoSize,tout autre valeur sera facheuse...

    Cette serie de difficultés resolues on peut ecrire le code complet suivant :
    1/ code du Class AxisVertical:
    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
     
     
     namespace WinDecouperBmp
    {
        public class AxisVertical
        {
            public Point Point1 { get; set; }
            public Point Point2 { get; set; }
            public Pen PenLine { get; set; }
            public AxisVertical()
            {
                PenLine = new Pen(Brushes.Yellow, 1.0f);
                PenLine.DashStyle = System.Drawing.Drawing2D.DashStyle.DashDot;
            }
        }
    }
    2/ code du Form User:
    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
     
     
      namespace WinDecouperBmp
    {
        public partial class Form1 : Form
        {
            private AxisVertical axis = new AxisVertical();
            public Form1()
            {
                InitializeComponent();
            }
            private void Form1_SizeChanged(object sender, EventArgs e)
            {
                Bitmap bmp = new Bitmap(Application.StartupPath + "/Images/modern_arhitecture.bmp");
                bmp = new Bitmap(bmp);
     
                pictureBox1.SizeMode = PictureBoxSizeMode.AutoSize;
                pictureBox1.Image = bmp;
     
                axis.Point1 = new Point(-1, 0);
                axis.Point2 = new Point(-1, 0);
     
            }
            private void pictureBox1_MouseClick(object sender, MouseEventArgs e)
            {
                axis.Point1 = new Point(e.X, 0 );
                axis.Point2 = new Point(e.X, pictureBox1.Width  );
     
                pictureBox1.Invalidate();
            }
     
            private void pictureBox1_Paint(object sender, PaintEventArgs e)
            {
                Graphics gr = e.Graphics;
                DrawAxis(gr);
                if (axis.Point1.X < 0 || axis.Point2.X < 0) return; 
                RepaintBitmap();
            }
     
     
            private void DrawAxis(Graphics gr)
            {
     
                    gr.DrawLine(axis.PenLine, axis.Point1, axis.Point2);
     
            }
            private void RepaintBitmap()
            {
                int countLeftPixels = 0;
                int countRightPixels = 0;
                Bitmap bmp =(Bitmap) pictureBox1.Image;
                for (int y = 0; y < pictureBox1.Height; y++)
                {
                    for (int x = 0; x < pictureBox1.Width; x++)
                    {
                        Color clr =bmp.GetPixel(x, y);
     
                         if (x   <=axis.Point1.X)
                         {
                             countLeftPixels++;
                             clr=Color.FromArgb(clr.A ,Color.Red);
                             bmp.SetPixel(x, y, clr);
                         }
                         else if ( x > axis.Point1.X)
                         {
                             countRightPixels++;
                             clr = Color.FromArgb(clr.A, Color.Blue );
                             bmp.SetPixel(x, y, clr);
                         }
                    }
                    pictureBox1.Image = bmp;
                    label1.Text = countLeftPixels.ToString();
                    label2.Text = countRightPixels.ToString();
                }
     
     
            }
     
        }
     
    }
    Cette façon de coder avec Bitmap.GetPixel(x,y) et Bitmap.SetPixel(x,y,Color) est totalement inefficace,hélas , à cause de sa lenteur d’exécution en presence d'une image est de grande dimension -width * height)...

    Aussi la version suivante avec BitmapData est plus rapide à l’exécution,mais il faut s'armer du class LockImage

    1/code du Class LockImage

    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
     
    using System;
    using  System.Drawing.Imaging;
    using  System.Runtime.InteropServices;
    using System.Drawing;
    namespace WinDecouperBmp
    {
     
     
        public class LockImage
        {
            private Bitmap BaseImage ;
            private int BaseImageWidth ;
            private int BaseImageHeight  ;
            private int TotalPixels ;
            private IntPtr ImageAddress ;
            private BitmapData ImageContent;
            private int[] ImageBuffer;
            //'comptage pixels
            public int CountLeftPixels { get; set; }
            public int CountRightPixels { get; set; }
     
            public Bitmap Image
    	    {
                //  User access to the relevant image.
    		    get { return  BaseImage;}
    		    set 
                {
                    Graphics canvas ;
                    BaseImage = new Bitmap(value.Width, value.Height, value.PixelFormat);
                    canvas = Graphics.FromImage(BaseImage);
                    canvas.DrawImage(value, 0, 0, value.Width, value.Height);
                    canvas.Dispose() ;
                }
    	    }
     
     
     
        private void LockTheImage()
        {
                // Lock the image in memory. How much room
                //      do we need?
                BaseImageWidth = BaseImage.Width;
                BaseImageHeight = BaseImage.Height;
                TotalPixels = BaseImageWidth * BaseImageHeight;
     
                //----- Create a stable (locked) area in memory. It
                //       will store 32-bit color images.
                ImageBuffer = new int[TotalPixels ];
                ImageContent = BaseImage.LockBits(
                new Rectangle(0, 0, BaseImageWidth, BaseImageHeight),
                ImageLockMode.ReadWrite, 
                PixelFormat.Format32bppRgb);
                ImageAddress = ImageContent.Scan0;
     
                 //----- Associate the buffer and the locked memory.
              Marshal. Copy(ImageAddress, ImageBuffer, 0, TotalPixels);
        }
     
            private void UnlockTheImage()
            {   
                // ----- Unlock the memory area.
               Marshal.Copy(ImageBuffer, 0, ImageAddress, TotalPixels);
                Image.UnlockBits(ImageContent);
                ImageContent = null;
                ImageBuffer = new int[0];
            }
            public  void Colorize(AxisVertical axe,Color rightColor,Color leftColor)
            {   
                int pixelIndex ;
                int onePixel ;
                int alphaPart ;
                int redPart ;
                int greenPart ;
                int bluePart ;
     
     
     
                //----- Lock the image for speed.
                LockTheImage();
     
               //----- Process each pixel in the grid.
                for (int y = 0 ; y < BaseImageHeight;  y++)
                {
                    for (int x = 0 ; x< BaseImageWidth;  x++)
                      {
                            // ----- Locate the pixel's color.
                            pixelIndex = y * BaseImageWidth + x;
                            onePixel = ImageBuffer[pixelIndex];
     
                         //----- Extract the color values.
                        alphaPart = (onePixel >> 24) & 0xFF;
                        redPart = (onePixel >> 16) & 0xFF;
                        greenPart = (onePixel >> 8) & 0xFF;
                        bluePart = onePixel & 0xFF;
     
                         //----- Get the general color intensity.
                         if ( x<= axe.Point1.X)
                         {
                             CountLeftPixels++;
                             redPart = rightColor.R;
                             greenPart = rightColor.G ;
                             bluePart = rightColor.B ;
                         }
                         else if ( x > axe.Point1.X)
                         {
                             CountRightPixels++;
                             redPart = leftColor .R;
                             greenPart = leftColor.G;
                             bluePart = leftColor.B;
                         }
     
                        // ----- Set the pixel to the new color. Retain
                        //       the original alpha channel.
                        ImageBuffer[pixelIndex] = (alphaPart << 24) +
                           (redPart << 16) + (greenPart << 8) + bluePart;
     
                    }
                }
     
                //----- Finished. Unlock the image.
                UnlockTheImage();
        }
     
     
        }
     
     
    }
    2/code du Form User:
    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
     
    namespace WinDecouperBmp
    {
        public partial class Form2 : Form
        {
            private AxisVertical axis = new AxisVertical();
            private LockImage lockedimage;
            public Form2()
            {
                InitializeComponent();
            }
     
            private void Form2_SizeChanged(object sender, EventArgs e)
            {
               Bitmap bmp = new Bitmap(Application.StartupPath + "/Images/modern_arhitecture.bmp");
               bmp = new Bitmap(bmp);
     
                pictureBox1.SizeMode = PictureBoxSizeMode.AutoSize;
                pictureBox1.Image = bmp;
     
                axis.Point1 = new Point(-1, 0);
                axis.Point2 = new Point(-1, 0);
     
            }
            private void pictureBox1_MouseClick(object sender, MouseEventArgs e)
            {
                axis.Point1 = new Point(e.X, 0);
                axis.Point2 = new Point(e.X, pictureBox1.Width);
     
                pictureBox1.Invalidate();
     
            }
            private void pictureBox1_Paint(object sender, PaintEventArgs e)
            {
     
                Graphics gr = e.Graphics;
                DrawAxis(gr);
                if (axis.Point1.X < 0 || axis.Point2.X < 0) return;
                RepaintBitmap();
            }
     
            private void DrawAxis(Graphics gr)
            {
     
                gr.DrawLine(axis.PenLine, axis.Point1, axis.Point2);
     
            }
            private void RepaintBitmap()
            {
                lockedimage = new LockImage();
                lockedimage.Image =(Bitmap)pictureBox1.Image ;
     
                lockedimage.Colorize(axis, Color.Red, Color.Blue);
                pictureBox1.Image = lockedimage.Image;
                label1.Text = lockedimage.CountLeftPixels.ToString();
                label2.Text =lockedimage.CountRightPixels.ToString();
            }
        }
    }



    bon code...

  5. #5
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2018
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2018
    Messages : 12
    Par défaut
    Bonsoir,

    Merci pour toutes vos réponses. Je me penche des que possible dessus et vous fais un retour dès que possible

  6. #6
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2018
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2018
    Messages : 12
    Par défaut
    Bonjour,

    Tout d'abord je souhaiterais vous remercier encore une fois à tous pour vos superbes réponses.
    Je reviens vers vous tous, et plus particulièrement vers toi Mabrouki au vu de ta réponse très pédagogique^^, avec mon lot de questions qui peuvent sembler un peu bêtes/triviales .Mais avec moins d'une semaine d'"expérience" sous Visual studio mes connaissances sont très légères donc en attendant de trouver et corriger les erreurs une par une par moi même je vais vous décrire la démarche que j'ai suivie pour faire fonctionner ce code.

    Donc, J'ai ouvert une form dans laquelle j'ai insérer la picture box (logique) en rajoutant les events mouseclik et sizemode. J'ai copié les morceaux de code correspondant dans les différents blocs (Form,picturebox_mouseclick,...) et j'ai aussi rajouté au projet les 2 classes LockImage et Axisvertical nécessaires pour faire marcher la version plus rapide de ton code, en prenant bien soin de reporter les using et les codes à chaque fois et en changeant les déclarations si necessaires (class-->public class,...).

    Au final je me retrouve avec 6 erreurs surement dues à ma maigre expérience . Je vous joint quelques captures d'écrans pour que vous puissiez y voir plus claire.

    Donc voilà quelles sont les étapes que j'ai oubliées/manquées?

    Merci.
    Images attachées Images attachées

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

Discussions similaires

  1. Mesure de symétrie au sein d'une image
    Par deckard_fawkes dans le forum ImageJ
    Réponses: 1
    Dernier message: 04/05/2010, 16h11
  2. Récupérer données d'une base par lien d'une image
    Par ekzouille dans le forum Langage
    Réponses: 18
    Dernier message: 30/12/2008, 18h05
  3. Réponses: 5
    Dernier message: 15/12/2008, 17h15
  4. Réponses: 3
    Dernier message: 15/08/2007, 09h04

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