AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Multimedia weniger Scanline aufrufe ... Graustufenbild
Thema durchsuchen
Ansicht
Themen-Optionen

weniger Scanline aufrufe ... Graustufenbild

Ein Thema von bernhard_LA · begonnen am 10. Feb 2024 · letzter Beitrag vom 6. Apr 2024
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von dummzeuch
dummzeuch

Registriert seit: 11. Aug 2012
Ort: Essen
1.768 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#1

AW: weniger Scanline aufrufe ... Graustufenbild

  Alt 11. Feb 2024, 10:51
As for 8bit the as above but 8bit bitmap are very rare and almost dead format and most importantly it is very wide in range !, this format or to be more accurate the lack of unified/standardized format goes to 80s and the its color space is might hard to work with,
Actually, the 8 bit greyscale (Mono8) is a common format used in machine vision cameras. To use that in bitmaps, they need a greyscale palette. Which then makes access quite easy, because the byte value directly represents the brightness of the pixel.

Why working with 8bit Windows Bitmap (or 8bit DIB) is hard ? because When we talk Windows Bitmap then the there is a table define these 8bit colors representing 256 color value predefined to be used within this 8bit bitmap, so such bitmap will have lookup table with 256 value, the the pixel with grab the value form there, these values can be 8bit, 16bit.. 24bit color value..
As for generic 8 bit color bitmaps you are right: These are very uncommon nowadays, because memory and storage size are no longer limited and graphics cards / monitors generally use 24 bits or even more.
Thomas Mueller
  Mit Zitat antworten Zitat
Kas Ob.

Registriert seit: 3. Sep 2023
487 Beiträge
 
#2

AW: weniger Scanline aufrufe ... Graustufenbild

  Alt 11. Feb 2024, 11:18
Actually, the 8 bit greyscale (Mono8) is a common format used in machine vision cameras. To use that in bitmaps, they need a greyscale palette. Which then makes access quite easy, because the byte value directly represents the brightness of the pixel.
That makes sense, thank you for the links.
Kas
  Mit Zitat antworten Zitat
Michael II

Registriert seit: 1. Dez 2012
Ort: CH BE Eriswil
778 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: weniger Scanline aufrufe ... Graustufenbild

  Alt 11. Feb 2024, 14:55
Dein Code ist viel zu kompliziert und dadurch auch langsam.

So könntest du es für 24Bit tun. Und für die anderen Formate natürlich ähnlich.

Delphi-Quellcode:
procedure CreateSpecialImage(const InBmp, OutBmp: TBitmap; Threshold: Byte);
var
  OutPixel: PRgbTriple;
  height, width, x, y: Integer;

begin
  OutBmp.Assign(InBmp);

  Height := OutBmp.Height;
  Width := OutBmp.Width;

  for y := 0 to Height - 1 do
  begin
    OutPixel := OutBmp.ScanLine[y];
    for x := 0 to Width - 1 do
    begin
      if OutPixel^.Blue > Threshold then OutPixel^.Blue := Threshold;
      if OutPixel^.Red > Threshold then OutPixel^.Red := Threshold;
      if OutPixel^.Green > Threshold then OutPixel^.Green := Threshold;
      inc(OutPixel);
    end;
  end;
end;
Michael Gasser
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.826 Beiträge
 
Delphi 12 Athens
 
#4

AW: weniger Scanline aufrufe ... Graustufenbild

  Alt 11. Feb 2024, 15:18
Im CreateSpecialImage kann ein IF/Assert nicht schaden, wenn das PixelFormat nicht stimmt, sonst kann man sich hier den Speicher zerschießen (z.B. wenn pf1 bis bf16 und somit der Speicher kleiner wäre)


Dein Code ist viel zu kompliziert
Da es überall der selbe Code/Threshold ist ...

