17. september 2005 - 14:54
Der er
10 kommentarer og 2 løsninger
Algoritme: finde farve
Hej... Jeg søger en algoritme der kan finde farver der fx er over 250rød,over 250 blå og over 250 gul fra fx et Image, eller bitmap... Jeg har selv lavet en, som simpelhen søger hvert enkelt pixel, men det tager ALLLLLLT for lang tid... det skulle gerne gå forholdsvis hurtigt
Annonceindlæg fra HP
17. september 2005 - 15:18
#1
hvis du skal checke alle pixels så skal du vel checke alle pixels ??
17. september 2005 - 15:24
#2
Bruger du GetPixel / SetPixel ? Det er kendt, at disse metoder er ret langsomme. Du er nødt til at søge hver pixel igennem for at opnå det du søger. Men det går sikkert hurtigere hvis du laver en buffer med de rå data og selv løber det igennem.
17. september 2005 - 15:25
#3
ja kan du have ret i... Men måden jeg gjorde det var noget lignede det her: for (int i = 0; i < ANTALPIXELS) { if (billede.getpixel.color.red > 250) //tror det bar nogenlunde det den hed { blah } } jeg ved der er en hurtigere løsning, da jeg har set andre programmer gøre noget ligende... ville det være bedre at tage bitmap billedet binært, og så kører alle bytes igennem?
17. september 2005 - 15:26
#4
driis-> noget ikke at se dit svar inden jeg postede, men ja getpixel...
17. september 2005 - 15:29
#5
at læse billedet ind som byte array og løbe bytes igennem vil uden tvivl være hurtigere men forudsætter dog at man kender formatet
17. september 2005 - 15:46
#6
har en bog hvor formatet er vist hhm... tror bare ikke jeg er alt for cool til c# til at kunne lave det... men man kan jo lærer af det så :)
17. september 2005 - 15:49
#7
Følgende er en mulighed: unsafe static void Main(string[] args) { Bitmap bm = new Bitmap("mc.jpg"); BitmapData data = bm.LockBits(new Rectangle(new Point(0), bm.Size), ImageLockMode.ReadOnly,PixelFormat.Format24bppRgb); IntPtr ptr = data.Scan0; int rCount = 0, gCount = 0, bCount = 0; int threshold = 200; byte * ptrByte = (byte *)ptr.ToPointer(); for ( int pos = 0 ; pos < 3 * data.Width * data.Height ; pos += 3 ) { if ( *(ptrByte + pos) > threshold ) rCount++; if ( *(ptrByte + pos + 1) > threshold ) gCount++; if ( *(ptrByte + pos + 2) > threshold ) bCount++; } Console.WriteLine("{0}, {1}, {2}",rCount,gCount,bCount); } Jeg tror ikke det kan laves meget hurtigere. Du skal i øvrigt kompilere med /unsafe eller finde en måde at undgå pointeren.
17. september 2005 - 15:50
#8
Og kald i øvrigt bm.UnlockBits(data) til sidst, det glemte jeg.
17. september 2005 - 16:07
#9
Her er en lidt optimeret version, der sparer nogle additioner: unsafe static void Main(string[] args) { Bitmap bm = new Bitmap("mc.jpg"); DateTime dtBegin = DateTime.Now; BitmapData data = bm.LockBits(new Rectangle(new Point(0), bm.Size), ImageLockMode.ReadOnly,PixelFormat.Format24bppRgb); IntPtr ptr = data.Scan0; int rCount = 0, gCount = 0, bCount = 0; int threshold = 200; byte * ptrByte = (byte *)ptr.ToPointer(); byte * endloc = ptrByte + data.Width * data.Height * 3; while(ptrByte < endloc) { if ( *(ptrByte++) > threshold ) rCount++; if ( *(ptrByte++) > threshold ) gCount++; if ( *(ptrByte++) > threshold ) bCount++; } bm.UnlockBits(data); Console.WriteLine("{0}, {1}, {2}",rCount,gCount,bCount); TimeSpan ts = DateTime.Now - dtBegin; Console.WriteLine("Execution time: {0}.{1} seconds",ts.Seconds,ts.Milliseconds); }
17. september 2005 - 16:09
#10
Sidste version kan eksekveres på 31 millisekunder ved 4 mio. pixels (på min maskine). Det er eksklusive indlæsning af billedet på disk.
17. september 2005 - 16:10
#11
DAMN det går hurtigt :) lige hvad jeg havde brug for... TAK TAK og atter tak :) det går i hvert fald 9 gange så hurtigt som min :)
17. september 2005 - 16:10
#12
nej, 90 gange hurtigere mente jeg..
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.