Autor Beitrag
deki
Hält's aus hier
Beiträge: 10



BeitragVerfasst: Sa 05.05.07 20:53 
Guten Tag,

ich arbeite im Moment an folgendem Projekt:

Über eine Webcam wird die Bewegung eines schwarzen Balls auf einer weißen Platte aufgenommen. Es soll der "Aufschlagpunkt" (wo der Ball das Ende der Platte erreicht) und die Geschwindigkeit des Balles bestimmt werden. Mit diesen Daten wird ein Roboter gesteuert, der einen Korb am Ende der Platte so verschiebt, dass der Ball in diesen hineinfällt.

Dieses Projekt ist für mich sehr aufwendig, deswegen erhoffe ich mir ein wenig Hilfe. Klar, dass ihr mir nicht das Programm schreiben werdet, aber zumindest wie man die Sache angehen kann, möchte ich vorher einmal besprechen.

Bisher habe ich also die Webcam quasi als "Live-Stream" in mein Programm eingebunden. Über einen Timer werden immer zwei Bilder gemacht, die auf RGB-Werte überprüft werden, woraus sich die Positon des Balles ermitteln lässt. (Zeigt mir die RGB-Auswertung den Mittelpunkt des Balles?) Leider ist dieser Vorgang insgesamt ziemlich langsam. Im Moment speichere ich ein Bild, lade es dann in ein "Image-Fenster" und werte es dann aus. Geht das schneller? Sonst gibt es wohl später Probleme bei schnellen Bewegungen.

Nun habe ich also zwei X- und Y-Werte, aus denen ich den Aufschlagspunkt berechnen möchte. Kann ich das einfach über eine lineare Funktion machen? Also (delta x)/(delta y)? Oder gibt es auch hier eine einfachere Methode?

Zuletzt muss ja auch die Postion des Korbes berechnet werden, soll ich diesem eine andere Farbe geben und ihn auch über die RGB-Werte bestimmen?

Danke für jede Hilfe und bei Unverständlichkeiten einfach an mich wenden.
Einloggen, um Attachments anzusehen!
klezmor
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 558


delphi 6 personal delphi 2005 personal
BeitragVerfasst: Sa 05.05.07 21:02 
Willst du die ganze sache in Delphi machen? Wenn c++ eine alternative wäre, dann könnte ich dir wärmstens die opencv Bibliothek von Intel, damit hättest du einige grundlegende Funktionen welche für Bildverarbeitung notwendig sind schon implementiert.
Die bibliothek ist außerdem ziemlich schnell.

_________________
"Beware of bugs in the above code; I have only proved it correct, not tried it." Donald Knuth
deki Threadstarter
Hält's aus hier
Beiträge: 10



BeitragVerfasst: Sa 05.05.07 21:09 
Ich würde das auch in C++ schreiben, dabei bräuchte ich aber dementsprechend ein bisschen Nachhilfe. Es gibt doch bei C++ keine visuellen Komponenten wie bei Delphi oder? Also wenn ich in die Richtung ein paar Hinweise bekomm, steig ich gerne auf C um, zugunsten der Schnelligkeit.
klezmor
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 558


delphi 6 personal delphi 2005 personal
BeitragVerfasst: Sa 05.05.07 21:41 
Also das ist schon mal ein ganz positiver ansatz.
In der von mir genannten Bibliothek ist schon ein kleineres GUI eingebaut.
Heißt du kannst bilder anzeigen, striche malen, es gibt mousehandler und du kannst sogar Trackbars verwenden.
Wenn dir das allerdings nicht reichen sollte, dann würde ich dir empfehlen den Borland C++ Builder zu verwenden, ist genau das selbe wie Delphi, da findest du dich instinktiv sofort zurecht und kannst dennoch die Library einbinden.
Als erstes solltest du einfach mal das neuste release hier herunterladen.
Schau dir einfach die beispiele an, der müsste deine webcam sogar automatisch erkennen.
Möglicherweise kennst du die Darpa Challenge, da fährt in amerika ein führerloses Fahrzeug durch die Wüste und sollt den Weg allein durch sensoren und Kameras finden.
Der Gewinner der Challenge verwendete für seine Kameras auch die besagte Bibliothek.
Es gibt sogar ein programm, wo object Tracking schon implementiert ist :D .
Die Bibliothek ist außerdem auf dem neusten Stand der Forschung und wird kontinuierlich
weiterentwickelt.

