Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi Pixelparty - oder das irre Projekt *seufz* (https://www.delphipraxis.net/58480-pixelparty-oder-das-irre-projekt-%2Aseufz%2A.html)

tretmine.net 7. Dez 2005 16:38


Pixelparty - oder das irre Projekt *seufz*
 
Hallo!

Ich habe relativ wenig Erfahrung mit Delphi. Bisher habe ich jedoch eigentlich alles mit meinen begrenztem Wissen irgendwie lösen können.
Nun stehe ich jedoch vor einem großen Problem:

Ich will ein Programm schreiben, welches einen Ausschnitt von meinem Bildschirm ständig im Auge behält. Ändern sich xyz-Pixel in der Zeitspanne abc, dann soll das Programm einem anderen Programm eine Anweisung geben.

Nun ist die Frage: Wie lese ich ein Pixel vom Bildschirm aus? Also den Farbwert.
Ich habe zwar in der Codebase etwas gefunden, aber das bezieht sich nur auf Images, oder?

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  dc: hDc;
begin
  dc := GetDC(0);
  Color := GetPixel(dc, x, y); //statt x und y, bitte Integer eingeben
  ReleaseDC(0, dc);
end;
Weiter wollte ich fragen: Ist das überhaupt realistisch? Also könnte es mit genug Engagement etwas werden, oder ist ein Ausschnitt, welcher ca. 5x5 cm groß ist, garnicht pixelweise zu betrachten?
Wie würdet ihr daran gehen?
Ich sitze gerade vor meinem Dephi und weiß eigentlich garnicht, wo ich anfangen soll. Plz helft mir.

Eine wirkliche "Bildanalyse, wie hier beschrieben: http://www.delphipraxis.net/internal...xel+bildschirm brauche ich nicht. Die Änderungsrate muss bei mir nur einen gewissen Schwellenwert (durch Probieren später herauszufinden) übersteigen.

Thx schon mal.

MfG Phil

P.S.: Ach ja, ich habe das ins Multimedia geschrieben, da ich eine "Spielzeug-"Kamera auslesen will, und etwas danach steuern will... Ich hoffe es ist richtig plaziert...

tretmine.net 7. Dez 2005 17:04

Re: Pixelparty - oder das irre Projekt *seufz*
 
Ok... Ich glaub ich habe es soweit zumindest mal einen pixel auszulesen... nun aber die Frage: wie mache ich ein TColor zu einem String o.ä.
Hört sich jetzt zwar sehr doof an, aber ich kann mir unter "TColor" nix vorstellen. Wie kann ich mir die Farbwerte anzeigen lassen?

MfG Phil

sh17 7. Dez 2005 17:09

Re: Pixelparty - oder das irre Projekt *seufz*
 
Ein TColor ist einfach nur ein Integer

Hast Du zwei Colorwerte eines Pixels des Bildschirms, dann vergleich sie einfach

tretmine.net 7. Dez 2005 17:12

Re: Pixelparty - oder das irre Projekt *seufz*
 
Ah... IntToStr... Du glaubst nicht, was ich alles probiert habe *lach*. Aber darauf bin ich nicht gekommen. Thx.

Ging schneller, als ich dachte. Zuerst bin ich 2 Stunden vor dem PC gesessen und hab nicht gewusst wo ich anfangen soll. Kaum klappt es mit diesem "GetPixel" und schon läuft es wie am Schnürchen... Thx

MfG Phl

ichbins 7. Dez 2005 17:32

Re: Pixelparty - oder das irre Projekt *seufz*
 
Hier eine Screenshot-Funktion:
Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
var
  i,i2:integer;
  b2:tbitmap;
  r:trect;
begin
  if not savedialog1.Execute then
    application.Terminate;
  b:=tbitmap.Create;
  b.Width:=screen.Width;
  b.Height:=screen.height;
  b.Canvas.handle:=GetWindowDC(GetDesktopWindow);
  b2:=tbitmap.Create;
  b2.Width:=screen.Width-1;      
  b2.Height:=screen.Height-1;
  sleep(100);
  b2.Canvas.CopyRect(screen.desktoprect,b.Canvas,screen.desktoprect);
  if savedialog1.filterindex=1 then
    b2.SaveToFile(savedialog1.filename) else
  begin
    j:=tjpegimage.create;
    form2:=tform2.Create(application);
    form2.showmodal;
    j.assign(b2);
    j.savetofile(savedialog1.FileName);
    j.free;
  end;
  application.terminate;
  b.free;
  b2.free;
end;
Hab ich mal geschrieben.

Kannst du ja einfach abwandeln. Statt screen.desktoprect nimmst du den zu beobachtenden Bildschirmbereich und statt der Speicherungsprozedur schreibst du eine Vergleichsprozedur.
Delphi-Quellcode:
var
  i,i2:integer;
  b,b2:tbitmap;
  r,zubeobachtenderbereich:trect;
begin
  zubeobachtenderbereich.left:=...;

  b:=tbitmap.Create;
  b.Width:=screen.Width;
  b.Height:=screen.height;
  b.Canvas.handle:=GetWindowDC(GetDesktopWindow);
  b2:=tbitmap.Create;
  b2.Width:=screen.Width-1;      
  b2.Height:=screen.Height-1;
  sleep(100);
  b2.Canvas.CopyRect(screen.desktoprect,b.Canvas,zubeobachtenderbereich);
  //Hier BMPs vergleichen
  b.free;
  b2.free;
end;

Nicolai1234 7. Dez 2005 17:42

Re: Pixelparty - oder das irre Projekt *seufz*
 
Darf man fragen, wofür das eigentlich genau benötigt wird? Eventuell ist eine soclhe Lösung gar nicht sinnvoll und etwas ressourcenschonenderes besser...

tretmine.net 7. Dez 2005 18:02

Re: Pixelparty - oder das irre Projekt *seufz*
 
Also...
Es gibt 2 Anwendungsbereiche.

1.
Mein Onkel, welcher sich leider eine Kamera ohne genau diese Funktion (die gibts manchmal schon integriert) gekauft hat, will seine Kasse und Lager damit überwachen. Dort sind leider größere Gottes Fehlbestände zu verzeichnen.
Diese werden mittels einer TV-Karte auf einem PC gespeichert. Nur ist eben das doofe: Es wird viel zu viel gespeichert *gg*.
Hier könnte man aber noch sagen: Pech, dann muss er sich eben ein anderes System kaufen, wobei es sehr schwierig ist eine Kamera mit Funkübertragung UND die oben erwähnte Funktion zu finden. Wobei ich immer noch der Meinung bin, dass eine zufällige Überprüfung und bei der Kasse ein konsequenteres Herausgeben des Schlüssels mehr Erfolg bringen würde.

2.
Ich will mir evtl. irgendwann solch eine Spielzeug-Kamera kaufen (wenn ich mal Geld habe ^^) und darüber etwas automatisch steuern. Sprich das Bild in verschiedene Felder aufteilen und nun etwas darüber automatisieren. Bei Fischertechnik gibts afaik so etwas auch.
Spielerei, aber der Mensch lebt nicht nur von bierernstem Schaffen.
Das ist eigentlich mein Hauptantrieb.

3.
Ich wollte eigentlich immer schon einmal wissen, wie man so etwas macht. Also rein interessenhalber mal nicht "nur" kleine Programme schreiben, die nur etwas hin- und herschreiben, sondern auch mal etwas diffuses und schwer fassbares (wann ändert sich ein Bild?!?) schreiben.

MfG Phil

ichbins 7. Dez 2005 18:06

Re: Pixelparty - oder das irre Projekt *seufz*
 
Dann wird der Vergleich schwieriger. Denn die Pixel ändern sich dauernd (Helligkeitsschwankungen etc...)

Oxmyx 7. Dez 2005 18:12

Re: Pixelparty - oder das irre Projekt *seufz*
 
Du hast jetzt aber nicht wirklich die TColor-Werte in Strings umgewandelt, um sie zu vergleichen?

ichbins 7. Dez 2005 18:19

Re: Pixelparty - oder das irre Projekt *seufz*
 
Du müsstest die RGB-Werte extrahieren und dann vergleichen ob der Unterschied zum vorherigen Wert höher als beispielsweise 64 ist. Wenn ja, inkrementierst du einen Zähler.

Wenn sich der Farbton dann bei mehr als beispielsweise 1024 Pixeln gleichzeitig verändert hat, schlägst du Alarm. Diese Berechnungsmethode benötigt allerdings seeeeeeeeeeeeeeehr viel Zeit.

Deshalb habe ich hier eine Funktion geschrieben (ursprünglich sollte sie entscheiden ob ein Bitmap nun schwarzweiss ist), die nur ein Gitter von 100 Probepixeln vergleicht:

Delphi-Quellcode:
function pos(i:integer):integer;
begin
  if i<0 then result:=-i else result:=i;
end;

function changed(old,new:tbitmap):boolean;
var
  i,j,counter,rold,gold,bold,rnew,gnew,bnew:integer;
  pixold,pixnew:tcolor;
begin
  counter:=0;
  for i:=1 to 10 do
    for j:=1 to 10 do
    begin
      pixold:=old.Canvas.Pixels[((old.Width*i) div 10)-(old.Width div 20),((old.Height*j) div 10)-(old.Height div 20)];
      pixnew:=new.Canvas.Pixels[((new.Width*i) div 10)-(new.Width div 20),((new.Height*j) div 10)-(new.Height div 20)];
      bold:=(pixold shr 16) and $FF;
      gold:=(pixold shr 8) and $FF;
      rold:=(pixold and $FF);
      bnew:=(pixnew shr 16) and $FF;
      gnew:=(pixnew shr 8) and $FF;
      rnew:=(pixnew and $FF);
      if pos(bold-bnew)+pos(gold-gnew)+pos(rold-rnew)>=64*3 then
        inc(counter);
    end;
  if counter>10 then
    ALARMSCHLAGEN, da sich die Farbe von 10% der Pixel des Bildes um mehr als 1/4 geändert hat.
end;

tretmine.net 7. Dez 2005 18:40

Re: Pixelparty - oder das irre Projekt *seufz*
 
wg Umwandlung:
neeee... aber das brauch ich um mal ein Gefühl zu bekommen, was überhaupt hinter TColor steckt und wie es sich verändert, wenn sich das Bild ändert.

wg. Snapshot.
Danke noch für den Quelltext! Brachte mir viel, auch wenn irgendwas nicht klappt. Ich glaube es liegt an dem TRect. Das ist doch ein Rechteck, oder? Ich kann aber nur Integers einfügen. Wenn ich nun z.B. 220 testweise rein schreib und b2.SaveToFile('c:\file.bmp'); vor dem "b.free" hin schreibe, dann bekomm ich ein leeres Bitmap... *grübel*
Ich habs danach so probiert:

Delphi-Quellcode:
zubeobachtenderbereich.left:=220;
  zubeobachtenderbereich.top:=220;
Jetzt speichert er zwar etwas, jedoch ist das spiegelverkehrt und gleichzeitig gezerrt. Ich versteh die Welt nicht mehr.



Und zu IchBins: Du bist wiklich göttlich! Danke! Das bringt mich ca. 3 Stunden Arbeit weiter... wow!



MfG Phil

ichbins 7. Dez 2005 18:42

Re: Pixelparty - oder das irre Projekt *seufz*
 
du musst ja außer left und top auch noch bottom und right setzten.

:angel: :mrgreen:

Nicolai1234 7. Dez 2005 18:50

Re: Pixelparty - oder das irre Projekt *seufz*
 
Zitat:

Zitat von tretmine.net
Also...
Es gibt 2 Anwendungsbereiche.

1.
Mein Onkel, welcher sich leider eine Kamera ohne genau diese Funktion (die gibts manchmal schon integriert) gekauft hat, will seine Kasse und Lager damit überwachen. Dort sind leider größere Gottes Fehlbestände zu verzeichnen.
Diese werden mittels einer TV-Karte auf einem PC gespeichert. Nur ist eben das doofe: Es wird viel zu viel gespeichert *gg*.
Hier könnte man aber noch sagen: Pech, dann muss er sich eben ein anderes System kaufen, wobei es sehr schwierig ist eine Kamera mit Funkübertragung UND die oben erwähnte Funktion zu finden. Wobei ich immer noch der Meinung bin, dass eine zufällige Überprüfung und bei der Kasse ein konsequenteres Herausgeben des Schlüssels mehr Erfolg bringen würde.

2.
Ich will mir evtl. irgendwann solch eine Spielzeug-Kamera kaufen (wenn ich mal Geld habe ^^) und darüber etwas automatisch steuern. Sprich das Bild in verschiedene Felder aufteilen und nun etwas darüber automatisieren. Bei Fischertechnik gibts afaik so etwas auch.
Spielerei, aber der Mensch lebt nicht nur von bierernstem Schaffen.
Das ist eigentlich mein Hauptantrieb.

3.
Ich wollte eigentlich immer schon einmal wissen, wie man so etwas macht. Also rein interessenhalber mal nicht "nur" kleine Programme schreiben, die nur etwas hin- und herschreiben, sondern auch mal etwas diffuses und schwer fassbares (wann ändert sich ein Bild?!?) schreiben.

MfG Phil

Wäre es dann nicht besser, sich das Bild direkt von der Kamera zu holen und es nicht vom Bildschirm abzuzeichnen?

tretmine.net 7. Dez 2005 18:56

Re: Pixelparty - oder das irre Projekt *seufz*
 
aso... das weiß ich ja nicht *lach*

Ne, Das Teil übergibt das in Pal oder NTSC an die TV-Karte. Und da liegt der Hund begraben... Um diese Formate jemals zu verstehen, bräuchte ich wohl Jahre.
Und ein paar weniger Resourcen auf nem GeschäftsPC sind nicht wirklich schlimm.

MfG Phil

tretmine.net 7. Dez 2005 19:04

Re: Pixelparty - oder das irre Projekt *seufz*
 
Thx an alle... Ich glaub ich schaff das jetzt alleine (will ja etwas dabei noch lernen). Die Screens gehen nun auch so, wie ich mir das vorstelle... THX!

MfG Phil, der gedacht hätte, dass er wohl mind. 2 Wochen da dran sitzt...

-NIP- 7. Dez 2005 19:08

Re: Pixelparty - oder das irre Projekt *seufz*
 
Ein paar ist gut :lol: .
Wie oft willst du das denn überprüfen? Pro Sekunde einmal?
Und wenn du beispielsweise das vom Bildschirm ablesen willst, dann müsste ja das Kameraprogramm ständig im Vordergrund laufen.

Khabarakh 7. Dez 2005 19:21

Re: Pixelparty - oder das irre Projekt *seufz*
 
Zitat:

Delphi-Quellcode:
function pos(i:integer):integer;
begin
  if i<0 then result:=-i else result:=i;
end;

Delphi-Referenz durchsuchenAbs :wink:
Wenn man statt Pixels Delphi-Referenz durchsuchenScanline benutzt, sollte der Code noch einmal um einiges schneller werden.

Airblader 7. Dez 2005 20:19

Re: Pixelparty - oder das irre Projekt *seufz*
 
:shock:
Und dann Variablennamen, die einem auch was sagen, wären doch ein guter Anfang @ichbins (auch wenn es nichts allzu Schlimmes ist...aber mit solchen Variablen würde ich nicht leben können ;) )

