none
Vision par Ordinateur Win32 webcam RRS feed

  • Question

  • bonjour,

    je suis entrain de développer une petite appli de vision par ordinateur, mais je me trouve confronté a quelques petit soucis.

    un exemple de code très simplifié qui plante  :

    #define WIN32_LEAN_AND_MEAN
    
    #include <windows.h>
    #include <vfw.h>
    #include "resource.h"
    
    HINSTANCE hInst;
    
    BOOL CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
        HWND VFWAPI win1;
        switch(uMsg)
        {
            case WM_INITDIALOG:
                return TRUE;
    
            case WM_CLOSE:
                EndDialog(hwndDlg, 0);
                return TRUE;
    
            case WM_COMMAND:
                switch(LOWORD(wParam))
                {
                    case IDC_BTN_QUIT:
                        EndDialog(hwndDlg, 0);
                        return TRUE;
    
                    case IDC_BTN_TEST:
                        win1 = capCreateCaptureWindow( "CapWind", WS_CAPTION, 10, 10, 640, 480, hwndDlg, WIN_01);
                        return TRUE;
                }
        }
    
        return FALSE;
    }
    
    
    int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
    {
        hInst = hInstance;
        return DialogBox(hInstance, MAKEINTRESOURCE(DLG_MAIN), NULL, (DLGPROC)DialogProc);
    }
    

    le code erreur c'est :

    undefined reference to `capCreateCaptureWindowA@32'

    là j’avoue que je ne comprend pas ce qui plante.

    Pour info je suis sous windows7, je développe sur Codeblock. L'application sera sur un pc avec pour Os : XP, et la web cam a une résolution de 8MP

    Cordialement.

    mardi 22 mai 2012 13:43

Réponses

Toutes les réponses

  • A en croire la documentation

    http://msdn.microsoft.com/en-us/library/windows/desktop/dd756879(v=vs.85).aspx

    Il faut que "Vfw32.lib" fasse partie des librairies en entrée des options du linker.


    Paul Bacelar, Ex - MVP VC++

    mardi 22 mai 2012 14:17
    Modérateur
  • ça j'ai déjà testé et :

    invalid preprocessing directive #inculde

    que ce soit :

    #include <windows.h>
    #include <vfw.h>
    #inculde "Vfw32.lib"
    #include "resource.h"

    ou :

    #include <windows.h>
    #include <vfw.h>
    #inculde <Vfw32.lib>
    #include "resource.h"
    mardi 22 mai 2012 15:21
  • Primo : c'est #include et non #inculde

    Secondo : #include, c'est à la compilation pas à l'édition de lien, et on n'inclut pas des lib aux sources mais des fichiers d'en-tête(.h).

    A la rigueur, vous utilisez une commende équivalente au "#pragma comment(lib,...)" de VS. (http://msdn.microsoft.com/en-us/library/7f0aews7(v=vs.100).aspx)

    Tercio : j'ai dit d'ajouter la lib à la liste des librairies en entrés des options du linker, donc potassez la documentation de Code:Block pour ajouter ces librairie à  la liste des librairie du LINKER.

    Révisez comment marche une chaine de génération C/C++, SVP.


    Paul Bacelar, Ex - MVP VC++

    • Proposé comme réponse Ciprian Duduiala mercredi 23 mai 2012 06:43
    • Non proposé comme réponse 23253 mercredi 23 mai 2012 07:46
    • Marqué comme réponse 23253 mercredi 23 mai 2012 08:02
    • Non marqué comme réponse 23253 mercredi 23 mai 2012 08:02
    • Marqué comme réponse Ciprian Duduiala lundi 28 mai 2012 06:37
    mardi 22 mai 2012 15:57
    Modérateur
  • alors pour les #inculde au lieu de include ... erreur de frappe.

    ensuite pour le #pragma ou le Linker ... je n'avais jamais eu besoin d'y avoir recours et code block je m'en sert depuis juste 5 semaine au grand maximum.

    et pour info si jamais quelqu'un se demande comment on fait c'est (sous code block):

    settings --> compiler and debugger --> linker setting --> add  :  "Vfw32"

    a savoir que les image que je prend avec le programme ne fond que 640 * 480 alors que ma camera a une résolution de 1920 * 1080 et bien sur il ne me les affiche pas, savez vous pourquoi ?

    voila le code avec le quel je test.

    #define WM_CAP_START  0x0400
    #define WM_CAP_DRIVER_CONNECT  (WM_CAP_START + 10)
    #define WM_CAP_DRIVER_DISCONNECT  (WM_CAP_START + 11)
    #define WM_CAP_EDIT_COPY (WM_CAP_START + 30)
    #define WM_CAP_GRAB_FRAME (WM_CAP_START + 60)
    #define WM_CAP_SET_SCALE (WM_CAP_START + 53)
    #define WM_CAP_SET_PREVIEWRATE (WM_CAP_START + 52)
    #define WM_CAP_SET_PREVIEW (WM_CAP_START + 50)
    #define WM_CAP_DLG_VIDEOSOURCE  (WM_CAP_START + 42)
    #define WM_CAP_STOP (WM_CAP_START+ 68)
    
    #include <windows.h>
    #include <vfw.h>
    
    LRESULT CALLBACK WindowProc (HWND, UINT, WPARAM, LPARAM);
    
    char szAppName [] = TEXT("WebCam");
    HWND camhwnd;
    HDC hdc ;
    HDC hdcMem;
    PAINTSTRUCT ps;
    HBITMAP hbm;
    RECT rc;
    
    int WINAPI WinMain ( HINSTANCE hInstance, HINSTANCE hPrevInstance,
                         LPSTR lpCmdLine, int nCmdShow )
    {
    
        HWND hwnd;
        MSG msg;
    
        WNDCLASS wc;
        wc.style = 0;
        wc.lpfnWndProc = WindowProc;
        wc.cbClsExtra = 0;
        wc.cbWndExtra = 0;
        wc.hInstance = hInstance;
        wc.hIcon = LoadIcon(GetModuleHandle(NULL), IDI_APPLICATION);
        wc.hCursor = LoadCursor (NULL, IDC_ARROW);
        wc.hbrBackground = (HBRUSH) (COLOR_WINDOW+1);
        wc.lpszMenuName = NULL;
        wc.lpszClassName = szAppName;
    
        RegisterClass (&wc);
        
        hwnd = CreateWindow (szAppName,szAppName,WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX,CW_USEDEFAULT,CW_USEDEFAULT,300,600,0,0,hInstance,0);
    
        ShowWindow (hwnd,SW_SHOW);
        UpdateWindow (hwnd);
    
        while (GetMessage(&msg,0,0,0))
        {
            if (!IsDialogMessage(hwnd, &msg))
            {
                TranslateMessage (&msg);
                DispatchMessage (&msg);
            }
        }
        return msg.wParam;
    }
    
    LRESULT CALLBACK WindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        HINSTANCE hInstance = GetModuleHandle(NULL);
    
        HWND hButtStartCam;
        HWND hButtStopCam;
        HWND hButtGrabFrame;
    
        switch (message)               
        {
    
            case WM_CTLCOLORSTATIC:
                SetBkMode(hdc,TRANSPARENT);
                return (LRESULT)CreateSolidBrush(0xFFFFFF);
    
            case WM_CREATE:
            {
                hButtStartCam = CreateWindowEx(0,"BUTTON","Start Camera",WS_CHILD | WS_VISIBLE,0,0,100,20,hwnd,(HMENU)1,hInstance, 0);
                hButtStopCam = CreateWindowEx(0,"BUTTON","Stop Camera",WS_CHILD | WS_VISIBLE,0,25,100,20,hwnd,(HMENU)2,hInstance, 0);
                hButtGrabFrame = CreateWindowEx(0,"BUTTON","Grab Frame",WS_CHILD | WS_VISIBLE,0,50,100,20,hwnd,(HMENU)3,hInstance, 0);
    
                camhwnd = capCreateCaptureWindow ("camera window", WS_CHILD , 0, 100, 3000, 3000, hwnd, 0);
                SendMessage(camhwnd,WM_CAP_DRIVER_CONNECT,0,0);
                SendMessage(camhwnd,WM_CAP_DLG_VIDEOSOURCE,0,0);
    
                break;
            }
    
            case WM_COMMAND:
            {
                switch (LOWORD(wParam))
                {
                    case 1:
                    {
                        ShowWindow(camhwnd,SW_SHOW);
                        SendMessage(camhwnd,WM_CAP_DRIVER_CONNECT,0,0);
                        SendMessage(camhwnd, WM_CAP_SET_SCALE, true , 0);
                        SendMessage(camhwnd, WM_CAP_SET_PREVIEWRATE, 66, 0);
                        SendMessage(camhwnd, WM_CAP_SET_PREVIEW, true , 0);
                        break;
                    }
    
                    case 2:
                    {
                        ShowWindow(camhwnd,SW_HIDE);
                        SendMessage(camhwnd, WM_CAP_DRIVER_DISCONNECT, 0, 0);
                        break;
                    }
    
                    case 3:
                    {
                        LPSTR filename =(LPSTR)"MyCapture.bmp";
                        SendMessage(camhwnd,WM_CAP_FILE_SAVEDIB, 0, (LPARAM) filename);
                        SendMessage(camhwnd,WM_CAP_DRIVER_CONNECT,0,0);
                        SendMessage(camhwnd, WM_CAP_SET_SCALE, true , 0);
                        SendMessage(camhwnd, WM_CAP_SET_PREVIEWRATE, 66, 0);
                        SendMessage(camhwnd, WM_CAP_SET_PREVIEW, true , 0);
                        break;
                    }
                }
                break;
            }
    
            case WM_DESTROY:
            {
                SendMessage(camhwnd, WM_CAP_DRIVER_DISCONNECT, 0, 0);
                PostQuitMessage(0);
                break;
            }
    
            default:
                return DefWindowProc(hwnd, message, wParam, lParam);
        }
        return 0;
    }




    • Modifié 23253 mercredi 23 mai 2012 07:45
    mercredi 23 mai 2012 06:45
  • Rien dans une fenêtre type "sortie" de VS ?

    Rien dans L'eventLog ?


    Paul Bacelar, Ex - MVP VC++

    mercredi 23 mai 2012 08:42
    Modérateur
  • je ne vois pas ce dont vous parlez "sortie"de VS

    le programme fonctionne parfaitement bien, mais n'affiche pas l'image et quand il prend une photo la prend avec une résolution de 640*480

    mercredi 23 mai 2012 08:48
  • Vérifiez systématiquement, au moins en Debug, les valeurs de retour, SVP.

    La MACRO VERIFY est là pour ça.

    Pensez à utiliser les MACRO dédiées comme capGrabFrame (http://msdn.microsoft.com/en-us/library/windows/desktop/dd756915(v=vs.85).aspx)

    Cela rend le code plus lisible et plus maintenable comme dans l'exemple suivant :

    http://www.codeproject.com/Articles/7882/Easy-Digital-Camera-Connection

    Votre pompe à message est suspecte. L'utilisation d'IsDialogMessage m'interloque.

    La taille de la fenêtre ne correspond à rien.

    Votre caméra est capable de faire du 1920 * 1080 mais ce n'est pas forcement sa résolution de restitution actuel.

    Il est ou l'appel à capDlgVideoFormat ou SendMessage(...,WM_CAP_DLG_VIDEOFORMAT,... ?

    Commencez par faire un POC et utilisant les exemples sur le Net.

    La fenêtre sortie/output de VS est une fenêtre dans l'IDE qui affiche le chargement des Dll et des évènements comme la levée d'exception etc...


    Paul Bacelar, Ex - MVP VC++


    mercredi 23 mai 2012 12:57
    Modérateur
  • comme vous me l'avez dit j'ai était voir sur msdn ...

    donc j'ai fait au plus simple :

    switch(LOWORD(wParam)) { case IDC_BTN_QUIT: SendMessage(win1,WM_CAP_DRIVER_DISCONNECT,0,0); capPreview(win1, FALSE); EndDialog(hwndDlg, 0); return TRUE; case IDC_BTN_TEST: win1 = capCreateCaptureWindow("capturewindow", WS_VSCROLL|WS_HSCROLL|WS_CHILD|WS_VISIBLE, 10,10,192,108,hwndDlg,ID_WIN1); SendMessage(win1,WM_CAP_DRIVER_CONNECT,0,0); SendMessage(win1,WM_CAP_DLG_VIDEOSOURCE,0,0); capPreviewRate(win1, 66); capPreview(win1, TRUE); capDlgVideoFormat(win1); return TRUE;

    }

    la camera s'allume, mais je n'ai rien d'afficher, et la résolution maximum proposé dans  capDlgVideoFormat est de 640*480


    PS : visual Studio je ne l'ai pas.



    mercredi 23 mai 2012 13:44
  • VS en version Express, c'est gratis : http://msdn.microsoft.com/fr-fr/express/aa975050.aspx

    N'êtes-vous pas dans le cas évoqué par les réponses 7 et 8 du thread à l'URL suivante ?

    http://go4answers.webhost4life.com/Example/webcam-vfwh-problem-black-screen-60791.aspx


    Paul Bacelar, Ex - MVP VC++

    mercredi 23 mai 2012 17:23
    Modérateur
  • effectivement je me trouve dans un cas similaire,

    quand je lance la prévisualisation, j'ai un écran noir, on me demande quelle camera utiliser le voyant de la webcam s'allume, puis une dilogbox apparait me demandant le "format video" resolution maximum 640*480, 352*288, 320*240, 176*144, 160*120 et densité de pixel [...] MJPG ou YUY2.

    Mais la différence majeur c'est que il on tous l'air de vouloir prendre des vidéo, moi ce qui m’intéresse vraiment c'est de prendre des photo pour ensuite travailler dessus.

    Question de second ordre, y a t'il une qui vectorise une image 2D : qui renvoi par exemple Vi(56, 84, 12, 1, 5) oû Vi serai le nom du vecteur,56 sont origine en X,84 sont origine en Y, 12 son déplacement sur les X, 1 sont déplacement sur les Y et 5 sa largeur en pixel, ou un truc dans ce genre avec vfw ou une autre librairie.

    Cordialement et merci de vos réponses.

    PS :je fait du stop motion pour le moment pas fait exprès mais toujours sans prévisualisation.

    • Modifié 23253 jeudi 24 mai 2012 15:03
    jeudi 24 mai 2012 06:40
  • personne ne sais comment capturer une image "photo", avec vfw, quel qu’en soit le format ?
    vendredi 25 mai 2012 06:22
  • Comme indiqué dans ma précédente réponse :

    N'êtes-vous pas dans le cas évoqué par les réponses 7 et 8 du thread à l'URL suivante ?

    http://go4answers.webhost4life.com/Example/webcam-vfwh-problem-black-screen-60791.aspx


    Paul Bacelar, Ex - MVP VC++

    vendredi 25 mai 2012 10:28
    Modérateur
  • je suis d'accord avec vous mais il faut savoir que mon anglais n'est pas des meileurs et que avec ce que j'ai pu comprendre :

    LPVIDEOHDR lpVHdr;
    LRESULT CALLBACK win2;
    win2 = capVideoStreamCallback(camhwnd, lpVHdr);
    capSetCallbackOnFrame(camhwnd,win2);

    mais sa me donne une erreur :

    'capVideoStreamCallback' was not declared in this scope

    Alors que sur msdn le seul header c'est vfw.h (oui oui ... je l'ai linker). donc j'en déduit que j'ai loupé un truc, sa aurai planté a l'exécution je me serais dit que j'aurais codant mais là je ne comprend pas.

    vendredi 25 mai 2012 13:43
  • Vous êtes toujours un peu perdu.

    Si vous regardez bien la documentation de capVideoStreamCallback (http://msdn.microsoft.com/en-us/library/dd797759(VS.85).aspx) vous verrez qu'il s'agit d'un "placeholder". Il s'agit, en fait, de rien de très concret, juste un nom pour donner la signature de la fonction (type du résultat en sortie et types des paramètres en entré) attendu par d'autres fonctions.

    Elle n'est donc pas "définie" dans un .h.

    Il faut jsute que vous fournissiez à la fonction "capSetCallbackOnFrame" un pointeur de fonction sur une fonction qui à la même signature.

    C'est cette fonction qui sera appelée répétivement pour traiter les images "à la volé".

    Voici un exemple de définition et d'utilisation de ce type de fonction (section <The functions taking care of "Capture to .bmp" buttons.>):

    http://sites.google.com/site/pengjungwu/Home/video-capture-using-vfw


    Paul Bacelar, Ex - MVP VC++

    vendredi 25 mai 2012 16:44
    Modérateur
  • meci pour ce message, grâce a cela je peut prendre une photo, mais le problème est que cette photo n'est prise que dans une resolution de 640*480 si je souhaite passer en 1920*1080 ce qui est la resolution de ma camera, j'ai deux possibilités mais aucune des deux fonctionne, soit :

    capDlgVideoFormat(hWndC);

    qui ne me propose que des résolution inférieurs ou égales a 640*480 ce qui ne m’intéresse pas.

    soit :

    BITMAPINFO psVideoFormat;
    capGetVideoFormat(camhwnd,&psVideoFormat,sizeof(psVideoFormat));
    psVideoFormat.bmiHeader.biWidth = 1920;
    psVideoFormat.bmiHeader.biHeight = 1080;
    if(!capSetVideoFormat(camhwnd,&psVideoFormat,sizeof(psVideoFormat)))
    {
         printf("erreur de format\n");
    }else printf("format changé\n");
    capDriverDisconnect (camhwnd);
    capDriverConnect (camhwnd, 0);
    

    dans la console il me met que j'ai changé le format mais les image que je sauvegardes sont vides : 0 Ko

    deuxième question :

    connaissez vous une fonction qui permette de transformer une image Bmp et une matrice de vecteur ?

    mardi 29 mai 2012 07:32
  • Si le format n'est pas présent dans la boite de dialogue affichée par capDlgVideoFormat, ça sent le sapin.

    Avez-vous les derniers drivers de votre caméra ?

    Pour la question subsidiaire : un autre thread svp.


    Paul Bacelar, Ex - MVP VC++

    mardi 29 mai 2012 09:05
    Modérateur
  • alors oui j'ai les dernier driver (j'ai vérifié) et non j'ai pas le format que je veux de proposé

    sinon vous avez pas un autre idée de comment faire ?

    et ok je fait un nouveau thread pour l'autre question

    mardi 29 mai 2012 09:12
  • Regardez la documentation technique (SDK) de votre caméra, ils n'ont peut-être pas respecté les API Windows.

    Il n'y a pas des .ini ou des clés de registres pour modifier la configuration de votre caméra ?


    Paul Bacelar, Ex - MVP VC++

    mardi 29 mai 2012 10:30
    Modérateur