Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi Toleranzen von Farben (https://www.delphipraxis.net/134030-toleranzen-von-farben.html)

BAMatze 14. Mai 2009 10:40


Toleranzen von Farben
 
Hallo und guten Morgen an alle DP´ler,

Heute mal ein ganz anderes Thema, nicht immer nur Komponenten :roll: Also ich zeichne und schreibe auf ein TBitmap mit der Farbe csBlack. Nun wollte ich zurücklesen, wieviele der Pixel in diesem TBitmap nach dem Zeichnen und Beschriften die Farbe csBlack erhalten haben. Leider stoße ich dort auf ein paar Wiedrigkeiten. Gerade bei dem Schriftteil gehen sehr viele Pixel bei der Zählung verloren, da anscheinend eine Fluktuation in den Farben der einzelnen Pixeln vorliegt.

Jetzt habe ich mehrfach zu solchen ähnlichen Themen gelesen, dass DeddyH auf Toleranzen hinweißt, die man dort beim auslesen setzen könnte, leider noch keinen Beitrag gefunden, wo dies mal umgesetzt wurde.

Hat jemand vieleicht ein Beispiel, dass mit Farbtoleranzen arbeitet oder kennt jemand ein Beispiel, wo man sieht, wie man das machen kann?

Vielen Dank
BAMatze

Dust Signs 14. Mai 2009 10:44

Re: Toleranzen von Farben
 
Kann es sein, dass du ClearType aktiviert hast? Das würde dieses Verhalten erklären.

Dust Signs

BAMatze 14. Mai 2009 10:49

Re: Toleranzen von Farben
 
Zitat:

Zitat von Dust Signs
Kann es sein, dass du ClearType aktiviert hast? Das würde dieses Verhalten erklären.

Hmm das sagt mir gerade nichts, wo könnte ich das denn ausstellen, wenn ich es wollte? In der Hilfe hab ich nur was über Rendering gelesen dazu aber aktiv dies eingeschaltet, habe ich glaube nicht.

DeddyH 14. Mai 2009 10:51

Re: Toleranzen von Farben
 
Eine TColor wie clBlack besteht aus 4 Byte (jeweils eins für rot, grün, blau und ein Merkmal für Systemfarben). clBlack ist AFAIK $00000000. Wenn nun beispielsweise der Rotanteil auch nur geringfügig höher ist ($00000001), greift Dein Vergleich nicht mehr. Du könntest nun also die Farbe in ihre Bestandteile zerlegen (GetRValue, GetGValue, GetBValue) und mit einfacher Prozentrechnung ermitteln, ob sich der jeweilige Anteil innerhalb einer von Dir definierten Toleranz (z.B. 5 %) befindet.

Dust Signs 14. Mai 2009 10:53

Re: Toleranzen von Farben
 
ClearType kannst du in der Systemsteuerung deaktivieren, indem du die Kantenglättung bei Schriften auf "deaktiviert" stellst. Mehr Informationen zu ClearType findest du z.B. hier

Dust Signs

BAMatze 14. Mai 2009 10:58

Re: Toleranzen von Farben
 
Zitat:

Zitat von DeddyH
Eine TColor wie clBlack besteht aus 4 Byte (jeweils eins für rot, grün, blau und ein Merkmal für Systemfarben). clBlack ist AFAIK $00000000. Wenn nun beispielsweise der Rotanteil auch nur geringfügig höher ist ($00000001), greift Dein Vergleich nicht mehr. Du könntest nun also die Farbe in ihre Bestandteile zerlegen (GetRValue, GetGValue, GetBValue) und mit einfacher Prozentrechnung ermitteln, ob sich der jeweilige Anteil innerhalb einer von Dir definierten Toleranz (z.B. 5 %) befindet.

Das hört sich schonmal sehr gut an. Werde ich gleich mal versuchen einzubauen. Folgendes habe ich auch gefunden auch dieser Seite. Ähm ja anscheinend versucht er ja auch mit
Delphi-Quellcode:
if abs(bm1.canvas.pixels[i,j] - bm2.canvas.pixels[i,j]) < 20 then
die Unterschiede der Farben einzugehen. Ich hab mir dazu mal ein kleines Programm geschrieben und es an einem einzigen Buchstaben getestet und das geht total in die Hose. Bis zu einem Unterschied von 2 gibt er immer das gleiche aus (natürlich das falsche) und bei 1 gibt er was anderes aus (aber auch flasch). Kann natürlich immer noch sein, dass ich da was flasch verstanden habe. Das nurmal als Einwurf.

Jetzt zu GetRValue, ... :-D

taaktaak 14. Mai 2009 11:18

Re: Toleranzen von Farben
 
Moin,
in dem letzten Beispiel wird der Farbunterschied von Pixeln identischer Koordinate in zwei verschiedenen Bitmaps ausgewertet. In deinem Fall geht es doch aber wohl um die Abweichung von einem Sollwert, oder?

BAMatze 14. Mai 2009 11:28

Re: Toleranzen von Farben
 
Zitat:

Zitat von taaktaak
Moin,
in dem letzten Beispiel wird der Farbunterschied von Pixeln identischer Koordinate in zwei verschiedenen Bitmaps ausgewertet. In deinem Fall geht es doch aber wohl um die Abweichung von einem Sollwert, oder?

Ja richtig. Hab dazu auch mal schnell ein kleines Testprogramm geschrieben. Allerdings ist das Ergebnis schon etwas überraschend. Also obwohl ich ihm eigentlich anweise mit der Farbe clBlack zu schreiben, weichen die meisten Pixelwerte sehr stark vom RGB-Wert (0,0,0) ab. Teilweise sind diese Abweichungen > als 100 Farbstufen in einem der RGB-Bereiche.

Allerdings muss ich jetzt auch sagen, ich versuche ein sehr kleinen Buchstaben zu "scannen".

DeddyH 14. Mai 2009 11:35

Re: Toleranzen von Farben
 
Ich habe mal schnell eine Funktion geschrieben (für Fehlerfreiheit und Performance übernehme ich allerdings kein Garantie):
Delphi-Quellcode:
function SimilarColors(FirstColor, SecondColor: TColor;
                       Percentage: byte = 5): Boolean;

    function ColorInRange(first, second: byte): Boolean;
    begin
      Result := abs(first - second) <= Round(MAXBYTE / 100 * Percentage);
    end;

var R1,R2,G1,G2,B1,B2: byte;
begin
  R1 := GetRValue(FirstColor);
  R2 := GetRValue(SecondColor);
  G1 := GetGValue(FirstColor);
  G2 := GetGValue(SecondColor);
  B1 := GetBValue(FirstColor);
  B2 := GetBValue(SecondColor);
  Result := ColorInRange(R1,R2) and ColorInRange(G1,G2) and ColorInRange(B1,B2);
end;
In kurzen Tests sah das ganz gut aus, aber ich kann mich auch irgendwo verrechnet haben.

Reinhard Kern 14. Mai 2009 12:09

Re: Toleranzen von Farben
 
Zitat:

Zitat von BAMatze
... Also obwohl ich ihm eigentlich anweise mit der Farbe clBlack zu schreiben, weichen die meisten Pixelwerte sehr stark vom RGB-Wert (0,0,0) ab. Teilweise sind diese Abweichungen > als 100 Farbstufen in einem der RGB-Bereiche.
.

Hallo,

das ist logisch, wenn richtig gerendert wurde. Am Rand (des Buchstabens z.B.) wird nämlich die Farbe proportional zur belegten Pixelfläche interpoliert zwischen Buchstabenfarbe und Hintergrund. Gehört z.B. die Häfte des Pixels zu einem schwarzen Buchstaben auf weissem Grund, so erhält das Pixel ein 50% grau. Das heisst EBEN NICHT, dass es sich um ein graues Pixel handelt, sondern dass an diese Stelle eigentlich ein halbes weisses und ein halbes schwarzes Pixel gehört.

Daraus ist zu entnehmen, dass die Abweichung beliebig gross sein kann, im Beispiel 50%, und dass das auch völlig korrekt ist.

Gruss Reinhard

Nachtrag:

a das Ergebnis hängt also auch vom Hintergrund ab.

b um etwa einen Buchstaben zu löschen, müsste man alle Pixel zurücksetzen, die sich vom Hintergrund unterscheiden, auch wenn sie im Beispiel nur 10% grau sind - sonst bleibt ein grauer Schatten übrig.

BAMatze 14. Mai 2009 12:13

Re: Toleranzen von Farben
 
Deine Funktion sieht natürlich schöner aus, weil man die Farbe wechseln kann @DeddyH. Hab hier auch mal eine Funktion geschrieben gehabt, war schon fast fertig, als ich deine Post gesehen hab.

Hier mal meine Funktion:

Delphi-Quellcode:
procedure TForm1.Bildanalyse;
var i, j, AnzahlSchwPixel, PosOben, PosUnten, PosRechts, PosLinks, Anz, RefRValue,
    RefGValue, RefBValue, PCRValue, PCGValue, PCBValue: integer;
begin
  AnzahlSchwPixel := 0; //Anzahl der gefundenen schwarzen Pixel
  Anz := 0; // Anzahl der Schleifendurchgänge (reiner Kontrollwert für mich)
  // die Positionen für Unten und Rechts werden negativ gesetzt, da beim finden einer
  // dieser Grenzen immer ein positiver Wert eingetragen wird
  PosUnten := -1;
  PosRechts := -1;
  // die Psoitionen für Oben und Links werden übernatürlich groß gewählt, da somit eine
  // einfachere Prüfung durchgeführt werden kann.
  PosOben := 999;
  PosLinks := 999;
  Memo1.Clear;
  for i := 1 to FprivBMP.Width do
    begin
      for j := 1 to FprivBMP.Height do
        begin
          Anz := Anz + 1; // Kontrollwert erhöhen
          PCRValue := GetRValue(FprivBMP.Canvas.Pixels[i,j]);
          PCGValue := GetGValue(FprivBMP.Canvas.Pixels[i,j]);
          PCBValue := GetBValue(FprivBMP.Canvas.Pixels[i,j]);
          Memo1.Lines.Add('R ' + inttostr(PCRValue) + ',G ' + inttostr(PCGValue) + ', B ' + inttostr(PCBValue));
          if (PCRValue < 10) and
             (PCGValue < 10) and  // Hier gehe ich jetzt mal davon aus, dass man den Wert der Farbe clBlack weiß.
             (PCBValue < 10) then
            begin
              AnzahlSchwPixel := AnzahlSchwPixel + 1;
              if j < PosOben then PosOben := j;
              if i > PosRechts then PosRechts := i;
              if j > PosUnten then PosUnten := j;
              if i < PosLinks then PosLinks :=i;
            end;
        end;
    end;
  Lbl_Oben.Caption := inttostr(PosOben);
  Lbl_Unten.Caption := inttostr(PosUnten);
  Lbl_Rechts.Caption := inttostr(PosRechts);
  Lbl_Links.Caption := inttostr(PosLinks);
  Lbl_Anzahl.Caption := inttostr(AnzahlSchwPixel);
  Lbl_Anz.Caption := inttostr(Anz);
end;
Funktioniert auch eignentlich gut. Nur PErformance ist aufgrund des Memos nicht so toll.

markus5766h 14. Mai 2009 12:39

Re: Toleranzen von Farben
 
Hallo,
"Funktioniert auch eignentlich gut. Nur PErformance ist aufgrund des Memos nicht so toll."

speicher Deine Werte doch erst einmal nicht visuell (z.B. StringList, Array ...) und
kopiere die erhaltenen Werte nach Abarbeitung der Schleifen in Dein Memo.

BAMatze 14. Mai 2009 13:30

Re: Toleranzen von Farben
 
Zitat:

Zitat von markus5766h
Hallo,
"Funktioniert auch eignentlich gut. Nur PErformance ist aufgrund des Memos nicht so toll."

speicher Deine Werte doch erst einmal nicht visuell (z.B. StringList, Array ...) und
kopiere die erhaltenen Werte nach Abarbeitung der Schleifen in Dein Memo.

Das Memo war ja eigentlich nur mal gedacht, dass ich mir anschauen kann, welche Werte er überhaupt findet. Also kann eigentlich ganz raus fliegen und dann sollte das mit der Performance ok sein.

HeinzJ 14. Mai 2009 13:32

Re: Toleranzen von Farben
 
Würde nicht schon ein einfacher Bitmap-Vorher/Bitmap-Nacher Vergleich ausreichen ?

Medium 14. Mai 2009 16:49

Re: Toleranzen von Farben
 
Mal eine kleine Unwichtigkeit am Rande: Was möchtest du am Ende überhaupt erreichen?


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:56 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 by Thomas Breitkreuz