AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Bewegungsmelder

Ein Thema von Clane · begonnen am 7. Okt 2005 · letzter Beitrag vom 9. Nov 2005
 
Benutzerbild von turboPASCAL
turboPASCAL

Registriert seit: 8. Mai 2005
Ort: Sondershausen
4.274 Beiträge
 
Delphi 6 Personal
 
#17

Re: Bewegungsmelder

  Alt 8. Okt 2005, 11:49
So einen "Bewegungsmelder" zu machen ist gar nicht so leicht. Wenn man bedenkt das jedes Bild zu dem vorherigen unterschiedlich ist welches von einer Kamera aufgenommen wird. Damit meine ich das Bildrauschen was in der Kamera entsteht. Jeder Pixel ist von den Farbwerten leicht unterschiedlich.
Um das zu umgehen müsste man die Farbwerte verringern, ein Graustufenbild mit 256 Farben wäre da eine Alternative.
Jetzt könnte man ein aufgenommenes Bild (Bitmap) mit einem davor aufgenommenen Bild vergleichen.

Dabei ist die nun die Frage wie diese beiden Bilder verglichen werden sollen.

- gesamte Bilder vergleichen Pixel für Pixel / hohe Fehlerrate bei viel Bewegungen

- Bilder in Bereiche aufteilen und anschließend diese vergleichen / hohe Genauigkeit geringe Fehlerrate

Zum vergleichen von zwei Bitmaps Pixel zu Pixel zwei einfache Varianten:

abfragen der Pixel uber die GDI mit:
Delphi-Quellcode:
for y := 0 to Bitmap1.Height -1 do
      for x := 0 to Bitmap1.Width -1 do
      begin
        Bitmap1_PixelColor := Bitmap1.Canvas.Pixels[x,y];
        Bitmap2_PixelColor := Bitmap2.Canvas.Pixels[x,y];
        if Bitmap1_PixelColor <> Bitmap2_PixelColor then ...
      end;
da diese Funktion sehr langsam ist sollte man sich für Scanline entscheiden. Das würde dann so aussehen:
Delphi-Quellcode:
function BitmapCompare(Bitmap1, Bitmap2: TBitmap; DifferentPixel: Integer): TRect;
var
  y, x, CountDifferentPixel: Integer;
  Bitmap1Pixel, Bitmap2Pixel: PRGBQuad; // PRGBQuad def. in Unit Windows;
  aRect: TRect;
begin
  // ein Rechteck auf Min-und Maxwerte vordef.
  aRect := Rect(65000, 65000, 0, 0);
  CountDifferentPixel := 0;

  for y := 0 to Bitmap1.Height - 1 do
  begin
    // Bitmaps Y Linie einlesen
    Bitmap1Pixel := Bitmap1.ScanLine[y];
    Bitmap2Pixel := Bitmap2.ScanLine[y];

    for x := 0 to Bitmap2.Width - 1 do
    begin
      // Pixel farbwerte vergleichen zw. Bitmap1Pixel u. Bitmap2Pixel
      if RGB(Bitmap1Pixel^.rgbRed, Bitmap1Pixel^.rgbGreen, Bitmap1Pixel^.rgbBlue) <>
        RGB(Bitmap2Pixel^.rgbRed, Bitmap2Pixel^.rgbGreen, Bitmap2Pixel^.rgbBlue) then
      begin
        // das Rechteck (aRect) auf die Werte der unterschiedlichen
        // Pixel erweitern die ausserhab des Bereiches des Rechtecks liegen
        if x < aRect.Left then aRect.Left := x;
        if y < aRect.Top then aRect.Top := y;
        if x > aRect.Right then aRect.Right := x;
        if y > aRect.Bottom then aRect.Bottom := y;
        Inc(CountDifferentPixel);
      end;
      // Zeiger auf nächsten Pixel setzen
      Inc(Bitmap1Pixel);
      Inc(Bitmap2Pixel);
    end;
  end;
  // keinen Unterschied gefunden dann kein Rechteck ansonsten
  // das Rechteck zurückgeben in dem sich die Pixel unterscheiden.
  if CountDifferentPixel > DifferentPixel // Grosse des Schwellwerts der Unterschiede
    then Result := TRect(0, 0, 0, 0)
    else Result := aRect;
end;


// Umwandeln eines Bitmaps in Grauwerte auf einfache Art und Weise (eine Möglichkeit von vielen)
procedure MakeGreyBitmap(aBitmap: TBitmap);
var
  PixelLine: PByteArray;
  x, y: integer;
begin
 aBitmap.PixelFormat := pf24Bit;
 for y := 0 to aBitmap.height - 1 do
  begin
    PixelLine := aBitmap.ScanLine[y];
    for x := 0 to aBitmap.width - 1 do
    begin
       PixelLine^[x*3] := (PixelLine^[x*3] + PixelLine^[x*3+1] + PixelLine^[x*3+2]) div 3;;
       PixelLine^[x*3+1] := PixelLine^[x*3];
       PixelLine^[x*3+2] := PixelLine^[x*3];
    end;
  end;
end;

// Aufruf zB. so, hier wir in ein Preview Bitmap ein
// Rechteck gezeichnet in dem ein Unterschied vorliegt.

// ...
MakeGreyBitmap(BitmapAlt);
MakeGreyBitmap(BitmapNeu);
PreviewBitmap.Canvas.Rectangle(BitmapCompare(BitmapAlt, BitmapNeu, 1000));
Der Code ist jetzt nur mal so zusammengetippt und nicht getest.

Wenn man die Farbwerte zu gering setzt also zB. 16 Farben ist durch das Umrechnen der Farbwerte die Fehlerquelle zu gross, da man beim umrechnen icht immer die selben Farbwerte erreicht wie bei der vorherigen Umrechnung, das kann man mal mit einem Paint Programm ausprobieren.

Matti
Meine Software-Projekte - Homepage - Grüße vom Rüsselmops -Mops Mopser
  Mit Zitat antworten Zitat
 


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 01:44 Uhr.
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