_________________
"Beware of bugs in the above code; I have only proved it correct, not tried it." Donald Knuth
deki Threadstarter
Hält's aus hier
Beiträge: 10



BeitragVerfasst: So 06.05.07 18:57 
Also dieses Wüstenrennen kannt ich bis jetzt noch nicht, aber man muss ja immer Ziele haben. ;)
Ich suche gerade Borland C++ Builder und finde verschiedenste Versionen. Welche ist richtig und wo gibt es freie Downloads?
klezmor
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 558


delphi 6 personal delphi 2005 personal
BeitragVerfasst: So 06.05.07 19:53 
Also da hab ich keine ahnung meine version ist jetzt schon ziemlich alt(ca. 5 jahre).
Ich weiß leider nicht mehr wo es eine personal kostenlos zum download gibt, bzw. könnte es sein, dass es sie gar nciht mehr gibt(Borland bietet z.b. auch keine delphi6 pe mehr an).
Wie gesagt ist der Borland C++ Builder nicht unbedingt notwendig.
Du kannst die GUI auch über einen anderen Weg implementieren.
Es unter anderem gäbe folgende Möglichkeiten:
1. Nur OpenCV, dort ist wie gesagt schon eine GUI namens Highgui dabei.
Dies anzuwenden ist halt ein wenig aufwendiger als der C++ Builder, dafür vollständig
plattformunabhängig, sprich kannst das ganze auch unter mac und linux laufen lassen.
2. QT ist auch eine OpenSource GUI-Bibliothek, ist allerdings nicht ganz so komfortabel,
wie Delphi bzw. der Builder.
3. Es gibt natürlich auch sonst zahlreiche Bibliotheken welche eine GUI zur Verfügung stellen stellen. Beim dev c++ gibt es ein package namens RAD c++, basiert glaub vollständig auf der Winapi.
4. Du verwendest die WinApi selbst um das GUI zu erstellen, ist allerdings ziemlich aufwendig, müsstest du dich an luckie wenden, der kennt sich da sehr gut aus.
5. zahlreiche weitere Methoden..... :)

_________________
"Beware of bugs in the above code; I have only proved it correct, not tried it." Donald Knuth
deki Threadstarter
Hält's aus hier
Beiträge: 10



BeitragVerfasst: Mo 07.05.07 15:39 
Also die OpenCV Library sieht schon ziemlich komplex aus, dazu kommt noch, dass mir bei Start eines Samples die Datei "cxcore100.dll" als fehlend gemeldet wird.

Gibt es nichts was näher an Delphi ist, so das ich damit klar komm. ;)

Was ist zum Beispiel hiermit: www.bloodshed.net/dev/devcpp.html ? Der letzte Download sagt etwas mit "Delphi Source".

Also die OpenCV alleine ist glaub ich nichts für mich als Anfänger mit C++.
GTA-Place
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
EE-Regisseur
Beiträge: 5248
Erhaltene Danke: 2

WIN XP, IE 7, FF 2.0
Delphi 7, Lazarus
BeitragVerfasst: Mo 07.05.07 15:50 
Entweder DevC++ (mit Delphi programmiert :lol:), Turbo C++ (BDS 2006, sieht wie Delphi aus) oder MS Visual Studio (da Hinweise auf der Website bezüglich Win32 beachten).

_________________
"Wer Ego-Shooter Killerspiele nennt, muss konsequenterweise jeden Horrorstreifen als Killerfilm bezeichnen." (Zeit.de)
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Di 08.05.07 06:02 
Warum meinen immer alle, C sei schneller als Delphi? Ich kann auch mit einer Sprache, deren Compiler besser optimiert ineffizienteren Code schreiben ... Und zum Tracken eines Balls brauch ich weiß Gott nicht High-Performance mit C und ner ASM-optimierten Bibliothek ... Mit ein wenig Ahnung von Bildverarbeitung sind das genau 3 Schritte:
1. Helligkeitssegmentierung des Bildes
2. Objektlokalisation (kann man sogar im ersten Schritt mit integrieren ...
3. Form-Erkennung (um zu prüfen, dass da wirklich ein Ball rollt und kein Quadrat :P)
Spätestens nach dem zweiten Schritt hab ich die Koordinaten und kann anhand der Deltas und der Delays der Bilder den Weg approximieren.

Und wenn ich das richtig in Erinnerung hab: wenige als 300 Zeilen (Delphi-)Source (unoptimiert) ... Hab nur grad zu viel zu tun, um das zu schreiben ... Manchmal muss ich auch kurz nebenbei studieren ;-) An der Uni machen wir nämlich in Bildverarbeitung nichts anderes ... und da nutzen wir Delphi - auch wenn wir ein Framework haben, wo uns ggf. einige Dinge abgenommen werden).

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
deki Threadstarter
Hält's aus hier
Beiträge: 10



BeitragVerfasst: Di 08.05.07 13:19 
Ja das hab ich im Moment, nur, dass ich die Formenerkennung nicht brauche, weil da bestimmt nichts anderes als ein Ball rollt. Ich hab eine Helligkeitserkennung über RGB-Werte und somit auch kein Problem die Koordinaten des Balles zu bestimmen. Wie ich dann den Aufschlagspunkt berechne ist mir auch klar.

Mein Problem ist nur, dass das Speichern eines Bildes vom Video-Stream, dann das Wideraufrufen und überprüfen der Helligkeitswerte sehr lange dauert, zu lange, um damit eine flüssige Bewegung aufzunehmen.

ausblenden volle Höhe 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:
57:
58:
procedure TForm1.BildTimerTimer(Sender: TObject);
begin
     BildMachen(IntToStr(i));
     button1.Click;
     i:=i+1;
     BildMachen(IntToStr(i+1));
     button1.Click;

     if i = 2 then
        begin
          BildTimer.Enabled:= False;
          i:=1;
        end

end;  


procedure TForm1.BildMachen(Name: string);
var
  Dateiname : string;
begin
     Dateiname:= ExtractFilePath(ParamStr(0)) + IntToStr(i) + '.bmp';
     CapSetSingleImageFileName( Dateiname );
     CapGrabSingleFrame;
     CapSetVideoLive;
     image1.Picture.LoadFromFile(path+IntToStr(i)+'.bmp');

end;


procedure TForm1.Button1Click(Sender: TObject);
begin
x := 0;
y := 1;
while y+2<image1.Height do
 begin
  while x+2<image1.Width do
   begin
    x := x+2;
    if (GetRValue(image1.Canvas.Pixels[x,y])<50) and (GetGValue(image1.Canvas.Pixels[x,y])<50) and (GetBValue(image1.Canvas.Pixels[x,y])<50) then
     begin
      xpossumme := xpossumme+x;
      xsumme := xsumme+1;
      ypossumme := ypossumme+y;
      ysumme := ysumme+1;
     end
   end;
    x := 0;
    y := y+2;
 end;
xpos := Round(xpossumme/xsumme);
ypos := Round(ypossumme/ysumme);
if i=1 then begin
edit1.Text := 'x= '+InttoStr(xpos)+';  y= '+InttoStr(ypos);
end
else if i=2 then
edit2.Text := 'x= '+InttoStr(xpos)+';  y= '+InttoStr(ypos);
end;