air

Khabarakh 7. Dez 2005 20:39

Re: Pixelparty - oder das irre Projekt *seufz*
 
Da finde ich dieses notorische Kleinschreiben schlimmer :mrgreen: . Mit Camel- oder PascalCaps sind wären die Namen der Kanal-Bytes um einiges leichter zu lesen.
Code:
[s]gold[/s]
GOld
[i]oder[/i]
gOld

tretmine.net 7. Dez 2005 22:33

Re: Pixelparty - oder das irre Projekt *seufz*
 
Ich glaune ich kanns vergessen...
Der ScreenShot-Quelltext, sowe auch GetPixel sehen ein Video als schwarze Fläche. Wird also nicht berücksichtigt. Schade :(((
Somit kann ich alles in die Tonne werfen, oder?

MfG Phil

Luckie 8. Dez 2005 00:22

Re: Pixelparty - oder das irre Projekt *seufz*
 
Zitat:

Zitat von tretmine.net
Ich will ein Programm schreiben, welches einen Ausschnitt von meinem Bildschirm ständig im Auge behält. Ändern sich xyz-Pixel in der Zeitspanne abc, dann soll das Programm einem anderen Programm eine Anweisung geben.

Was willst du den eigentlich mache? Ich glaube nämlich, du gehst falsch an das Problem ran.

bate 8. Dez 2005 07:49

Re: Pixelparty - oder das irre Projekt *seufz*
 
Hi,

liegt nicht immer bei jeder Webcam so ne Software bei die nen Event auslöst wenn sich etwas in einem bestimmten Feld (Rechteck) bewegt? Sollte das nicht einfacher sein?


P.S. Video's werden in den Framebuffer geschrieben (ausgegeben) sprich du kannst sie nicht direkt abfragen.

tretmine.net 8. Dez 2005 11:03

Re: Pixelparty - oder das irre Projekt *seufz*
 
@Lukie:

Der Thread ist verdammt unübersichtlich geworden. In Beitrag Nr. 7 Seite 1 hab ich es nochmal hingeschrieben.

@bate:

Ne, das ist nicht dabei. Da war überhaupt keine Software dabei. Das ist ja das Problem. Und die Software der TV-Karte (InterVideo WinDVR) kann das nicht.

MfG Phil

tretmine.net 8. Dez 2005 11:11

Re: Pixelparty - oder das irre Projekt *seufz*
 
EDIT:
Geht evtl. doch... Dieses Proggi schafft es auch:
http://www.delphipraxis.net/internal...hlight=tvkarte

Ach btw.:
Ich wäre gestern fast ausgerastet, weil ich es nicht geschafft habe, die function changed aufzurufen. Am liebsten hätte ich in mein Mousepad gebissen.
Bis im IRC mich jemand darauf aufmerksam machte, dass ich die function mal umbenennen sollte. *arrrr*

Jetzt saß ich da ewig dran, probierte wirklich ALLES und verzweifelte an mir selbst (so ein Noob bin ich doch auch nicht).
Und dann liegt es an so einem Käse.

MfG Phil

tretmine.net 9. Dez 2005 11:23

Re: Pixelparty - oder das irre Projekt *seufz*
 
Hmmm... Jetzt trat ein größeres (unlösbares?!?) Problem auf, welches mich doch sehr beschäftigt.
Dieses "VideoCapture" ist ja relativ genial. Nur hat es ein Problem:
Ich kann mit

Delphi-Quellcode:
CapSetSingleImageFileName(PathAndFilename);
CapGrabSingleFrame;
CapSetVideoLive;
zwar ein Bild Schießen und es als *.bmp in einem Ordner speichern. Doch bringt mir das überhaupt nichts. Durch das Schreiben auf der Platte und das relativ zeitnah folgende Lesen der Datei um es zu Vergleichen, bringt, so vermute ich, Kuddelmuddel auf der Festplatte. Bevor er es geschrieben hat, muss er es auch schon wieder lesen. -> EAccessViolation. Ich brauche aber kurze Zeitabstände. Sonst bringt mir das alles nichts.

Nun habe ich dieses erst einmal mit einem Screenshot gelöst, was wunderbar funktioniert. Das blöde hierbei ist: Das Program muss ständig im Vordergrund oben links im Bildschirm sein. Sonst macht es einen Screen vom falschen Ausschnitt.

Natürlich ist mir der Gedanke gekommen über das CapGrapSingelFrame dies sofort einem TBitmap o.ä. zuzuweißen. Ja, das beschäftigte mich sogar die ganze Nacht... *grml* Das blöde ist, dass er dieses Cap[...] als "Undeclared identifier" nur anerkennt.
Nun habe ich es leider nicht geschafft. Meine einzigste Hoffnung liegt in TBitmap.LoadFromStream, LoadFromResourceID und LoadFromResourceName, welches ich aber beim besten Willen nicht verstanden habe, wie dies fuktioniert. Ich glaube, dass dies mir zu hoch ist...

Hätte jemand eine Idee, wie man aus dem Cap ein Bitmap macht, ohne es vorher auf Platte zu schreiben?

MfG Phil

1ceman 16. Dez 2005 20:17

Re: Pixelparty - oder das irre Projekt *seufz*
 
Davon,hab ich zwar kene Ahnung, aber damit dein Vater schon mal überwachen kann, such doch mal
bei google nach nem prog, da gibt es bestimmt ein programm, was nur das video aufzeichnet wenn sich
was bewegt.(das ist doch das was du willst oder?)
und dann kannste ja selber mit delphi, um was zu lernen(ohne zeitdruck), son program schreiben.


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