Trouver tous les pixels noire dans une image binaire trés grande

Résolu
issam414 Messages postés 10 Date d'inscription jeudi 1 mai 2008 Statut Membre Dernière intervention 4 septembre 2011 - 8 avril 2011 à 22:49
idrissiilias Messages postés 76 Date d'inscription mercredi 19 janvier 2011 Statut Membre Dernière intervention 31 janvier 2012 - 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.

6 réponses

LUDINSKI Messages postés 441 Date d'inscription mardi 2 décembre 2003 Statut Membre Dernière intervention 22 mai 2012 8
9 avril 2011 à 08:56
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...
3
LUDINSKI Messages postés 441 Date d'inscription mardi 2 décembre 2003 Statut Membre Dernière intervention 22 mai 2012 8
9 avril 2011 à 11:22
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
3
issam414 Messages postés 10 Date d'inscription jeudi 1 mai 2008 Statut Membre Dernière intervention 4 septembre 2011
9 avril 2011 à 11:36
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
3
LUDINSKI Messages postés 441 Date d'inscription mardi 2 décembre 2003 Statut Membre Dernière intervention 22 mai 2012 8
9 avril 2011 à 09:01
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...
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
issam414 Messages postés 10 Date d'inscription jeudi 1 mai 2008 Statut Membre Dernière intervention 4 septembre 2011
9 avril 2011 à 11:09
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
0
idrissiilias Messages postés 76 Date d'inscription mercredi 19 janvier 2011 Statut Membre Dernière intervention 31 janvier 2012
18 mai 2011 à 15:27
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
0
Rejoignez-nous