Moderiert von user profile iconmatze: Code- durch Delphi-Tags ersetzt
deki Threadstarter
Hält's aus hier
Beiträge: 10



BeitragVerfasst: Di 08.05.07 19:25 
Kann sich den Code nicht mal einer angucken?

*schieb*

Edit: Hab gerade etwas quer gelesen und gesehen, dass man anstatt der canvas.pixel methode etwas anderes, bsp. scanline einbinden kann. Wie macht man das? Brauche ich dafür eine extra Lib?
jakobwenzel
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1889
Erhaltene Danke: 1

XP home, ubuntu
BDS 2006 Prof
BeitragVerfasst: Di 08.05.07 20:45 
user profile icondeki hat folgendes geschrieben:
Edit: Hab gerade etwas quer gelesen und gesehen, dass man anstatt der canvas.pixel methode etwas anderes, bsp. scanline einbinden kann. Wie macht man das? Brauche ich dafür eine extra Lib?

Nein, aber die Forumssuche :wink:

_________________
I thought what I'd do was, I'd pretend I was one of those deaf-mutes.
deki Threadstarter
Hält's aus hier
Beiträge: 10



BeitragVerfasst: Di 08.05.07 20:46 
Ist der Code denn danach schnell genug? Sind noch andere Sachen zu verbessern?
Sinspin
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1340
Erhaltene Danke: 120

Win 10
RIO, CE, Lazarus
BeitragVerfasst: Di 08.05.07 22:59 
mit scanlines wird der code deutlich fixer. ich habe mal ein bildanalyseprogramm geschrieben das ein 4 MB großes grauwert bild das ein sehr feines muster enthielt analysiert hat und die löcher in dem raster gezählt hat. und das ganze in null komma nix!

_________________
Wir zerstören die Natur und Wälder der Erde. Wir töten wilde Tiere für Trophäen. Wir produzieren Lebewesen als Massenware um sie nach wenigen Monaten zu töten. Warum sollte unser aller Mutter, die Natur, nicht die gleichen Rechte haben?
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Do 10.05.07 09:53 
Hier mal so, was ich auf Anhieb sehe ...

1. Nur ein Bild im Timer machen. Das Referenzbild kann man vom vorigen Durchlauf hernehmen ...

2. Nicht auf Platte capturen, sondern in einen Speicherblock: Die Festplatte IST langsam. Bei 320*240px hast Du etwa 250kB zu verarbeiten, wofür heutige Festplatten ca 10ms (incl. 6ms Suchzeit) benötigen. Der RAM ist da um einiges schneller

3. Nicht Canvas.Pixels verwenden, sondern das Bild direkt scannen. Dazu brauchst Du ein Bitmap, was Du aber durch einen RAM-Capture sowieso bekommst

4. Unnötige Objekt-Zugriffe vermeiden. Anstatt also Image1.Picture.Bitmap.Canvas zuzugreifen: Merk Dir die Referenzen, die du häufig brauchst in Variablen und verwende diese als Alias

5. Unnötige Funktionsaufrufe und Konvertierungen vermeiden. Anstatt einen RGB-Wert über die Funktion GetRValue usw. zu zerlegen:
(Speicherbyte1 or Speicherbyte2 or Speicherbyte3) <= 31 wobei Du die Speicherbytes allein mit Shifting bekommst ...

6. Verwende nicht Canvas.Pixels, sondern Bitmap.Scanline ... Ist um EINIGES schneller.

Hab mir den Source aber nicht näher angeschaut ...

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
Horst_H
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1654
Erhaltene Danke: 244

WIN10,PuppyLinux
FreePascal,Lazarus
BeitragVerfasst: Do 10.05.07 11:50 
Hallo,

das erstellen der Datei wird nicht allzuviel Zeit kosten, das es erstmal im FestplattenCache landet und auch von dort abgeholt wird ~700 Mb/s bei mir.
Aber egal, ohne den Umweg über die Festplatte wird sicher schneller sein.

