Avatar billede mysitesolution Nybegynder
18. september 2005 - 11:39 Der er 12 kommentarer og
1 løsning

Algoritme: finde farve

Hej...

Jeg har denne algoritme:

            Bitmap bm = new Bitmap("test.bmp");

            BitmapData data = bm.LockBits(new Rectangle(new Point(0), bm.Size),
                ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
            IntPtr ptr = data.Scan0;
            int startPoint = 0;
            byte* ptrByte = (byte*)ptr.ToPointer();
            byte* endloc = ptrByte + data.Width * data.Height * 3;

            while (ptrByte < endloc)
            {
                int b = (int)*(ptrByte++), g = (int)*(ptrByte++), r = (int)*(ptrByte++);

                if (r > 250 && g < 250 && b < 250)
                {
                    startPoint = (int)ptrByte - 3;
                    break;
                }
            }

            if (startPoint > 0)
            {
                startPoint -= (int)data.Scan0;
                startPoint = startPoint/3;

                Point pos = new Point(startPoint % data.Width, startPoint / data.Width);
                Console.WriteLine(pos);
            }

            bm.UnlockBits(data);

som gerne skulle finde den første pixel der er R>250,G<250,B<250 men den virker ikke helt? prøv at opret test.bmp, og lav det fx 1000*1000 og med en rød,blå og grøn pixel nogenlunde i starten...
Avatar billede mysitesolution Nybegynder
18. september 2005 - 12:28 #1
100 points then
Avatar billede polle007 Nybegynder
18. september 2005 - 12:35 #2
hos mig virker det umiddelbart fint
Avatar billede mysitesolution Nybegynder
18. september 2005 - 12:58 #3
prøv forskellige billeder, fx også hvor pixels er langt fra starten
Avatar billede polle007 Nybegynder
18. september 2005 - 13:42 #4
Prøv denne udgave

        Bitmap bm = new Bitmap("test.bmp");
   
        BitmapData data = bm.LockBits(new Rectangle(new Point(0), bm.Size), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
        IntPtr ptr = data.Scan0;
        int startPoint = 0;
        byte* ptrByte = (byte*)ptr.ToPointer();
   
        byte* endloc = ptrByte + data.Width * data.Height * 3;
   
        int padWidth = data.Width - ((data.Width+3) & (~3));
        int rowCount = 0;
   
        while (ptrByte < endloc)
        {
            if(rowCount == data.Width)
            {
                ptrByte += padWidth - data.Width;
                rowCount = 0;
            }
            else
            {
                rowCount++;
                int b = (int)*(ptrByte++), g = (int)*(ptrByte++), r = (int)*(ptrByte++);
   
                if (r > 250 && g < 250 && b < 250)
                {
                    startPoint = (int)ptrByte - 3;
                    break;
                }
            }
        }
   
        if (startPoint > 0)
        {
            startPoint -= (int)data.Scan0;
            startPoint = startPoint/3;
            Point pos = new Point(startPoint % data.Width, startPoint / data.Width);
            Console.WriteLine(pos);
        }
   
        bm.UnlockBits(data);
Avatar billede polle007 Nybegynder
18. september 2005 - 13:43 #5
ptrByte += padWidth - data.Width;

skal blot være

ptrByte += padWidth;
Avatar billede polle007 Nybegynder
18. september 2005 - 13:47 #6
endloc skal så også justeres korrekt, hvis bredden er 'skæv'
Avatar billede mysitesolution Nybegynder
18. september 2005 - 13:51 #7
virker slet ikke...

har lavet denne, måske er den lettere at redigere i?

            //Open image
            Bitmap bm = new Bitmap("test.bmp");

            //Lock the bitmap into memory, so it does not move around
            BitmapData data = bm.LockBits(new Rectangle(0, 0, bm.Width, bm.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

            unsafe
            {
                byte* bmPtr = (byte*)(data.Scan0); //Memory start
                byte* lastByte = (byte*)data.Scan0.ToPointer() + data.Width * data.Height * 3;

                while (bmPtr < lastByte)
                {
                    if ((int)*(bmPtr + 2) < 250 && (int)*(bmPtr + 1) < 250 && (int)*(bmPtr) > 250)
                        break;
                     
                    bmPtr += 3;
                }
                int startPoint = (int)bmPtr - (int)data.Scan0;
                startPoint /= 3;
                Point pos = new Point(startPoint % data.Width, startPoint / data.Width);
                Console.WriteLine(pos);
            }
           
            bm.UnlockBits(data);

            Console.Read();
Avatar billede polle007 Nybegynder
18. september 2005 - 13:54 #8
Anyways, dit problem er, at bredden bliver padded så den kan deles med 8

hvis bredden f.eks. er 6 så bliver der tilføjet 2 ekstra pixels til hver linie. Disse skal skippes
Avatar billede mysitesolution Nybegynder
18. september 2005 - 13:55 #9
dvs. du siger altså, at hvis mit billede er 16*16 vil det virke?
Avatar billede mysitesolution Nybegynder
18. september 2005 - 13:58 #10
det vidste jeg ikke :) TAKKER... man lærer noget nyt hver dag :)...

men det er kun bredden, så højden er lige meget?
Avatar billede mysitesolution Nybegynder
18. september 2005 - 14:01 #11
opret svar for det vigtige tip :)... klarer den herfra :)
Avatar billede n1ghtmr Nybegynder
21. september 2005 - 12:48 #12
Hvis du vil have det har jeg skrevet en klasse (SuperBit) der gor det du vil have. Konstruktoren tager et bitmap og laser det saa i hukommelsen. herefter kan du iterere igennem det og til sidst frigive det igen. Det virker (saa vidt jeg ved) med alle 24 og 32 bit bitmaps. Jeg har selv brugt det til at genkende figurer i et pc spil :)
Avatar billede mysitesolution Nybegynder
21. september 2005 - 18:45 #13
det virker nu så...
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester