Autor Beitrag
Heiko
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3169
Erhaltene Danke: 11



BeitragVerfasst: Do 25.01.07 09:25 
moin moin,

ich arbeite im PRaktkum gerade an einer Positionsbestimmung eines Roboters mit Hilfe von Auswertung von WebCam bildern. An die Bilder bin ich jetzt direkt per WinAPI gekommen, allerdings nicht ganz so, wie ich es braiche :(. Und zwar liefert die API nur dann die Bilder, wenn mein Form zu sehen ist. Und die alternative dazu wäre, das aktuelle Bild von der APi auf der Platte speichern zu lassen und dann wieder einzulesen und dann erst auswerten. Und diesen Umweg über die Platte möchte ich nicht machen. Weiß einer von euch zufällig wie die richtige API dazu heißt, denn mit dem IE5 ist ein vernünftiger Besuch bei MSDN leider nicht möglich (der macht da nur Schrott...), so dass eine Suche nach der richtigen APi schwer ist?

Momentan mache ich es so:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
procedure ...FormCreate(...);
begin
  ...
  CapHandle:=capCreateCaptureWindow(...);
  SendMessage(CapHandle, WM_CAP_DRIVER_CONNECT, 0, 0);
  SendMessage(CapHandle, WM_CAP_SET_CALLBACK_FRAME, 0, Integer(@OnFrame));
  SendMessage(CapHandle, WM_CAP_SET_PREVIEWRATE, 1, 0);
  ..
end;


ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
function OnFrame(hCapWnd: HWND; lpVHDR: PVideoHDR);
begin
  //Hier ist meine Bildauswertung
  ...
  Image1.Refresh;//um nächstes bild abzuholen - nur ist das nicht ne Rekusion???
end;


Mir ist vor allem das mit OnFrame wichtig, denn über dessen 2. Parameter bekomme ich das Bild ausm Speicher.
nivosta
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 35



BeitragVerfasst: Do 25.01.07 09:36 
Hi,

das du nur Bilder bekommst liegt wahrscheinlich daran dass das Image1.Refresh nur durchgeführt wird wenn der Inhalt des Fensters neu gezeichnet werden muss. Dieses ist nicht der Fall wenn das Image nicht zu sehen ist dann bekommt es keine Message zum neu Zeichen. Die WinApi Funktion müste aber einen Aufrufparameter haben der unabhängig von dem Neuzeichnen des Image ist.


//Edit hier noch ein tipp

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
function OnFrame(hCapWnd: HWND; lpVHDR: PVideoHDR);
begin
  //Hier ist meine Bildauswertung
  ...
  //del 
    // Image1.Refresh;//um nächstes bild abzuholen - nur ist das nicht ne Rekusion???

 //ins
    capGrabFrame(hCapWnd); // Erneuter aufruf von OnFrame

end;


Gruß
Hubert
Heiko Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3169
Erhaltene Danke: 11



BeitragVerfasst: Do 25.01.07 10:01 
Das mit CapFrame funzt irgendwie nicht :(. Wenn mein Febster hinter Delphi ist, springt mein Haltepunkt nicht mehr an... .Wenn das Fenster vorne ist, funktioniert es allerdings, auch wenn er dann nichts mehr zeichnet (aber durchgehen tut er den Code trotzdem) - ist also ein bissl seltsam.

Und wenn ich statt SendMessage(hCapWND, WM_CAP_GRAB_FRAME, 0, 0) PostMessage nehme, damit keine Rekusion entsteht. Bleibt mein Form gleich grau - ich bekomme als gar keinen Frame zu sehen, während ich bei SendMessage noch den Startframe gesehen habe...
nivosta
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 35



BeitragVerfasst: Do 25.01.07 10:21 
so mal ein ausschnitt

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
procedure ...FormCreate...
begin
   hWndC = capCreateCaptureWindow("Capture Window", WS_CHILD | WS_DLGFRAME,
   m_rectFrame.TopLeft().x, m_rectFrame.TopLeft().y,
   m_rectFrame.Width(), m_rectFrame.Height(),
   GetSafeHwnd(), 1);//Set a capture window
   capDriverConnect (hWndC, 0);//connect to cammera's driver.
end;

procedure ...OnTimer()
begin

   capGrabFrame(hWndC); // simple macro that sample a single frame from the  camera.
   capEditCopy(hWndC);  // simple macro that edit a copy of the frame.
   OpenClipboard();     //like virtual memory.
 
   //m_hBmp is a Handle to Bitmap.
   m_hBmp = GetClipboardData(CF_BITMAP); 
   CloseClipboard();

end;


Entspricht nicht ganz Delphi einige Funktionsaufrufe für Clipboard must du wahrscheinlich ändern.

Hier noch ein Intressanter Link: www.vb-magazin.de/Kn...rticle.aspx?ID=10060
Heiko Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3169
Erhaltene Danke: 11



BeitragVerfasst: Do 25.01.07 19:36 
Ich habs gerade getestet. Doch leider funktioniert das auch nicht. Ich bekomme nur ein weißes Bild (was auch nur daran liegt, dass ich ein Bitmap da zeichne...):

ausblenden 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:
procedure TCamAnalyzer.FilterColorPanelClick(Sender: TObject);
var
  m_hBmp: HWND;
  Width, Height: Integer;
  BitmapInfo: TBitmapInfo;
begin
  FillChar(BitmapInfo, SizeOf(BitmapInfo), 0);
  SendMessage(CapHandle, WM_CAP_GET_VIDEOFORMAT, SizeOf(BitmapInfo), Integer(@BitmapInfo));
  Width:=BitmapInfo.bmiHeader.biWidth;
  Height:=BitmapInfo.bmiHeader.biHeight;

  if (cur_Width<>Width) or (cur_Height<>Height) then
  begin
    bmpdata:=nil;
    cur_Width :=Width ;
    cur_Height:=Height;
    Size:=Width*Height;
    SetLength(bmpdata, Size);
    CamAnalyzer.CamImage.Picture.Bitmap.SetSize(Width, Height);
    Bitmap.SetSize(Width, Height);
  end;
  Clear
  SendMessage(CapHandle, WM_CAP_GRAB_FRAME, 0, 0);
  SendMessage(CapHandle, WM_CAP_EDIT_COPY, 0, 0);
  OpenClipboard(HWND(nil));
  m_hBmp := GetClipboardData(CF_BITMAP);
  BitBlt(CamImage.Picture.Bitmap.Canvas.Handle, 0, 0, Width, Height, m_hBmp, 0, 0, SRCCOPY);
  CloseClipboard;
end;


ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
procedure TCamAnalyzer.FormCreate(Sender: TObject);
begin
  CapHandle:=capCreateCaptureWindow('CamStream', WS_CHILD or WS_VISIBLE, 0, 0, 1, 1, Handle, 1);
  SendMessage(CapHandle, WM_CAP_DRIVER_CONNECT, 0, 0);
  SendMessage(CapHandle, WM_CAP_SET_OVERLAY, 1, 0);
  SendMessage(CapHandle, WM_CAP_SET_PREVIEW, 1, 0);
  {SendMessage(CapHandle, WM_CAP_SET_CALLBACK_FRAME, 0, Integer(@OnFrame));
  SendMessage(CapHandle, WM_CAP_SET_PREVIEWRATE, 1, 0);}

  CamAnalyzer.DoubleBuffered:=true;
end;