Delphi-Quellcode:
var OutByte: PByte; // mit aktiver Pointer-Arithmetic

  for y := 0 to Height - 1 do
  begin
    OutByte := OutBmp.ScanLine[y];
    for x := Width * 3 - 1 downto 0 do
    begin
      if OutByte^ > Threshold then
        OutByte^ := Threshold;
      Inc(OutByte);
    end;
  end;

  for y := 0 to Height - 1 do
  begin
    OutByte := OutBmp.ScanLine[y];
    for OutByte := OutByte to OutByte + Width * 3 - 1 do
      if OutByte^ > Threshold then
        OutByte^ := Threshold;
  end;
Man bräuchte nur "einmal" ScanLine abzufragen, da alle Lines hintereinander liegen,
aber da die Linien an im Speicher ausgerichtet/aligned sind (auf 4 Bytes),
sind eventuell nachträglich noch Bytes eingefügt.

Wenn Width ein Vielfaches von 4, dann nicht ... sonst nach jeder Line aufgerundet werden
oder man arbeitet z.B. mit pf32bit.

Außerdem aufpassen, dass die Lines meistens unten anfangen zu zählen, also die letzte Line zuerst im Speicher liegt.
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu (11. Feb 2024 um 15:26 Uhr)
  Mit Zitat antworten Zitat
Michael II

Registriert seit: 1. Dez 2012
Ort: CH BE Eriswil
778 Beiträge
 
Delphi 11 Alexandria
 
#5

AW: weniger Scanline aufrufe ... Graustufenbild

  Alt 11. Feb 2024, 15:29

Da es überall der selbe Code/Threshold ist ...
Und da Threshold wahrscheinlich eh fast immer 0 ist geht's noch einfacher .
Michael Gasser
  Mit Zitat antworten Zitat
Benutzerbild von dummzeuch
dummzeuch

Registriert seit: 11. Aug 2012
Ort: Essen
1.768 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#6

AW: weniger Scanline aufrufe ... Graustufenbild

  Alt 11. Feb 2024, 15:21
Dein Code ist viel zu kompliziert und dadurch auch langsam.

So könntest du es für 24Bit tun. Und für die anderen Formate natürlich ähnlich.

Delphi-Quellcode:
procedure CreateSpecialImage(const InBmp, OutBmp: TBitmap; Threshold: Byte);
var
  OutPixel: PRgbTriple;
  height, width, x, y: Integer;

begin
  OutBmp.Assign(InBmp);

  Height := OutBmp.Height;
  Width := OutBmp.Width;

  for y := 0 to Height - 1 do
  begin
    OutPixel := OutBmp.ScanLine[y];
    for x := 0 to Width - 1 do
    begin
      if OutPixel^.Blue > Threshold then OutPixel^.Blue := Threshold;
      if OutPixel^.Red > Threshold then OutPixel^.Red := Threshold;
      if OutPixel^.Green > Threshold then OutPixel^.Green := Threshold;
      inc(OutPixel);
    end;
  end;
end;
Von wegen langsam:
Dein Code ruft TBitmap.Scanline Width*Height-mal auf. Jeder dieser Aufrufe ist extrem lahm, wenn auch schon wesentlich schneller als der Zugriff auf TBitmap.Canvas.Pixel[x,y]. Genau das war der Punkt in meinem Blog-Post, auf den Bernhard im ersten Post verwiesen hat. Und da er jedes Pixel sowieso nochmal anpasst, kann er auch gleich die erste Bitmap pixelweise lesen und die zweite schreiben, das spart dann auch noch das TBitmap.Assign.

Edit: Und Himitsu hat recht: Da die Grenze für alle Farben dieselbe ist, kann man die RGB-Bytes auch einfach mittels einer Schleife von 3*Width byteweise abarbeiten statt ein PRgbTriple zu verwenden. Ob das von der Performance her nochmal einen großen Unterschied macht, weiß ich aber nicht. Die Vermeidung der Scanline-Aufrufe bringt deutlich mehr.
Thomas Mueller

Geändert von dummzeuch (11. Feb 2024 um 15:27 Uhr)
  Mit Zitat antworten Zitat
Michael II

