Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi Art Motion Tracking mit Scanlines (https://www.delphipraxis.net/59120-art-motion-tracking-mit-scanlines.html)

NeoXan 17. Dez 2005 17:29


Art Motion Tracking mit Scanlines
 
Liste der Anhänge anzeigen (Anzahl: 4)
Also...das Prinzip (eine Art Motion Tracking, wenn man so will):

#1
- Ich lese ein Bitmap ein...in diesem Bitmap befindet sich ein oder mehrere Pixel mit einer ganz bestimmten Farbe.
- Ich durchsuche das Bitmap und finde die Position des Pixels und mache in einem Zweiten zur Laufzeit erstellten Bitmap den Pixel an genau derselben Position rot oder blau...irrelevant, ich hebe ihn also hervor
- Ich lese ein weiteres(!) Bitmap ein [bmpIN] und durchsuche ebenfals, dann den gefundenen Pixel wieder auf das zweite Bitmap übertragen

#2
- Dasselbe nur dass ich keine Pixel setze, sondern immer LineTo(x,y) benutze

Vorgehensweise
Jetzt: siehe Oben
hoffentlich später:
- damit es schneller geht das Bitmap zu durchsuchen, alle Farben bis auf die eine zu eleminieren... (so dass ich z.B. nur noch S/W habe)

4 Frames Beispiele:
Video1.jpg (das Endbild bmpOUT)
- so sieht es leider aus
Video0.jpg (von diesen Bildern wird gelesen)
- hier alle 4 Bilder zusammengesetzt...jedes Bild enthält einen Pixel

421 Frames Beispiel mit LineTo:
Lines1.jpg (Endbild bmpOUT)
-So sieht es mit LineTo und Scanline aus
Lines0.jpg (Endbild bmpOUT)
-und so mit Pixels statt Scanline als Suchalgorithmus...so sollte es auch mit scanloine ausschauen

Typ:
Delphi-Quellcode:
type
  TRGB32 = packed record
    B, G, R, A: Byte;
  end;
  TRGB32Array = packed array[0..MaxInt div SizeOf(TRGB32)-1] of TRGB32;
  PRGB32Array = ^TRGB32Array;

  Line : PRGB32Array;
  BitmapIN.PixelFormat := pf32bit;
  BitmapOUT.PixelFormat := pf32bit;
Auch wenn ich versuche auf beiden Bildern dieselben Pixel anzusprechen, so erhalte ich ein eher konfuse Bild? Woran könnte das liegen? Wenn ich das ohne Scanlines mache, also mit Pixels dann dauert es natürlich um einiges länger, aber das Ergebnis ist korrekt :/
Delphi-Quellcode:
    for y := 0 to bmpIN.Height - 1 do
    begin
      Line := bmpIN.ScanLine[y];
      Line2 := bmpOUT.ScanLine[y];    
      for x := 0 to bmpIN.Width - 1 do
      begin
          if (
          (Line[x].R = 0 ) AND
          (Line[x].G = 0 ) AND
          (Line[x].B In [250..255] )
          )
           then
           begin
            Line2[x].B := 255;
            Line2[x].R := 0;
            Line2[x].G := 0;
            Line2[x].A := 0;
           end;
      end;    
    end;

Ratte 17. Dez 2005 17:45

Re: Art Motion Tracking mit Scanlines
 
Wie gehst du mit Pixels das Bild durch? Auch oben-unten, jede Zeile links-rechts?

NeoXan 18. Dez 2005 20:07

Re: Art Motion Tracking mit Scanlines
 
so

Delphi-Quellcode:
for y:=0 to bmpIN.Height do
  for x:=0 to bmpIN.Width do
    for i:=250 to 255 do
      if bmpIN.Canvas.Pixels[x,y] = RGB(0,0,i)
     then
      begin
        if( FirstRun ) then
        begin
          bmpOUT.Canvas.MoveTo(x,y);
          FirstRun := false;
        end;
        bmpOUT.Canvas.LineTo(x,y);
       break;
      end;

grizzly 18. Dez 2005 21:32

Re: Art Motion Tracking mit Scanlines
 
Also, der Code mit den Scanlines sieht eigentlich OK aus. (Statt des "IN" vielleicht einfach ">=250" verwenden, aber das ändert nix am Ergebnis)
Ich hab' ihn hier auch mal schnell ausprobiert, und für eine Bilderserie mit einem wandernden Punkt erhalte ich damit ein Bild mit der Spur des Punktes (Das war es doch, was der Code erreichen soll, oder?).
Das Lines1.jpg sieht mir eher danach aus, als ob hier schon was mit moveto und lineto schiefgelaufen wäre. Kann mir kaum vorstellen, daß das wirklich mit diesem Algo erzeugt wurde.
Oder hat das Zielbild vielleicht ein anderes Handycap: Anderes pixelformat, unterschiedliche Größe?


Gruß
Michael

NeoXan 18. Dez 2005 22:17

Re: Art Motion Tracking mit Scanlines
 
Das ist vielleicht seltsam...

probieren ich bei der Pixel Variante dies hier
Delphi-Quellcode:
      if (
      (bmpIN.Canvas.Pixels[x,y] >= RGB(0,0,250)) AND
      (bmpIN.Canvas.Pixels[x,y] <= RGB(0,0,255))
      )
oder
Delphi-Quellcode:
  Color[0] := RGB(0,0,250);
  Color[1] := RGB(0,0,255);
if bmpIN.Canvas.Pixels[x,y] in [Color[0]..Color[1]]
so bekomme ich noch wirrere Bilder (und die beiden Bilder sind nicht ähnlich), kannst du mir vielleicht mal deinen Suchalgorithmus posten...
wäre dir sehr dankbar...

liebe Grüße
Florian

grizzly 19. Dez 2005 08:20

Re: Art Motion Tracking mit Scanlines
 
Ups, den hab' ich nicht mehr. Ausprobiert und gar nicht erst gespeichert.
Aber es war ja eh Deine Routine mit den ScanLines!
Da hab ich gerade mal ein "procedure Test(BMPIn, BMPOut: TBitmap);" davorgeschrieben. (Okay, und das "IN [250..255]" durch ein ">= 250" ersetzt, keine Ahnung warum)
Dann hatte ich zwei Images auf meiner Form, deren Bitmaps ich explizit auf 32bit, 320*240 Pixel gesetzt habe.
Und in einer Schleife (t := 0 TO 300) hab ich Image1 gelöscht und ein Pixel drauf gezeichnet, irgendwie so:
Image1.Picture.Bitmap.Canvas.Pixels[160+round(80*sin(t/50)),120+round(80*cos(t/40)] := clBlue;
Anschließend rief ich Deine Routine auf ("Test(Image1.picture.bitmap,Image2.picture.Bitmap )") und habe wie erwartet die ganze Spur in Image2 gesehen.

Als ich den Code durchgelesen hatte, dachte ich mir eh, daß der eigentlich funktionieren sollte. Habs ja nur ausprobiert um zu sehen, ob ich nicht doch was übersehen habe. Aber wenn die Rahmenbedingungen stimmen (gleich große Bilder, Bittiefe) funktioniert das Teil wie erwartet.

Meiner Meinung nach ist da irgenwas anderes verquer....

Gruß
Michael

NeoXan 19. Dez 2005 15:36

Re: Art Motion Tracking mit Scanlines
 
Liste der Anhänge anzeigen (Anzahl: 1)
Woot, kleiner Erfolg, also das mit den Pixel funktioniert jetzt

Delphi-Quellcode:
function TfrmMain.ScanPicture(var bmpIN, bmpOUT: TBitmap): boolean;
var
  y, x: integer;
  LineIN, LineOUT: PRGBQuad;
  Red, Green, Blue : Array [0..1] of Byte;
begin

  Red[0]  := $00;
  Green[0] := $00;
  Blue[0] := $F0;

  Red[1]  := $00;
  Green[1] := $00;
  Blue[1] := $FF;

  for y := 0 to bmpIN.Height - 1 do
  begin
    LineIN := bmpIN.ScanLine[y];
    LineOUT := bmpOUT.ScanLine[y];
    for x := 0 to bmpIN.Width - 1 do
    begin

      if(
      (LineIN^.rgbRed  = $00) AND
      (LineIN^.rgbGreen = $00) AND
      (LineIN^.rgbBlue in [Blue[0]..Blue[1]])
      ) then
      begin
        if(DisplayMethod = dmPoints) then
        begin
          LineOUT^.rgbRed  := $00; // = RGB (255, 0, 0) = clRed
          LineOUT^.rgbGreen := $00;
          LineOUT^.rgbBlue := $FF;
        end;
       if(DisplayMethod = dmLines) then
        begin
          if( FirstRun ) then
          begin
  //          bmpOUT.Canvas.MoveTo(x,y);
            FirstRun := false;
          end;
//          bmpOUT.Canvas.LineTo(x,y);
          bmpOUT.Canvas.Ellipse(x - 5, y - 5, x + 1 + 5, y + 1 + 5);
        end;
      end;

      Inc(LineIN);
      Inc(LineOUT);
    end; // x Achse
  end; // y Achse

end;
Aber das mit den Linien klappt immernoch nicht, meine Vermutung wäre, dass es da mit Canvas vielleicht Probleme gibt (?) Ob ich nun Linien zeichne, oder die Pixel etwas "vergrößere"
Delphi-Quellcode:
       if(DisplayMethod = dmLines) then
        begin
          if( FirstRun ) then
          begin
  //          bmpOUT.Canvas.MoveTo(x,y);
            FirstRun := false;
          end;
//          bmpOUT.Canvas.LineTo(x,y);
          bmpOUT.Canvas.Ellipse(x - 5, y - 5, x + 1 + 5, y + 1 + 5);
        end;
Aber einer bestimmten Position werden die Punkte auf der linken Seite auch auf die Rechte Übertrage (siehe Lines1.jpg ganz oben)

Das erste Problem konnte ich wie folgt lösen:
Delphi-Quellcode:
BitmapIN.LoadFromFile('images/'+i2+'.bmp');
BitmapOUT.PixelFormat := BitmapIN.PixelFormat;
ScanPicture(BitmapIN, BitmapOUT);
BitmapOUT.SaveToFile('images/Analysiert'+i2+'.bmp');
grüße
Florian

EDIT:
Als Anhang einmal das bild mit Lines und Pixels(Such)...so sieht es richtig aus....darüber gelegt das Bild was ich erhalte, wenn ich das ganze mit Ellipse (siehe oben) mache...die Ellipsen sind alle ein stück nach links verschoben bzw. tauchen auf der falschen Seite auf... :/ Kann es denn an Canvas liegen? Denn jetzt wo ich die einzelnen Pixel ohne Canvas einfärbe da klappt es recht gut.

UND mit ist noch etwas aufgefallen...
der erste Punkt liegt in dem BMP bei den Koordinate (293|121)...selbst Nachgeschaut...das Programm liefter als Koordinaten aber
X> [219] Y>[121]...
Wenn ich den Pixel mit Scanlines einfärbe klappt alles, versuche ich dasselbe mit (Pixels :=) so endet es im Chaos...woher könnten die Falschen Koordinaten herrühren?

grizzly 19. Dez 2005 19:30

Re: Art Motion Tracking mit Scanlines
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ich kann machen was ich will, bei mir gehts.
Wenn In und Out Bild selbe Größe und Format haben, dann liegts vielleicht an meiner Vorstellung, wie die Input-Bilder beschaffen sind?
Ist jedes neue Input-Bild ein leeres Bild mit einem einzigen blauen Pixel?
Zumindest in meinem Testprojekt ist es so, und da funktionieren beide Methoden. Habs mal angehängt, weil vielleicht hab ich ja eh alles falsch verstanden...

Gruß
Michael

NeoXan 19. Dez 2005 23:55

Re: Art Motion Tracking mit Scanlines
 
ok, danke...mein Problem lag in dem PixelFormat, welche sich beim einlesen geändert hatte. :) *Kopfhau*
Danke nochmals für deine Hilfe...

Liebe Grüße
Florian


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