![]() |
Pixel gleicher Farbe zählen
Hi
ich brauche von euch die schnellste Möglichkeit die Anzahl Pixel gleicher Farbe herauszufinden. Ganz einfaches Beispiel:
Delphi-Quellcode:
Ich hoffe ihr versteht was ich meine. Ich bin mir sicher das geht noch schneller als bei meinem Beispiel...
type
TColorArray = Array of TColor; TAnzahlArray = Array of Integer; function CountColor(aBitmap: TBitmap; Colors: TColorArray ): TAnzahlArray ; var I, J, K: Integer; Unten, Oben: Integer; begin Unten := Low(Colors); // Um nacher nicht so oft die Funktionen zu benutzen Oben := High(Colors); SetLength(Result, Succ(Oben)); for I := Unten to Oben do Result[I] := 0; for I := 0{oder 1?} to aBitmap.Width do for J := 0{oder 1?} to aBitmap.Height do for K := Unten to Oben do if aBitmap.Canvas.Pixels[I, J] = Color[K] then Inc(Result[K]); end; procedure bla; var Colors: TColorArray; Anzahl: TAnzahlArray; begin SetLength(Colors, 2); Colors[0] := clRed; Colors[1] := clBlue; Anzahl := CountColor(meinBitmap, Colors); showmessage(Format('%d Pixel sind Rot, %d Pixel sind Blau', [Anzahl[0], Anzahl[1])); end; Hat jemand von euch ne Idee? mfg.Dominik |
Re: Pixel gleicher Farbe zählen
Nimm TBitmap.Scanline.
|
Re: Pixel gleicher Farbe zählen
Zitat:
Delphi-Quellcode:
Leider kommt in der Zeile
type
TColorArray = Array of TColor; TAnzahlArray = Array of Integer; TLine = Array[1..3] of Byte; function CountColor(aBitmap: TBitmap; Colors: TColorArray): TAnzahlArray; var I, J, K: Integer; Unten, Oben: Integer; Line: ^TLine; begin Unten := Low(Colors); // Um nacher nicht so oft die Funktionen zu benutzen Oben := High(Colors); SetLength(Result, Succ(Oben)); for I := Unten to Oben do Result[I] := 0; for I := 0{oder 1?} to aBitmap.Height do begin Line := aBitmap.ScanLine[I]; for J := 0{oder 1?} to aBitmap.Width do for K := Unten to Oben do if Line[J] = Colors[K] then Inc(Result[K]); end; end;
Delphi-Quellcode:
eine AV. Wo ist mein Fehler?
if Line[J] = Colors[K] then
|
Re: Pixel gleicher Farbe zählen
Zitat:
Delphi-Quellcode:
Außerdem geht dein Array nur von 1-3 und nicht bis j (Das Bild wird wohl breiter als 3 Pixel sein ;) )
if Line[J]{!}^{/!} = Colors[K] then // dereferenzieren nicht vergessen!
// ==> if Array[1..3] of Byte = TColor then // Das wird nichts oder? Line^ enthält den RGB wert, des ersten Pixels der gescannten Reihe.
Delphi-Quellcode:
Wenn du jetzt den nächsten Pixel haben willst, musst du den Zeiger nach jedem j-Schleifendurchlauf inkrementieren:
Line^[1] = Rot
Line^[2] = Grün Line^[3] = Blau
Delphi-Quellcode:
Der Vergleich wäre dann so möglich:
inc(Line);
Delphi-Quellcode:
Ich hoffe du hast es ungefähr verstanden ;)
if RGB(line[1],line[2],line[3]) = Colors[k] then
Gruß Neutral General |
Re: Pixel gleicher Farbe zählen
Hallo Dominik,
bitte auch den Gültigkeitsbereich der Laufvariablen (off by one) beachten. Grüße vom marabu |
Re: Pixel gleicher Farbe zählen
hey danke für eure Antworten :mrgreen:
ich hab das nun so hingepfrimelt:
Delphi-Quellcode:
Ergebnis: braucht ca doppelt so viel Zeit wie die Methode über Pixels[I, J] und liefert zudem noch falsche Werte.
type
TLine = TRGBTriple; function TPaintEngine.CountColor(Colors: TColorArray): TAnzahlArray; var I, J, K: Integer; Unten, Oben: Integer; Line: ^TLine; begin Unten := Low(Colors); // Um nacher nicht so oft die Funktionen zu benutzen Oben := High(Colors); SetLength(Result, Succ(Oben)); for I := Unten to Oben do Result[I] := 0; for I := 1 to fBuffer.Height - 1 do begin Line := fBuffer.ScanLine[I]; for J := 1 to fBuffer.Width - 1 do begin for K := Unten to Oben do if RGB(line^.rgbtRed,line^.rgbtGreen,line^.rgbtBlue) = Colors[k] then Inc(Result[K]); Inc(Line); end; end; end; |
Re: Pixel gleicher Farbe zählen
Zitat:
In Bitmaps werden die RGB-Werte anders herum gespeichert (BGR):
Delphi-Quellcode:
Line^[1] = Blau
Line^[2] = Grün Line^[3] = Rot |
Re: Pixel gleicher Farbe zählen
Mist, ich war mir nichtmehr sicher :mrgreen:
|
Re: Pixel gleicher Farbe zählen
Zitat:
Delphi-Quellcode:
type
TLine = array [1..3] of Byte; function CountColor(aBitmap: TBitmap; Colors: TColorArray): TAnzahlArray; var I, J, K: Integer; Unten, Oben: Integer; Line: ^TLine; begin Unten := Low(Colors); // Um nacher nicht so oft die Funktionen zu benutzen Oben := High(Colors); SetLength(Result, Succ(Oben)); for I := Unten to Oben do Result[I] := 0; for I := 1 to aBitmap.Height - 1 do begin Line := aBitmap.ScanLine[I]; for J := 1 to aBitmap.Width - 1 do begin for K := Unten to Oben do if RGB(line^[3],line^[2],line^[1]) = Colors[k] then Inc(Result[K]); Inc(Line); end; end; end; |
Re: Pixel gleicher Farbe zählen
Hi,
... Ich weiß nicht genau was bei dir schief läuft. Ich habe mal selbst eine Funktion geschrieben, die, soweit ich sie getestet habe, funktioniert. Ich hoffe ich werde nicht erschlagen weil ich fertigen Code poste.
Delphi-Quellcode:
Gruß
TIntArray = Array of Integer;
function CountColors(bmp: TBitmap; Colors: Array of TColor): TIntArray; var i,j,k: Integer; old: TPixelformat; x: PRGBQuad; tmp: TColor; begin SetLength(Result,Length(Colors)); old := bmp.PixelFormat; // Pixelformat sichern bmp.PixelFormat := pf32Bit; //Mit 32-Bit Bitmaps gehts schneller for i := 0 to bmp.Height-1 do begin x := bmp.ScanLine[i]; for j:= 0 to bmp.Width-1 do begin tmp := RGB(x^.rgbRed,x^.rgbGreen,x^.rgbBlue); for k := 0 to High(Colors) do if Colors[k] = tmp then inc(Result[k]); inc(x); end; end; bmp.PixelFormat := old; // Altes Pixelformat wiederherstellen end; Neutral General |
Re: Pixel gleicher Farbe zählen
Das wird es wahrscheinlich sein @dominikkv, dein Bitmap hat keine 24/32 Bit.
bmp.PixelFormat := pf32Bit; :arrow: array[0..3] of byte bmp.PixelFormat := pf24Bit; :arrow: array[0..2] of byte Mit weniger Bits solltest du nicht rumhantieren, da du sonst die Werte erst "mühsam" in RGB-Werte umrechnen musst. Also schau mal, dass du bei dir
Delphi-Quellcode:
aufrufst
bmp.PixelFormat := pf24Bit;
|
Re: Pixel gleicher Farbe zählen
Wenn ich das ganze mit pf32Bit mache geht das wirklich ein ganzes Stück schneller!
Und wenn ich bei deiner Function, Neutral General, Result zunächst mit 0 initialisiere kommt auch wirklich das richtige Ergebnis raus 8) Vielen Dank euch beiden für eure Hilfe :cheers: 2 Fragen habe ich aber noch: - Wird das ganze mit pf24Bit nochmal schneller? - Wenn ja, wie komme ich dann zu meinem Farbwert, ich hab ja dann nur 2 Werte in dem Array, für RGB brauche ich aber 3 |
Re: Pixel gleicher Farbe zählen
Hi,
1. Die 32-Bit Methode ist die schnellste. 2. [0..2] = 3 Einträge (24 Bit), [0..3] = 4 Einträge (32 Bit) PS: Also bei mir ist das Array schon standardmäßig "genullt"... :gruebel: Aber wenn du es schon nullen willst dann hätte ich da was für dich:
Delphi-Quellcode:
FillChar(Result[0],Length(Result)*SizeOf(Integer),0);
|
Re: Pixel gleicher Farbe zählen
Zitat:
Zitat:
Darum ist bei mir bei den ersten Versuchen wahrscheinlich immer ein falsches Ergebnis rausgekommen -.- Zitat:
Werde jetzt auf jedenfall FillChar verwenden, Danke :stupid: Nochmal Danke an euch beide :dp: :love: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:31 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz