Entwickler-Ecke

Multimedia / Grafik - bildervergleich


Fabian E. - Mo 15.01.07 17:59
Titel: bildervergleich
Moin!
kennt jemand von euch ein pogramm oder noch besser ne schöne unit mit der man zwei bilder auf "grobe unterschiede" überprüfen kann? also z.B. ob jemand im bild steht?
will dadraus ne kleine arlarmanlage für meine webcam basteln^^

Vielen dank schon mal!

Fabi


Marc. - Mo 15.01.07 18:24

Du könntest schauen, ob sich einige Pixel geändert haben!
Ich vergleiche praktisch Pixel für Pixel miteinander.
Dazu speicherst du jede Sekunde ein Bild und vergleichst es mit dem voherigen.
Ich habe mal eine kleine Routine geschrieben, der Code ist wohl aber nicht ganz optimal:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
function ComparePics: Boolean;
var
  x, y, count: integer;
  BM1, BM2: TBitmap;
begin
  Result := false;

  BM1 := TBitmap.Create;
  BM2 := TBitmap.Create;

  try
    BM1.LoadFromFile('d:\Unbenannt.bmp');   // deine beiden Bilder laden
    BM2.LoadFromFile('d:\Unbenannt_3.bmp'); 

    for x := 1 to BM1.Width - 1 do
      for y := 1 to BM2.Height - 1 do
        if (BM1.Canvas.Pixels[x, y] <> BM2.Canvas.Pixels[x, y]) then // Pixel vergleichen
          inc(count);

    if count > 100 then // ist die Toleranz an Pixeln größer als 100 ?
      result := True; // dann schlage Alarm 

  finally
    BM1.Free;
    BM2.Free;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 if comparepics then showmessage('Alarm!');
end;

Vielleicht hilft es dir weiter
grüße marc


Fabian E. - Mo 15.01.07 18:30

hmm... ok das sieht ja schon ganz gut aus...nur wie kann ich jetzt noch die helligkeit ins spiel bringen?in meinem zimma isses ja nich den ganzen tag gleich hell!
Vllt einfach imma die zwei neusten bilder nehem?reicht da die toleranz oder wird dann ein fremdkörper als helligkeit erkannt?hat jemad damit erfahrungen?

vielen dank!

Fabi


Phantom1 - Mo 15.01.07 20:55

Ich würde einen anderen Farbraum benutzen, denn RGB ist dafür ungeeignet. Am besten sollte es mit TSL gehen, folgend ein code von mir mit dem man ein Bild in TSL umrechnen kann:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
procedure RGBQuadToHSV(rgb: PRGBQuad; var H,S,V: Integer);
var Delta, Min: Integer;
begin
  with rgb^ do begin
    Min := MinIntValue([rgbRed, rgbGreen, rgbBlue]);
    V := MaxIntValue([rgbRed, rgbGreen, rgbBlue]);
  end;
  Delta := V - Min;
  if V = 0 then
    S := 0
  else
    S := MulDiv(Delta, 255, V);
  if S = 0 then
    H := 0
  else begin
    with rgb^ do
      if rgbRed = V then
        H := MulDiv(rgbGreen - rgbBlue, 60, Delta)
      else
        if rgbGreen = V then
          H := 120 + MulDiv(rgbBlue-rgbRed, 60, Delta)
        else
          if rgbBlue = V then
            H := 240 + MulDiv(rgbRed-rgbGreen, 60, Delta);
    if H < 0 then
      H := H + 360;
  end;
end;

procedure TSL(Bmp: TBitmap);
var
  x, h, s, v: Integer;
  p: PInteger;
begin
  Bmp.PixelFormat:=pf32bit;
  p:=Bmp.ScanLine[Bmp.Height-1];
  for x:=1 to Bmp.Width*Bmp.Height do begin
    RGBQuadToHSV(PRGBQuad(p), h, s, v);
    if (s<50or (v<50then begin
      if v>127 then
        p^:=$00FFFFFF  // White
      else
        p^:=$00000000// Black
    end else
      case h of
           0..30: p^:=$00FF0000// Red
          31..90: p^:=$00FFFF00// Yellow
         91..150: p^:=$0000FF00// Green
        151..210: p^:=$0000FFFF// Cyan
        211..270: p^:=$000000FF// Blue
        271..330: p^:=$00FF00FF// Magenta
        331..360: p^:=$00FF0000// Red
      end;
    Inc(p);
  end;
end;


mfg