Colorcount
Übersicht

![]() |
TritonBetreff: Colorcount |
![]() Antworten mit Zitat ![]() |
---|---|---|
Also ich hab ein kleines Toolchen zum zählen der Farben in bildern gecodet. NIchts besonderes, war auch nicht sonderlich schwer.
Allerdings ist es so wie es ist auch nicht sonderlich schnell, ein 800x600 bild hatte bei mir 1 min gedauert. Irgendwo ist ne gewaltige Bremse drin, vermutlich beim Array-handling. Aber irgendwie fällt mir da nichts ein, was da falsch ist - wie auch, funktioniert ja ![]() Code: [AUSKLAPPEN] ;** Minitool zum Farben-Zählen von Bildern ;** 2004, by Triton Graphics 800,600,32,2 bild = LoadImage("test.bmp") breite=ImageWidth(bild) hoehe=ImageHeight(bild) Dim farbe(breite*hoehe) SetBuffer ImageBuffer(bild) LockBuffer ImageBuffer(bild) For scanX = 1 To breite For scanY = 1 To hoehe farbe1 = ReadPixelFast(scanX,scanY) If farbenanzahl = 0 Then farbe(0) = farbe1:farbenanzahl = 1 For suchen = 0 To farbenanzahl If farbe1 = farbe(suchen) Then a=1:Exit Next If a=0 Then farbenanzahl = farbenanzahl + 1:farbe(farbenanzahl) = farbe1 a=0 Next Next UnlockBuffer ImageBuffer(bild) SetBuffer FrontBuffer() DrawBlock bild, 0,0 Color 0,0,0 Rect 0,0,300,15,1 Color 255,255,255 Text 0,0,"Dieses Bild enthält "+farbenanzahl+" Farben" WaitKey End (ja, der code ist weder schön noch toll ![]() Irgendwelche Speed-Ideen also? |
||
- Zuletzt bearbeitet von Triton am Mo, Jul 12, 2004 14:52, insgesamt 2-mal bearbeitet
![]() |
Lord_Vader |
![]() Antworten mit Zitat ![]() |
---|---|---|
JA! Wirklich komisch, nunja. Bei dem Texturfarbenändercode, den ich gepostet habe geht das schneller. Son 500x500 bild in 1 sekunde :\
Und er schreibt ja manche pixel neu ![]() Is wahrscheinlich nur der zugriff auf den speicher. Trotzdem noch lang, bei Photoshop oder sowas macht der das auch immer sehr schnell, nunja ![]() Edit: Ganz vergessen :\ Gute arbeit ^^, ich meine ok is net wirklich schwer aber für leute, die was lernen wollen, oder für die die kein Bock haben das zu proggen ![]() |
||
Blitzkrieg Bop |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Hm, gute Arbeit(wie immer)Triton.
Nur ne kleinigkeit: Ich hab das mit nem weißen Bild getestet und da stimmt was mit dem schwarzen Balken net, wo steht wieviele Farben im Bild sind, weiß auf weiß gesellt nicht gern ![]() |
||
~ Hey Ho Let's Go ~ |
![]() |
Triton |
![]() Antworten mit Zitat ![]() |
---|---|---|
Schreib beim Rect statt 150, 300 hin...
Wegen sowas hab ich aber nicht das Topic eröffnet - ich brauche Speed ![]() |
||
hot-bitGast |
![]() Antworten mit Zitat |
|
---|---|---|
Hoi,
hab mir das noch nicht angesehen, aber beim ersten hingucken, ist mir gleich ein grober Fehler aufgefallen. Drawblock bild, 0, 0 Und dann läßt du von x=1 und y=1 erst die Farbwerte lesen. Also das Ergebnis wird so nie korrekt sein. <Edit> Habe mir das nun angeguckt. 640*480 jpg-Bild braucht über 20 Sekunden bei 32 Bit Farb-tiefe. Mit 16 Bit nur mehr 3 Sekunden. Die gezählten Farben sind dann aber nicht identisch. Toni |
||
![]() |
Vertex |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hi!
Erstmal liest du das Bild falsch ein. For scanX = 0 To breite-1 sowie For scanY = 0 To hoehe-1 muss es heißen. Ja zu dem eigentlich Problem: Ersteinmal https://www.blitzforum.de/viewtopic.php?t=4364 Hier kommst du bei ReadPixelFast voll auf deine Kosten genauer gesagt hier sogar um 33 mal schneller. Weiter könntest du mal versuchen QuickSort auf die Bank anzuwenden, dann per For - Next immer 2 Werte hinterienander prüfen und gegebenenfalls den Counter hochsetzen. Wobei ich nicht wirklich denke, das dies etwas bringt. mfg olli |
||
![]() |
Travis |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ähm. Irgendwie nicht dein Tag heute Triton, oder?
Was soll das denn bewirken? Erst das Bild laden und dann in den ImageBuffer zeichnen? ![]() Code: [AUSKLAPPEN] Bild = LoadImage("test.bmp") [...] SetBuffer ImageBuffer(Bild) DrawBlock Bild, 0,0 Naja, egal. Ich konnte keine Speedbremse finden, aber viellecht war es ja nur dein Debugger? Bei mir dauerte ein 1024x768 Pixel Bild nur 3,7 Sekunden (ohne Debug, natürlich) Ich habe dem Code mal was hinzugefügt. Jetzt werden auch die Anteile der einzelnen Farbwerte bestimmt (in Prozent). Code: [AUSKLAPPEN] ;** Minitool zum Farben-Zählen von Bildern ;** 2004, by Triton InputFile$ = "Test3.bmp" Graphics 800,600,32,2 Bild = LoadImage(InputFile$) Breite = ImageWidth(Bild) Hoehe = ImageHeight(Bild) Dim Farbe(Breite*Hoehe) SetBuffer ImageBuffer(Bild) DrawBlock Bild, 0,0 Start = MilliSecs() LockBuffer ImageBuffer(Bild) For ScanX = 0 To Breite For ScanY = 0 To Hoehe Farbe1 = ReadPixelFast(ScanX,ScanY,ImageBuffer(Bild)) If Farbenanzahl = 0 Then Farbe(0) = Farbe1: Farbenanzahl = 1 r# = r + (Farbe1 And $FF0000)/$10000 g# = g + (Farbe1 And $FF00)/$100 b# = b + (Farbe1 And $FF) For suchen = 0 To Farbenanzahl If Farbe1 = Farbe(suchen) Then a=1:Exit Next If a=0 Then Farbenanzahl = Farbenanzahl + 1:Farbe(Farbenanzahl) = Farbe1 a=0 Next Next UnlockBuffer ImageBuffer(Bild) AppTitle Inputfile + " ("+Breite+"x"+Hoehe+")" SetBuffer FrontBuffer() DrawBlock Bild, 10,80 Color 0,0,0 Rect 0,0,300,15,1 Color 255,255,255 Text 0,0,"Dieses Bild enthält "+Farbenanzahl+" Farben" gesRGB = r+g+b Text 0,20,"Rotanteil: " + (r / gesRGB) * 100 + "%" Text 0,30,"Grünanteil: " + (g / gesRGB) * 100 + "%" Text 0,40,"Blauanteil: " + (b / gesRGB) * 100 + "%" Text 0,60,"Zeit: " + (MilliSecs() - Start) + " ms" WaitKey End |
||
www.funforge.org
Ich hasse WASD-Steuerung. Man kann alles sagen, man muss es nur vernünftig begründen können. |
![]() |
Triton |
![]() Antworten mit Zitat ![]() |
---|---|---|
Zitat: Drawblock bild, 0, 0
Und dann läßt du von x=1 und y=1 erst die Farbwerte lesen. Ups - ändert bei den meisten Bildern aber das Ergebnis nur um paar Farben ![]() Zitat: Mit 16 Bit nur mehr 3 Sekunden.
Die gezählten Farben sind dann aber nicht identisch. Das ist klar - schließlich ist nur 24/32 bit Farbtiefe "truecolor". Zitat: Was soll das denn bewirken? Erst das Bild laden und dann in den ImageBuffer zeichnen?
Es war spät und ich hab fanatisch nach Speedbremsen gesucht ![]() Aber jetzt ist es noch später - erklär mir bitte den Fehler Oo Soll ich erst zeichnen und dann laden? ^^ edit-- jaja, jetzt ist es Mittags - schon klar. Vergiss es ^^ |
||
- Zuletzt bearbeitet von Triton am Mo, Jul 12, 2004 14:53, insgesamt einmal bearbeitet
![]() |
BladeRunnerModerator |
![]() Antworten mit Zitat ![]() |
---|---|---|
Jo... ist klar dass das sehr langsam läuft. Du gehst ja immer wieder das komplette Farbfeld durch obs die Farbe denn schon gibt. Damit ist deine Routine nur dann wirklich schnell, wenn ein Bild die häufigsten Farben zu Beginn der Bitmap enthält (und selbst dann fressen die ganzen if noch ne Menge Zeit).
Hab mir mal erlaubt das Ganze auf ne Bank umzustellen. Geprüft werden nur die 24 Farben-Bit, die 8 Bit Transparenz sind aussen vor (sie wären leicht einzubauen, allerdings hätte die Bank dann die stolze Größe von 512 Mb im Vergleich zu 2Mb bei 24 Bit. Wer genug Speicher hat möge es ausführen...) "Vorteil" ist hier auch dass die Routine bei gleicher Bildgröße immer etwa gleich lange braucht, da Bild als auch Bank nur jeweils einmal durchlaufen werden. Testdurchlauf1: 800*600 Pixel, das Bild hatte 92499 Farben: Triton: 131,08 Sekunden Triton @24 Bit (mit AND $FFFFFF maskiert): 129,072 Sekunden BladeRunner: 5,196 Sekunden Tritons Routine ermittelete zudem eine Farbe zu wenig (wurde mit verschiedenen Bitmaps kontrolliert, nur 1 Farbe wird korrekt ermittelt, ab 2 Farben ist das Ergebnis eins zu niedrig.) Testdurchlauf2: 800*600 Pixel, das Bild hatte 4 Farben: Triton: 0,311 Sekunden Triton@24 bit: 0,322 Sekunden BladeRunner: 5,04 Sekunden Hier ist eine direkte Farbenzählung natürlich absolut im Vorteil. Und der Code: Code: [AUSKLAPPEN] ;** Minitool zum Farben-Zählen von Bildern
;** 2004, by Triton ;** VERSION 2 mit Bank by BladeRunner Graphics 800,600,32,2 bild = LoadImage("test.bmp") breite=ImageWidth(bild) hoehe=ImageHeight(bild) farbfeld=CreateBank(2097152) SetBuffer ImageBuffer(bild) LockBuffer ImageBuffer(bild) start=MilliSecs() For scanX = 0 To breite-1 For scanY = 0 To hoehe-1 farbe1# = ReadPixelFast(scanX,scanY) And $FFFFFF byte#=Floor(farbe1/8) bit#=farbe1 Mod 8 altwert=PeekByte(farbfeld,byte) PokeByte farbfeld,byte,(altwert Or (2^bit)) Next Next UnlockBuffer ImageBuffer(bild) For schleife = 0 To 2097151 wert=PeekByte(farbfeld,schleife) For zaehl=0 To 7 If (wert And 2^zaehl) Then farbzahl= farbzahl+1 End If Next Next endzeit#=MilliSecs()-start SetBuffer FrontBuffer() DrawBlock bild, 0,0 Color 0,0,0 Rect 0,0,300,35,1 Color 255,255,255 Text 0,0,"Dieses Bild enthält "+farbzahl+" Farben" Text 0,20,"Ermittelt in "+(endzeit/1000)+" Sekunden" WaitKey End |
||
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3 Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64 B3D BMax MaxGUI Stolzer Gewinner des BAC#48, #52 & #92 |
![]() |
Triton |
![]() Antworten mit Zitat ![]() |
---|---|---|
Sehr schön. Super Optimiert.
Dennoch frage ich mich, wie gängige Tools (etwa Irfanview) dies in jedem Fall in weniger als 1 sek Schaffen. |
||
![]() |
Jan_Ehemaliger Admin |
![]() Antworten mit Zitat ![]() |
---|---|---|
ganz einfach, indem die das Bild nicht Pixel für Pixel aus dem Grafikspeicher laden, sondern entweder im arrey abgelegt haben, oder das Dateiformat öffnen! | ||
between angels and insects |
David |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Hi!
Was Jan_ mit dem "Dateiformat öffnen" meinte weis ich zwar nicht, aber im Normalfall liest man die Pixeldaten tatsächlich nicht aus dem Grafikspeicher sondern hat eben, wie schon gesagt, ein Bytearray. Wenn man dieses nun durchsucht ist das ganze wesentlich schneller. ![]() grüße |
||
http://bl4ckd0g.funpic.de |
![]() |
TheShadowModerator |
![]() Antworten mit Zitat ![]() |
---|---|---|
oje warum habt ihr floats drinne?
ich habe hier von meinem editor noch so eine routine drinne - muss mal etwas anpassen... |
||
AMD64 3500+ | GeForce6600GT 128MB | 1GB DDR | WinXPsp2 |
![]() |
RallimenSieger des 30-EUR-Wettbewerbs |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ich habe mal nachgedacht, und ohne sortieralgo wüßte ich jetzt nicht wie das schneller gehen könnte, werde da mal was testen.... | ||
[BB2D | BB3D | BB+]
|
![]() |
RallimenSieger des 30-EUR-Wettbewerbs |
![]() Antworten mit Zitat ![]() |
---|---|---|
so hab da mal meine idee umgesetzt,
....bei 800 x 600 Bildern egal wie viele farben immer so um 450 millisecs das Bild habe ich mal mit rein gebaut , könnt natürlich auch eins laden! Code: [AUSKLAPPEN] ;** Minitool zum Farben-Zählen von Bildern
;** 2004, by Triton Graphics 800,600,32,2 ;bild = LoadImage("test.jpg") ;Bild erstellen Bild = CreateImage (800,600) SetBuffer ImageBuffer (bild) For x =0 To 800 Step 5 For y =0 To 600 Step 5 Rect x,y,2,2,1 Color Rand (0,255),Rand (0,255),Rand (0,255) Next Next SetBuffer FrontBuffer() DrawBlock bild, 0,0 breite=ImageWidth(bild) hoehe=ImageHeight(bild) Dim farbe(breite * hoehe) timer1 = MilliSecs() SetBuffer ImageBuffer(bild) LockBuffer ImageBuffer(bild) For scanX = 0 To breite -1 For scanY = 0 To hoehe -1 farbe(z) = ReadPixelFast(scanX,scanY) z= z +1 Next Next UnlockBuffer ImageBuffer(bild) quicksort(0,breite*hoehe) For z = 1 To breite * hoehe If Farbe (z -1) <> Farbe (z) Then farbenanzahl = farbenanzahl +1 Next timer1 = MilliSecs() -timer1 SetBuffer FrontBuffer() DrawBlock bild, 0,0 Color 0,0,0 Rect 0,0,300,30,1 Color 255,255,255 Text 0,0,"Dieses Bild enthält "+farbenanzahl+" Farben" Text 0,15,"Dieses Bild dauerte "+timer1 + " Millisek." WaitKey Cls For t= 0 To breite*hoehe DebugLog Farbe (t) Next End ; Speedsort Function quicksort(l,r) Local p,q,h p=l : q=r x=Farbe((l+r)/2) Repeat While Farbe(p)<x p=p+1 Wend While x<Farbe(q) q=q-1 Wend If p>q Then Exit ;SWAP------------------ h=Farbe (q) Farbe (q)=Farbe (p) Farbe (p)=h ;---------------------- p=p+1 q=q-1 If q<0 Then Exit Forever If l<q Then a=quicksort(l,q) If p<r Then a=quicksort(p,r) Return True End Function |
||
[BB2D | BB3D | BB+]
|
![]() |
Triton |
![]() Antworten mit Zitat ![]() |
---|---|---|
Sehr schön. Wirklich erstaunlich verschnellert.
Wenn das Forum ein "daumen-hoch" Bild hätte, würde ich es jetzt posten. |
||
![]() |
Travis |
![]() Antworten mit Zitat ![]() |
---|---|---|
Gute Idee. Nachdem Rallimen vorhin die Idee hatte mit 'nem Sortieralgo an die Sache ran zu gehen, habe ich's auch noch mal vrsucht, bin aber gescheitert, weil mir keine schnelle Methode dazu bekannt war. |
||
www.funforge.org
Ich hasse WASD-Steuerung. Man kann alles sagen, man muss es nur vernünftig begründen können. |
hot-bitGast |
![]() Antworten mit Zitat |
|
---|---|---|
Hoi,
nur mal so eine Frage am Rande: Für was braucht man das eigentlich ? Toni |
||
![]() |
BladeRunnerModerator |
![]() Antworten mit Zitat ![]() |
---|---|---|
Respekt Rallimen!
Schneller gehgts wohl echt nimmer ![]() |
||
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3 Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64 B3D BMax MaxGUI Stolzer Gewinner des BAC#48, #52 & #92 |
![]() |
TheShadowModerator |
![]() Antworten mit Zitat ![]() |
---|---|---|
jo gute idee... | ||
AMD64 3500+ | GeForce6600GT 128MB | 1GB DDR | WinXPsp2 |
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group