Webcam wie kommt man an die Bilddaten
-
Hi ich habe mich in letzter Zeit damit beschäftigt meine Webcam in ein c++ Programm einzubinden. Hier im Forum habe ich einen quellcode von www.allanpetersen.com gefunden:
//--------------------------------------------------------------------------- #include <vcl.h> #pragma hdrstop #include <stdio.h> #include "c_cap.h" //--------------------------------------------------------------------------- #pragma package(smart_init) __fastcall TCap::TCap (HWND Handle) { // create video capture window ParentHandle = Handle; hwndVideo = capCreateCaptureWindow( (LPSTR) "My Capture Window", WS_CHILD | WS_VISIBLE, 0, 0, 300, 200, (HWND) Handle, (int) 1); pStringCapDrivers = new TStringList; SelectedDevice = -1; } __fastcall TCap::~TCap () { delete pStringCapDrivers; capCaptureStop(hwndVideo); capPreview(hwndVideo, FALSE); // end preview capDriverConnect(hwndVideo, SelectedDevice); capDriverDisconnect(hwndVideo); // disconnect from driver capCaptureAbort(hwndVideo); } //--------------------------------------------------------------------------- // enumerate the installed capture drivers //--------------------------------------------------------------------------- int TCap::EnumCapDrv () { char szDeviceName[80]; // driver name char szDeviceVersion[80]; // driver version char str[161]; // concatinated string int xcap; // counter xcap = 0; pStringCapDrivers->Clear (); do { if (capGetDriverDescription(xcap, szDeviceName, sizeof(szDeviceName), szDeviceVersion, sizeof(szDeviceVersion))) { sprintf (str, "%s, %s", szDeviceName, szDeviceVersion); pStringCapDrivers->AddObject (str, (TObject *)xcap); } else { break; } xcap++; } while (true); return 0; } //--------------------------------------------------------------------------- // connecting to selected device and starts preview //--------------------------------------------------------------------------- void TCap::Connect (int Selected) { CAPSTATUS CapStatus; int hsize; // capDlgVideoDisplay(hwndVideo); // connect to the driver if (SelectedDevice != -1) { capPreview (hwndVideo, FALSE); capDriverConnect(hwndVideo, SelectedDevice); } if (!capDriverConnect(hwndVideo, Selected)) { // ---- Unable to connect to driver return; } // update the driver capabilities capDriverGetCaps (hwndVideo, sizeof(CAPDRIVERCAPS), &CapDrvCaps); capDlgVideoFormat(ParentHandle); //----------------------------------------------------------------------------- //**********Eigene Veränderungen an dem Header********************************* //----------------------------------------------------------------------------- //Die Standarteinstellungen laden DWORD dwSize; // Länge der Formateigenschaften BITMAPINFO pbiInfo; // Bitmap-Eigenschaften der Datei dwSize=capGetVideoFormatSize(hwndVideo); // Messen der Länge capGetVideoFormat(hwndVideo, &pbiInfo, dwSize); // Momentane Formatierung laden // Einstellen der neuen Werte DWORD dwWidth,dwHeight,dwBPP; dwWidth=640; // Horizontale Auflösung dwHeight=480; // Vertikale Auflösung dwBPP=24; // Farbtiefe pbiInfo.bmiHeader.biWidth = dwWidth; pbiInfo.bmiHeader.biHeight = dwHeight; pbiInfo.bmiHeader.biBitCount = (WORD) dwBPP; pbiInfo.bmiHeader.biSizeImage = 0; // Größe der reservierten Bytes pbiInfo.bmiHeader.biCompression = BI_RGB; // Komprimierung (BI_RGB=keine Kompr.) pbiInfo.bmiHeader.biClrUsed = 0; // Maximale Anzahl der dargestellten pbiInfo.bmiHeader.biClrImportant = 0; // Farben, 0=alle Farben pbiInfo.bmiHeader.biPlanes = 1; // Einstellung der Treiberebenen. Muss 1 sein pbiInfo.bmiColors->rgbBlue = 0; // Eingabe der Farbverstärkung der pbiInfo.bmiColors->rgbGreen = 0; // Grundfarben. 0=keine Verstärkung pbiInfo.bmiColors->rgbRed = 0; pbiInfo.bmiColors->rgbReserved = 0; // Muss auf 0 gesetzt sein //Zurückschreiben zur API capSetVideoFormat(hwndVideo, &pbiInfo, dwSize); //----------------------------------------------------------------------------- // Die neu eingestellte Bildgröße wird in den CapStatus geladen capGetStatus(hwndVideo, &CapStatus, sizeof(CAPSTATUS)); hsize = GetSystemMetrics(SM_CYMENU); hsize += GetSystemMetrics(SM_CYCAPTION); // Das Anzeigefenster wird neu aufgebaut SetWindowPos(hwndVideo, NULL, 0, 0, CapStatus.uiImageWidth, CapStatus.uiImageHeight, SWP_NOZORDER | SWP_NOMOVE); SetWindowPos(ParentHandle, NULL, 0, hsize, CapStatus.uiImageWidth, CapStatus.uiImageHeight+hsize, SWP_NOZORDER | SWP_NOMOVE); // Stellt die Bildwiederholrate des Vorschaufensters ein capPreviewRate (hwndVideo, 33.3); // startet die Bildvorschau capPreview (hwndVideo, TRUE); // Das geöffnete Aufnahmegerät wird gespeichert SelectedDevice = Selected; } //--------------------------------------------------------------------------- // Get access to the video source format box //--------------------------------------------------------------------------- void TCap::Format () { int hsize; CAPSTATUS CapStatus; capDlgVideoFormat(hwndVideo); // Are there new image dimensions capGetStatus(hwndVideo, &CapStatus, sizeof(CAPSTATUS)); hsize = GetSystemMetrics(SM_CYMENU); hsize += GetSystemMetrics(SM_CYCAPTION); SetWindowPos(ParentHandle, NULL, 0, hsize, CapStatus.uiImageWidth, CapStatus.uiImageHeight+hsize, SWP_NOZORDER | SWP_NOMOVE); SetWindowPos(hwndVideo, NULL, 0, 0, CapStatus.uiImageWidth, CapStatus.uiImageHeight, SWP_NOZORDER | SWP_NOMOVE); } //--------------------------------------------------------------------------- // Get access to the video source dialog box //--------------------------------------------------------------------------- void TCap::Source () { capDlgVideoSource(hwndVideo); } //--------------------------------------------------------------------------- // capture a frame and save it //--------------------------------------------------------------------------- void TCap::CaptureFrame (char *FileName) { capFileSaveDIB (hwndVideo, FileName); } //---------------------------------------------------------------------------
(dazu gehört noch die unit1.cpp datei)
Ich habe das Programm zum laufen gebracht(ein Borland compiler bewirkt wunder), aber ich weiß immer noch nicht
1. wie ich an die Bilddaten selber drankomme,
2. wie ich ein Bild ohne speichern Dialog speichere und
3. wie ich das alle x millisekunden machen kann.
Wie ich ein Timer benutze ist mir schon klar nur ich habe noch nicht sowas wie ein Mainloop gefunden der kontinuirlich ausgeführt wird.Am Ich möchte aus diesem Program eine art bewegungsmelder basteln.
Welches auf meinem Server laufen soll. dazu brauche ich von dem webcam stream alle x millisekunden nen grauwert array
zb(3x3 Bild Dunkles kreuz):
[ 246 20 230
14 37 11
250 40 255 ]
die gui ist mir vollkommen egal die kann ruhig wegbleiben. Ich würde die daten am liebsten nicht erst auf die HD speichern sondern gleich benutzen.
vielen Dank für eure Mühe
Gruß KOR
-
Im Preview-Modus kannst du dir den DC vom capture-window holen und einfach via BitBlt() in eine von dir erzeugte Bitmap blitten.
(Ich würde aber eher auf DirectShow umsteigen statt Vfw zu nutzen)
-
warum würdest du auf DirectShow umsteigen und hast du einen Funktionierenden code?
das mit BitBlt() werde ich gleich mal ausprobieren.
-
BitBlt() nimmt sich die daten des Handles und kopiert sie in ein Bitmap file. Ich möchte aber nur an die Farbwerte und nicht erst nen bitmap machen und dann wieder einlesen.
-
Nimm eine DIBSection oder sowas, da kannst du direkt via Pointer auf die Pixeldaten zugreifen.
Alternativ kannst du auch BitBlt() weglassen und direkt mit GetPixel() arbeiten.
GetPixel() ist allerdings sau lahm wenn du mehrere Pixel angucken willst.Quellcode habe ich keinen (mehr) da
DirectShow meinte ich weil:
- Vfw noch ein Überbleibsel aus Windows 3.x Zeiten ist und aktuelle Webcams teilweise nur noch DirectShow-Wrapper auf Vfw mitliefern.
- Bei DirectShow kannst du dir einen DirectShow-Filter schreiben und kommst damit direkt an die Pixeldaten. Zudem ist DirectShow auch noch ziemlich schnell.
- Nachteil: In DirectShow muss man sich erstmal einarbeiten
-
hi ich benutze jetzt openCV das ist recht einfach und man kommt nach kurzer einarbeitungszeit auch an die pixeldaten. Wenns jemand mal braucht ich habe mal das minimal programm aus meinem Quelltext zusammenkopiert:
#include <cv.h> #include <cxcore.h> #include <highgui.h> //nicht das linken der libs und header vergessen int _tmain(int argc, _TCHAR* argv[]) { CvCapture* capture = cvCaptureFromCAM(0);// capture from video device #0 if(!cvGrabFrame(capture)){ // capture a frame printf("Could not grab a frame\n\7"); // if it fails print errormsg exit(0); // and exit } img=cvRetrieveFrame(capture); // get image IplImage *gray_img; // creating empty grey image pointer gray_img = cvCreateImage(imgSize, IPL_DEPTH_8U, 1); // allocate Memory cvCvtColor(img, gray_img, CV_BGR2GRAY); // converting from color to grayscale int step = gray_img->widthStep; int channels = gray_img->nChannels; // channels RGB(3) grey(1) etc uchar *data = (uchar *)gray_img->imageData;// pixeldata of image int r=0; int c=1; pixelrc=int(data[r*step+c]); //pixel at pos (0,1) cout<<pixelrc<<endl; return 0; }