Vielleicht ist dieser Beitrag www.delphi-forum.de/viewtopic.php?t=65518 etwas konstruktiver ;-)
Dort werden die HSL werte gegen Schwellenwerte verglichen.Das geht ja entsprechend für RGB Werte.
Bei 640x480 px in 200 ms (Welcher Rechner??).Dann müßte 320x240 px ja in 50 ms fertig sein.
Man könnte also aus dem Bild eine Schwellwertmaske erstellen, die nur 0 oder 1(oder 255) an den entsprechenden Stellen enthält.

Um die Kugel zu finden könnte man ja auch intervallschachteln, indem man den etwas weniger als den Durchmesser der Kugel als Zeilensprungmass nimmt, wobei die Frage ist, bleibt die Kugel auf dem Bild in konstanter Größe.
Oder ganz einfach, ersteinmal richtig suchen und dann nur noch in der Nähe zu der vorherigen Position.
Also vom alten Mittelpunkt ausgehen und von links>Mittelpunkt>rechts und von oben>Mittelpunkt>unten die Sehnenabschnitte bestimmen und daraus den neuen Mittelpunkt berechnen.
Als kleine Verbesserung hilft vielleicht die Suche in der vorherigen Bewegungsrichtung und senkrecht dazu.

Gruß Horst
deki Threadstarter
Hält's aus hier
Beiträge: 10



BeitragVerfasst: Fr 11.05.07 14:19 
Hallo,

Ich habe jetzt schon einmal Canvas.Pixel durch Scanline ersetzt - das Programm läuft nun um einiges schneller.
Wie funktioniert das RAM-Capture?


Edit:

Wie steuer ich eigentlich, sobald ich den Aufschlagpunkt des Balls kenne, am besten den Roboter an? Soll ich den Korb auch tracken lassen und solange verschieben bis seine Koordinaten mit denen dse Aufschlagspunkt übereinstimmen? Also in etwa eine "do...until" Schleife.

Oder soll ich eine Abhängigkeit zwischen Ansteuerungsdauer des Motors und zurückgelegte Strecke des Korbs herstellen und somit auf ein zweites Objekt zum Tracken verzichten?
deki Threadstarter
Hält's aus hier
Beiträge: 10



BeitragVerfasst: Mo 14.05.07 22:03 
*schieb*
Sinspin
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1340
Erhaltene Danke: 120

Win 10
RIO, CE, Lazarus
BeitragVerfasst: Mo 14.05.07 22:40 
was für einen motor hast du? einen schritt oder linearmotor? wenn ja, gibt es bei den meißten treibern für die motoren eine angabe wie weit der motor drehen soll (auch wieviele runden) das wird glaub ich in "winkel" angegeben.
ansonsten den motor mal laufen lassen und mit einem bandmaß oder was ähnlichem probieren wie weit er in einer bestimmten zeit kommt. wenn das nach einigen versuchen immer zum gleichen ergebnis führt kannst du über die betriebszeit ausrechnen wo sich der korb befinden muss.

_________________
Wir zerstören die Natur und Wälder der Erde. Wir töten wilde Tiere für Trophäen. Wir produzieren Lebewesen als Massenware um sie nach wenigen Monaten zu töten. Warum sollte unser aller Mutter, die Natur, nicht die gleichen Rechte haben?
Matthias
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 121



BeitragVerfasst: Mi 16.05.07 11:08 
Hallo,

so wie ich das sehe benutzt Du VFW. Hast Du die Schnittstelle direkt programmiert oder verwendest Du eine Komponente?
Bei VFW gibt es ein Callbackfunktion, die bei jedem neu erfassten Bild aufgerufen wird. Als Ergebnis bekommst Du einen
Framebuffer. Hierbei handelt es sich um eine DIB, die in eine Bitmap umgeandelt werden kann.

In der VFW Komponente von J. Hübler ist diese Vorghensweise inklusive Beispiel bereits integriert.

cu
Matthias