Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Farbtöne (mit Tollerenz) in einem Bild ersetzen (https://www.delphipraxis.net/199513-farbtoene-mit-tollerenz-einem-bild-ersetzen.html)

Mad_Max 28. Jan 2019 14:11

Farbtöne (mit Tollerenz) in einem Bild ersetzen
 
Hallo zusammen,

Ich suche nach einer Möglichkeit, wie ich mit GDI+ bestimmte Farbbereiche durch eine definierte Farbe (performant) ersetzen kann? Mit Scannline ist dies viel zu langsam. Mit dem Net-Framework AForge funktioniert dies mit ColorFiltering. Und auch mit OpenCV gibt es Möglichkeiten. Nur möchte ich weder einen NET- Wrapper, noch zusätzliche DLL's einsetzen.

Hat jemand so etwas schon einmal gemacht und kann mir hier einen Tipp geben?

Neutral General 28. Jan 2019 14:17

AW: Farbtöne (mit Tollerenz) in einem Bild ersetzen
 
Naja auch andere Bibliotheken oder Techniken müssen früher oder später alle Pixel des Bildes durchschlaufen und sich die Farbtöne jedes Pixels anschauen (und merken) um so etwas wie "Colorfiltering" bereitstellen zu können. Und das wird wahrscheinlich auch über Scanline (Bzw. direkten Zugriff auf die Pixeldaten - was Scanline ja quasi ist) gehen.

Wie ist denn dein Code?

Redeemer 28. Jan 2019 16:30

AW: Farbtöne (mit Tollerenz) in einem Bild ersetzen
 
Scanline ist schon schnell, wenn nicht machst du was falsch.

Mad_Max 28. Jan 2019 17:58

AW: Farbtöne (mit Tollerenz) in einem Bild ersetzen
 
Wie bereits beschrieben, suche ich eine Möglichkeit mit GDI+ mit dem Ziel, dass die Operation von der GPU durchgeführt wird. Mit openCV benötige ich für die reine Operation, bei einem jpg, mit der Auflösung von 1170 * 850 und 24 Bittiefe irgend etwas um 1 ms (Mit GetTickCount nicht messbar).Da ich hier mit einer dll arbeiten muss, benötige ich mit dem zusätzlichen Ladeaufwand des jpg insgesamt ca 47 ms! Mit Scanline bin ich noch nicht einmal im Ansatz in diesen Bereich gekommen. Zumal ich auch noch unnötig die CPU belaste, die ich für andere Dinge benötige. Nur möchte ich ungern zusätzliche dll's verwenden.

Daher die Suche nach einer Möglichkeit über GDI+. Wer hat da eine Idee?

Neutral General 28. Jan 2019 18:10

AW: Farbtöne (mit Tollerenz) in einem Bild ersetzen
 
Zitat:

Zitat von Mad_Max (Beitrag 1424328)
Daher die Suche nach einer Möglichkeit über GDI+. Wer hat da eine Idee?

EWeiss wahrscheinlich.
Hast du dir denn schon mal GDI+ angeschaut ob es da auf den ersten Blick was gibt, was nützlich aussieht?

EWeiss 28. Jan 2019 19:13

AW: Farbtöne (mit Tollerenz) in einem Bild ersetzen
 
erstelle eine Colormatrix
https://docs.microsoft.com/en-us/win...ngle-color-use
https://www.c-sharpcorner.com/upload...uranindia/941/

Delphi-Quellcode:
  ColorMatrixFlags = (
    ColorMatrixFlagsDefault,
    ColorMatrixFlagsSkipGrays,
    ColorMatrixFlagsAltGray
  );
  TColorMatrixFlags = ColorMatrixFlags;

  ColorMatrix = packed array[0..4, 0..4] of Single;
  TColorMatrix = ColorMatrix;
  PColorMatrix = ^TColorMatrix;
übergebe die Farbwerte.. r, g, b
Sample.
Delphi-Quellcode:
     
      if (nRed <> 0) or (nGreen <> 0) or (nBlue <> 0) then
      begin
        if (nRed <> 0) then
          sR := (nRed / 128.0)
        else
        sR := 1.0;

        if (nGreen <> 0) then
          sG := (nGreen / 128.0)
        else
        sG := 1.0;

        if (nBlue <> 0) then
          sB := (nBlue / 128.0)
        else
        sB := 1.0;

        sN := 0.0001;
        // Farb Matrix füllen
        // Red             Green            Blue             Alpha             W
        c2[0][0] := sR;  c2[1][0] := 0.0; c2[2][0] := 0.0; c2[3][0] := 0.0; c2[4][0] := 0.0; // Red
        c2[0][1] := 0.0; c2[1][1] := sG;  c2[2][1] := 0.0; c2[3][1] := 0.0; c2[4][1] := 0.0; // Green
        c2[0][2] := 0.0; c2[1][2] := 0.0; c2[2][2] := sB;  c2[3][2] := 0.0; c2[4][2] := 0.0; // Blue
        c2[0][3] := 0.0; c2[1][3] := 0.0; c2[2][3] := 0.0; c2[3][3] := 1.0; c2[4][3] := 0.0; // Alpha
        c2[0][4] := sN;  c2[1][4] := sN;  c2[2][4] := sN;  c2[3][4] := 0.0; c2[4][4] := 1.0; // W

        if cMdone then
        begin
          MoveMemory(@c1, @cM, 100);
          cM := MatMultiply(c1, c2);
        end else
        begin
          MoveMemory(@cM, @c2, 100);
          cMdone := true;
        end;
      end;

      if cMdone then
      begin
        GdipCreateImageAttributes(imgAttr);
        GdipSetImageAttributesColorMatrix(imgAttr, ColorAdjustTypeDefault, true,
          @cM, @gM, ColorMatrixFlagsDefault);
      end;

      GdipSetInterpolationMode(graphics, ObjItem.quality);
      GdipDrawImageRectRectI(graphics, img, PosX, PosY, wD, hD, xS, yS, wS, hS, 2, imgAttr, ImgAbort, nil);
Du benötigst zum setzen der Farb Attribute

API's
GdipCreateImageAttributes
GdipSetImageAttributesColorMatrix
GdipDisposeImageAttributes

zum zeichnen
Ein Image vom Bitmap-Source über GdipCreateBitmapFromScan0 erstellen das du in der Farbe verändern willst.

API's
GdipCreateBitmapFromScan0
GdipCreateFromHDC
GdipSetInterpolationMode
GdipDrawImageRectRectI
GdipDeleteGraphics
GdipDisposeImage

Willst du nun noch den Alpha Wert verändern dann musst du auch hier das jeweilige Byte im Array ändern.
Siehe..
Delphi-Quellcode:
     
      if (Alpha < 255) then
      begin
        sT := (min(254, Alpha) / 255.0);
        // Farb Matrix füllen
        // Siehe Transparenz! in row 4, column 4
        c2[0][0] := 1.0; c2[1][0] := 0.0; c2[2][0] := 0.0; c2[3][0] := 0.0; c2[4][0] := 0.0;
        c2[0][1] := 0.0; c2[1][1] := 1.0; c2[2][1] := 0.0; c2[3][1] := 0.0; c2[4][1] := 0.0;
        c2[0][2] := 0.0; c2[1][2] := 0.0; c2[2][2] := 1.0; c2[3][2] := 0.0; c2[4][2] := 0.0;
        c2[0][3] := 0.0; c2[1][3] := 0.0; c2[2][3] := 0.0; c2[3][3] := sT;  c2[4][3] := 0.0;
        c2[0][4] := 0.0; c2[1][4] := 0.0; c2[2][4] := 0.0; c2[3][4] := 0.0; c2[4][4] := 1.0;
        if cMdone then
        begin
          MoveMemory(@c1, @cM, 100);
          cM := MatMultiply(c1, c2);
        end else
        begin
          MoveMemory(@cM, @c2, 100);
          cMdone := true;
        end;
      end;
Zitat:

mit dem Ziel, dass die Operation von der GPU durchgeführt wird.
Das kannst du dir abschminken. GDI, GDI+ rendern nicht über die GPU! da musst du dich schon mit OpenGL, DIRECTX(Direct3D\Direct2D) beschäftigen.

gruss

Schokohase 28. Jan 2019 19:33

AW: Farbtöne (mit Tollerenz) in einem Bild ersetzen
 
Zitat:

Zitat von Mad_Max (Beitrag 1424313)
Mit Scannline ist dies viel zu langsam. Mit dem Net-Framework AForge funktioniert dies mit ColorFiltering.

AForge ist OpenSource und da kann man auch mal einen Blick riskieren
(Die gehen da quasi per Scanline durch das Bild und vergleichen die Pixelwerte)

EWeiss 28. Jan 2019 19:37

AW: Farbtöne (mit Tollerenz) in einem Bild ersetzen
 
Zitat:

Zitat von Schokohase (Beitrag 1424336)
Zitat:

Zitat von Mad_Max (Beitrag 1424313)
Mit Scannline ist dies viel zu langsam. Mit dem Net-Framework AForge funktioniert dies mit ColorFiltering.

AForge ist OpenSource und da kann man auch mal einen Blick riskieren
(Die gehen da quasi per Scanline durch das Bild und vergleichen die Pixelwerte)

Da kann er schauen wie er will GDI und GDI+ werden nicht über die Hardware gerendert.
Wenn es rein um die Manipulation von Pixeln geht, gut, da gibt's mehrere Möglichkeiten.

Ich behaupte das eine direkte Bit Manipulation schneller ist als Scanline.

OK bin raus da es ihm ums Hardware Rendern geht also über die GPU und das ist mit GDI+ nicht machbar.

gruss

TiGü 29. Jan 2019 12:31

AW: Farbtöne (mit Tollerenz) in einem Bild ersetzen
 
Zitat:

Zitat von Mad_Max (Beitrag 1424328)
...irgend etwas um 1 ms (Mit GetTickCount nicht messbar).

Nimm mal besser TStopWatch aus System.Diagnostics. Das arbeitet genauer.

Zitat:

Zitat von Mad_Max (Beitrag 1424328)
Da ich hier mit einer dll arbeiten muss, benötige ich mit dem zusätzlichen Ladeaufwand des jpg insgesamt ca 47 ms!
Nur möchte ich ungern zusätzliche dll's verwenden. Daher die Suche nach einer Möglichkeit über GDI+. Wer hat da eine Idee?

Vielleicht ist das ein bisschen Eulen nach Athen tragen, aber mit GDI+ verwendest du explizit auch eine DLL (GdiPlus.dll), die in der Regel unter C:\Windows\System32 liegt.

Von welcher Größenordnung reden wir denn? Wieviele JPEGs sind das denn so? Wie oft machst du das? Passiert das auf einen Server oder normalen PC? Welche GPU hat der?

Mad_Max 30. Jan 2019 18:52

AW: Farbtöne (mit Tollerenz) in einem Bild ersetzen
 
Super EWeiss, danke. Die Info's hatten mir gefehlt. Kann es aber erst in ein paar Tagen testen. SOweit ich weiss nutzt GDI+ doch auch die Hardwarebeschleunigung. In dem Fall etwa nicht?

@TiGü: Klar stehen hinter GDI+ auch Dll's. Die sind jedoch bereits mit Windows auf dem System. Mit TStopWatch bekomme ich dann tatsächlich 14ms heraus (bei Verwendung von Opencv).

Ich habe für jedes jpg max. 800ms zeit. In dieser Zeit muss eine Farbmaske drüber laufen und als Output dann je ein Farb- Grau und Schwarzweiss Bild.

Sind quasi "normale" PC's mit Xeon- CPU und durchschnittliche NVidea.

Sollte es mit GDI+ länger dauern, werde ich es eben doch mit opencv machen. Die Performance ist für mich sehr zufrieden stellend und ist sehr weit weg von AForge oder "Scanline".


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:17 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz