Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Pixels vs. Scanline. Seltsames Ergebnis... (https://www.delphipraxis.net/56670-pixels-vs-scanline-seltsames-ergebnis.html)

Flips 9. Nov 2005 15:34


Pixels vs. Scanline. Seltsames Ergebnis...
 
Hi @ all.

Bin an nem Programm welches Bilder vergleicht. In sehr vielen Thread´s und Post´s wird erwähnt das die Scanline Methode sehr viel schneller sei als die Pixels[x,y] Methode. Allerdings habe ich ein erstaunliches Ergebnis. Hier die Zeiten für den Vergleich von:

Bildergröße: 160*120 Pixel = 19600 Pixel

Zitat:

Scanline

Zeit/ms Unterschiede/Pixel
453 5355
453 5332
453 5538
469 5738

Pixels

Zeit/ms Unterschiede/Pixel
94 5595
78 5572
78 5560
79 5468
Irgendwie ist die Canvas.Pixels Methode um Meilen schneller als Scanline. Hier der Code:

Delphi-Quellcode:
//Scanline
procedure CompareImagesWithScanline(Image1,Image2:TBitmap);
var line1,line2 : PByteArray;
    x,y        : integer;
    differents : integer;
const max = 3;
begin
Zeit1 := GetTickCount;
differents := 0;
 for y := 0 to Image1.Height -1 do
 begin
  line1 := Image1.ScanLine[y];
  line2 := Image2.ScanLine[y];
   for x := 0 to Image1.Width -1 do
     if abs(line1[x]-line2[x]) > max then
     inc(differents);
 end;

Zeit2 := GetTickCount;
Form1.ListBox1.Items.Add(IntToStr(Zeit2-Zeit1));
Form1.ListBox2.Items.Add(IntToStr(differents));
end;


//Pixels
procedure CompareImagesWithPixels(Image1,Image2:TBitmap);
var x,y: integer;
Pixel1, Pixel2: Byte;
differents: integer;

const max = 3;
begin
Zeit1 := GetTickCount;
differents := 0;
 for y := 0 to Image1.Height -1 do
   for x := 0 to Image1.Width -1 do
    begin
    Pixel1 := Image1.Canvas.Pixels[x,y];
    Pixel2 := Image2.Canvas.Pixels[x,y];
     if abs(Pixel2-Pixel1) > max then
     inc(differents);
    end;
Zeit2 := GetTickCount;
Form1.ListBox1.Items.Add(IntToStr(Zeit2-Zeit1));
Form1.ListBox2.Items.Add(IntToStr(differents))
end;
Wisst ihr wieso das so ist???
Bin jetzt vollkommen verwirrt.

Mfg Flips

brechi 9. Nov 2005 16:38

Re: Pixels vs. Scanline. Seltsames Ergebnis...
 
weil du schwachsinn machst

puxels gibt nen TColor = integer zurück, das müsstest du noch mit GetRValue (G/B) auflösen um so den unterschied festzustellen
ausserdem muss man bei nem scanline noch pf24bit einstellen um dann bytesweise immer die farben zu bekommen: schau mal nach Trgbtriple oder prgbarray, und images per VAR param übergeben, dann kannste auch geich vergessen wenn dud as alles gemacht hast scanline mit Gettickocunt zu messen, dann wirst wohl Querperformancecounter brauchen dem kleinem bild

ichbins 9. Nov 2005 16:38

Re: Pixels vs. Scanline. Seltsames Ergebnis...
 
hai, bei dir MUSS scanline natürlich langsamer sein, da du in einer for-schleife die Zeilen einlieset und dann ein einer weiteren for-schleife die Pixel vergleichst. Im unteren Verfahren hast du ach 2 for-schleifen, also verwendest du praktisch bei beiden Funktionen die selbe Technik, nur wenn du zuerst über scanline noch den Speicher kopierst und dann erst überprüfst, kann er ja gar nicht schneller sein, da du einfach den selben code nur um ein paar ecken weiter verwendest.

@brechi: 2 colors kann man auch vergleichen ohne sie zuerst aufzuteilen. du teilst 2 integerwerte ja auch nicht zuerst in ihre 4 Bytes auf und vergleichst die dann extra :gruebel: [edit]du hast doch recht :oops: ich dachte es geht nur darum ob die dinger gleich sind | aaaaber bei der scanline-methode muss man ja den selben Unterschied auch machen.[/edit]

Flips 9. Nov 2005 16:56

Re: Pixels vs. Scanline. Seltsames Ergebnis...
 
dumm gefragt:
und wie bekomm ich die ganze Geschwindigkeit rausgekitzelt?

ps: der rohbau is von Delphi Source Tipps

xaromz 9. Nov 2005 17:00

Re: Pixels vs. Scanline. Seltsames Ergebnis...
 
Hallo,
Zitat:

Zitat von ichbins
hai, bei dir MUSS scanline natürlich langsamer sein, da du in einer for-schleife die Zeilen einlieset und dann ein einer weiteren for-schleife die Pixel vergleichst.

Das ist aber der korrekte Weg. Wenn man das Ganze schneller haben will, dann muss man sich die letzte Scanline holen (Bitmaps sind ja kopfüber gespeichert), damit kann man das ganze Bild auf einmal durchgehen.

Ich hab das übrigens mal bei mir ausprobiert. Bei einem kleinen Bild (650x430 Pixel) dauert Scanline Null, Pixels ca. 500 Ticks.

Gruß
xaromz

Flips 9. Nov 2005 17:04

Re: Pixels vs. Scanline. Seltsames Ergebnis...
 
Zitat:

Zitat von xaromz
Hallo,
Zitat:

Zitat von ichbins
hai, bei dir MUSS scanline natürlich langsamer sein, da du in einer for-schleife die Zeilen einlieset und dann ein einer weiteren for-schleife die Pixel vergleichst.

Das ist aber der korrekte Weg. Wenn man das Ganze schneller haben will, dann muss man sich die letzte Scanline holen (Bitmaps sind ja kopfüber gespeichert), damit kann man das ganze Bild auf einmal durchgehen.

Ich hab das übrigens mal bei mir ausprobiert. Bei einem kleinen Bild (650x430 Pixel) dauert Scanline Null, Pixels ca. 500 Ticks.

Gruß
xaromz

Wie jetzt? Mit einer Scanline das ganze Bild durchgehen?
(Bin heute ned gut im Kopf, bin extrem müde :pale: )

[edit]Achso, du meinst von hinten anfangen oder wie? :gruebel: [/edit]

xaromz 9. Nov 2005 17:14

Re: Pixels vs. Scanline. Seltsames Ergebnis...
 
Hallo,
Zitat:

Zitat von Flips
Wie jetzt? Mit einer Scanline das ganze Bild durchgehen?
(Bin heute ned gut im Kopf, bin extrem müde :pale: )

[edit]Achso, du meinst von hinten anfangen oder wie? :gruebel: [/edit]

ist doch ganz einfach:
Delphi-Quellcode:
var
  P: PByteArray;
  C: Integer;
begin
  P := Bitmap1.ScanLine[Bitmap1.Height - 1];
  for C := 0 to Bitmap1.Width * Bitmap1.Height - 1 do
    P[C] := Random(255);
end;
Damit füllst Du ein Bitmap mit Zufallsfarben. Dabei ist das Bitmap allerdings 8 Bit. Bei 24 Bit wird's schwieriger: Eine Zeile ist immer an einer Integer-Grenze ausgerichtet. Deshalb muss man z. B. bei einem 13 Pixel breiten Bild bei jeder Zeile 3 Byte addieren. Das geht dann so:
Delphi-Quellcode:
var
  P: PByteArray;
  C: Integer;
  Filler: Byte;
begin
  P := Bitmap1.ScanLine[Bitmap1.Height - 1];
  Filler := 4 - (Bitmap.Width mod 4);
  for C := 0 to ((Bitmap1.Width + Filler) * Bitmap1.Height) * 3 - 1 do
    P[C] := Random(255);
end;
Gruß
xaromz

SirThornberry 9. Nov 2005 17:16

Re: Pixels vs. Scanline. Seltsames Ergebnis...
 
genau, man kann mit einer Scanline das ganze Bild durchgehen, davon holt man sich das Scanline der letzten Zeile. Wenn du über das Ende dieser Zeile hinaus gehst (liest/schreibst) kommst du automatisch in die Zeile darüber etc.

Flips 9. Nov 2005 17:19

Re: Pixels vs. Scanline. Seltsames Ergebnis...
 
d.h. das ich nur eine Schleife brauche?

xaromz 9. Nov 2005 17:25

Re: Pixels vs. Scanline. Seltsames Ergebnis...
 
Hallo,
Zitat:

Zitat von Flips
d.h. das ich nur eine Schleife brauche?

genau. Bei 24 Bit ist aber der Inhalt der Füllbytes am Ende jeder Zeile undefiniert. Deshalb solltest Du stattdessen lieber 32 Bit nehmen, da hast Du immer eine Integer-Ausrichtung. Außerdem kann man auf ein Integer schneller zugreifen als auf drei Farb-Bytes.

gruß
xaromz

Flips 9. Nov 2005 17:27

Re: Pixels vs. Scanline. Seltsames Ergebnis...
 
thx.

Habe diesen Code getestet(Und die Bitmaps auf pf24bit gesetzt):

Delphi-Quellcode:
line1 := Image1.ScanLine[Image1.Height-1];
line2 := Image2.ScanLine[Image1.Height-1];
   for x := 0 to Image1.Width*Image1.Height do
   begin
   if abs(line1[x]-line2[x]) > max then
     inc(differents);
Es werden bei einem 320*160 großem bild nur noch 0-30 ticks beansprucht.


PS: Auch wenns evtl. falsch is :P


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:49 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