Trouver tous les pixels noire dans une image binaire trés grande [Résolu]

issam414 10 Messages postés jeudi 1 mai 2008Date d'inscription 4 septembre 2011 Dernière intervention - 8 avril 2011 à 22:49 - Dernière réponse : idrissiilias 76 Messages postés mercredi 19 janvier 2011Date d'inscription 31 janvier 2012 Dernière intervention
- 18 mai 2011 à 15:27
Bonjour à tous,

je débute dans la programmation en c# et je suis déjà perdu, pourtant ça me parait simple comme question .
alors, j'ai une image binaire de plus de (15.000*25.000)pixel; et je veux récupérer les coordonnées de tous les pixel noir. j'ai travaillé avec deux méthodes et pour les deux l'ordinateur n’arrête pas de calculer (plus de 20 minute )
et voici les deux méthodes

1/ (la plus simple mai pas efficace )

Bitmap p = new Bitmap(chemin_de_l_image);
                
                for (int y = 0; y < p.Height; y++)
                {
                    for (int x = 0; x < p.Width; x++)
                    {
                        Color pixelColor = p.GetPixel(x, y);
                        if (pixelColor.G != 255)
                        {
                            mm++;
                            textBox4.Text += x + ";" + y + "/" + "\n";
                        }
                        progressBar1.Value = (mm*100) / (p.Height*p.Width);
                    }
                }



2/ 2éme méthode ( plus complexe mais aussi pas efficace )
   Bitmap bitmap = new Bitmap(chemin_de_l_image);
            int width = bitmap.Width;
            int height = bitmap.Height;
            unsafe
            {
                BitmapData bmpData = bitmap.LockBits(new Rectangle(0, 0, width,
                height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);

                byte* newPixel = (byte*)(void*)bmpData.Scan0;
                byte swap;
                for (int y = 0; y < height; y++)
                    for (int x = 0; x < width; x++)
                    {

                        if (newPixel[2] != 255) 
                        { 
                            textBox4.Text += x + ";" + y + "/" + "\n"; 
                        }
                        newPixel += 4;

                        progressBar1.Value = ((1+x) * (1+y)) / 100;

                    }
                bitmap.UnlockBits(bmpData);
            }


pour la deuxième méthode l'image n'est pas binaire elle est en 32 bits

alors si quelqu'un a une autre méthode ou des réctifications je suis preneur
et un grand merci a tous.
_________________________________
la curiosité est un noble défaut.
Afficher la suite 

6 réponses

Répondre au sujet
LUDINSKI 441 Messages postés mardi 2 décembre 2003Date d'inscription 22 mai 2012 Dernière intervention - 9 avril 2011 à 08:56
+3
Utile
Bonjour,

La première méthode est à proscrire... le GetPixel() est très lent à ce que j'ai déjà pu constater !!

Concernant la deuxième méthode, rien que le fait de modifier textBox4 dans ta boucle prend énormément de temps...
Essayes d'en faire le moins possible dans cette boucle !
Je te propose ceci :

DateTime start = DateTime.Now;

Bitmap bitmap = new Bitmap( imgFilePath );
Rectangle bmpRect = new Rectangle( 0, 0, bitmap.Width, bitmap.Height );

BitmapData bmpData = bitmap.LockBits( bmpRect, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb );
byte* bmpPtr = (byte*)bmpData.Scan0.ToPointer();

int blackPixNbr = 0;

int pixIndex = 0;
int maxPixCount = (bitmap.Width * bitmap.Height) * 4;
while( pixIndex < maxPixCount )
{
    if( bmpPtr[ pixIndex ] != 255 )
        blackPixNbr++;

    pixIndex += 4;
}

bitmap.UnlockBits( bmpData );

DateTime end = DateTime.Now;
TimeSpan during = end - start;
MessageBox.Show( blackPixNbr.ToString() + " pixels noirs\r\nRécupérés en " + during.TotalSeconds.ToString( "0.00" ) + " secondes" );


sinon, au lieu de comptabiliser le nombre de pixels noirs tu peux les stocker dans une liste du genre
List blackPixCoords = new List();
dans laquelle tu stockeras les valeurs de pixIndex...
Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de LUDINSKI
LUDINSKI 441 Messages postés mardi 2 décembre 2003Date d'inscription 22 mai 2012 Dernière intervention - 9 avril 2011 à 11:22
+3
Utile
Si tu souhaites effectuer une requête INSERT à chaque pixel noir rencontré ça sera effectivement SUPER long...

Mais par contre, tu peux construire ta requête dans la boucle et l'exécuter une fois sorti !

la requête sera sous la forme
"INSERT INTO BlackPixels(CoordX, CoordY) VALUES(245, 124), (14521, 24511);"

Voilà ;)
Penses à accepter la réponse pour clore le sujet !!
Et bonne continuation
Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de LUDINSKI
issam414 10 Messages postés jeudi 1 mai 2008Date d'inscription 4 septembre 2011 Dernière intervention - 9 avril 2011 à 11:36
+3
Utile
encore merci pour ta rapidité
ça me convient comme réponse (et j'accepte)
et je te souhaite une bonne journée

________________________________
la curiosité est un noble défaut
Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de issam414
LUDINSKI 441 Messages postés mardi 2 décembre 2003Date d'inscription 22 mai 2012 Dernière intervention - 9 avril 2011 à 09:01
0
Utile
Pour info... dans mon code je teste la valeur du pixel BLEU
Dans le tien tu teste le pixel ROUGE (+2)

Bizarrement, le pointeur récupéré par Scan0 renvoi les pixels non pas en ARGB mais en BGRA !!!!

Mais ceci n'est pas un problème vu que tu testes une image en noir et blanc...
Commenter la réponse de LUDINSKI
issam414 10 Messages postés jeudi 1 mai 2008Date d'inscription 4 septembre 2011 Dernière intervention - 9 avril 2011 à 11:09
0
Utile
mille merci pour ta repense ci rapide et efficace
j'ai testé et ça marche a merveille le temps est 0.45 seconde
le problème été donc dans le remplissage du textbox (maudit textbox)
et pour la liste je vais la remplir dans une base de données

une autre quistion svp:
- si je remplis la base dans la boucle ça ne sera pas leng ?

_________________________________
la curiosité est un noble défaut
Commenter la réponse de issam414
idrissiilias 76 Messages postés mercredi 19 janvier 2011Date d'inscription 31 janvier 2012 Dernière intervention - 18 mai 2011 à 15:27
0
Utile
bonjour par contre moi j ai un souci en faite j ai luminaire qui des leds et je dois detecter les leds eteinte donc je me suis dit de faire 9 rectangle sous forme tableau et dans chaque case du rectangle je mets une condition si le pixel > 255 donc la led est blanche donc c allumer sinn c'est noir donc etiente mais le bleme je c pas comment adapter mes tableaux à mon image pour que je puisse detecter la leds eteinte
si vous voulez que je envoie la photo du luminaire pour avoir une idee bien claire il suffit juste de demander

Mercii
Commenter la réponse de idrissiilias

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.