Registriert seit: 1. Dez 2012
Ort: CH BE Eriswil
778 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: weniger Scanline aufrufe ... Graustufenbild

  Alt 11. Feb 2024, 15:26
Dann Sorry - macht es so wie es besser ist - ich lasse aber meinen Code als sehr schlechtes Beispiel stehen; ein Mahnmal für "wie man es nicht tun sollte". Danke für die wertvollen Inputs.
Michael Gasser
  Mit Zitat antworten Zitat
Benutzerbild von dummzeuch
dummzeuch

Registriert seit: 11. Aug 2012
Ort: Essen
1.768 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#8

AW: weniger Scanline aufrufe ... Graustufenbild

  Alt 11. Feb 2024, 15:52
Dann Sorry - macht es so wie es besser ist - ich lasse aber meinen Code als sehr schlechtes Beispiel stehen; ein Mahnmal für "wie man es nicht tun sollte". Danke für die wertvollen Inputs.
Es ist kein schlechtes Beispiel, wie man es nicht machen sollte, sondern im Gegenteil ein gutes Beispiel, wie man es lesbar programmieren kann, aber eben nicht die effizienteste Methode dafür. Solange die Performance kein Problem ist, würde ich es vermutlich genauso programmieren. Mein erster Ansatz sah damals auch so aus, war aber eben zu langsam für die Anwendung (Helligkeitsausgleich für riesige Graustufen-Bilder, die zu tausenden verarbeitet werden mussten). Mittels Profiling habe ich dann herausgefunden, was man wie beschleunigen kann.
Thomas Mueller
  Mit Zitat antworten Zitat
Michael II

Registriert seit: 1. Dez 2012
Ort: CH BE Eriswil
778 Beiträge
 
Delphi 11 Alexandria
 
#9

AW: weniger Scanline aufrufe ... Graustufenbild

  Alt 11. Feb 2024, 16:08
Eigentlich wollte ich ja nix mehr dazu schreiben, aber es "nervt" halt doch ein wenig, wenn behauptet statt gemessen wird .

Fünf Mal 1000 Bilder der Grösse 1000x1000 umgewandelt.

Die in #1 vorgestellte Lösung benötigt auf meinem nicht mehr allzu frischen Notebook im Schnitt 4950ms.
Meine in #7 benötigt 2011ms und diese hier (unten) 1373ms (wobei man das ganz sicher schöner und auch ein wenig schneller...)

Delphi-Quellcode:
procedure CreateSpecialImage2(const InBmp, OutBmp: TBitmap; Threshold: Byte);
var
  StartPixel : Pointer;
  OutPixel: PRgbTriple;
  deltascan : NativeInt;
  height, width, x, y: Integer;

begin
  OutBmp.Assign(InBmp);
  StartPixel := OutBmp.ScanLine[0];
  deltascan := NativeInt(OutBmp.ScanLine[1]) - NativeInt(StartPixel);

  Height := OutBmp.Height;
  Width := OutBmp.Width;

  for y := 0 to Height - 1 do
  begin
    OutPixel := StartPixel;
    for x := 0 to Width - 1 do
    begin
      if OutPixel^.Blue > Threshold then OutPixel^.Blue := Threshold;
      if OutPixel^.Red > Threshold then OutPixel^.Red := Threshold;
      if OutPixel^.Green > Threshold then OutPixel^.Green := Threshold;
      inc(OutPixel);
    end;
    inc(PByte(StartPixel), deltascan);
  end;
end;
Michael Gasser

Geändert von Michael II (12. Feb 2024 um 14:30 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.826 Beiträge
 
Delphi 12 Athens
 
#10

AW: weniger Scanline aufrufe ... Graustufenbild

  Alt 11. Feb 2024, 16:41
OK, man kann natürlich auch noch mit SSE/MMX anfangen, also mit nur einem Befehl jeweils 8 Bytes auf einmal,
oder mit CUDA bzw. OpenCL (OK, das wohl eher nicht).

Und natürlich noch Assembler.
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:42 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