|  (→Programmation UVC: les fonctions utilisées par uvcdynctrl) |  (→Code Sources) | ||
| (28 versions intermédiaires masquées) | |||
| Ligne 1 : | Ligne 1 : | ||
| retour vers [[linux]] | retour vers [[linux]] | ||
| - | ==WebCam logitech Web-Sphere (QuickCam Orbit) motorisée et autres WebCam UVC sous linux  | + | ==WebCam logitech Web-Sphere (QuickCam Orbit) motorisée et autres WebCam UVC sous linux== | 
| Ligne 8 : | Ligne 8 : | ||
| http://fr.wikipedia.org/wiki/USB_video_device_class <br> | http://fr.wikipedia.org/wiki/USB_video_device_class <br> | ||
| Linux n'est pas le seul concerné par cette norme. Solaris, Mac OS X, ... et Windows le sont aussi.<br> | Linux n'est pas le seul concerné par cette norme. Solaris, Mac OS X, ... et Windows le sont aussi.<br> | ||
| + | Le driver UVC est intégré au noyau depuis la version 2.6.26. Donc rien a faire a ce niveau :-) La WebCam fonctionne avec vos logiciels habituels.  | ||
| + | <br> | ||
| + | Pour ce qui est de la motorisation, c'est ci-dessous. | ||
| - | === | + | ===webcam motorisée, installez uvcdynctrl du dépôt universe=== | 
| Pour l'installer:   | Pour l'installer:   | ||
| Ligne 32 : | Ligne 35 : | ||
|        Media controller device /dev/media1 doesn't exist |        Media controller device /dev/media1 doesn't exist | ||
|    ERROR: Unable to list device entities: Invalid device or device cannot be opened. (Code: 5) |    ERROR: Unable to list device entities: Invalid device or device cannot be opened. (Code: 5) | ||
| + | Les 2 dernières lignes ne sont pas importantes. uvcdynctrl recherche par défaut des periphériques sur /dev/media* | ||
| - | + | Pour lister les formats possible de votre périphérique (par défaut /dev/video0 sinon préciser -d /dev/video34 par exemple):<br> | |
| + | <pre> | ||
| + | uvcdynctrl -f  | ||
| + | Listing available frame formats for device video0: | ||
| + | Pixel format: MJPG (MJPEG; MIME type: image/jpeg) | ||
| + |   Frame size: 160x120 | ||
| + |     Frame rates: 30, 25, 20, 15, 10, 5 | ||
| + |   Frame size: 176x144 | ||
| + |     Frame rates: 30, 25, 20, 15, 10, 5 | ||
| + |   Frame size: 320x240 | ||
| + |     Frame rates: 30, 25, 20, 15, 10, 5 | ||
| + |   Frame size: 352x288 | ||
| + |     Frame rates: 30, 25, 20, 15, 10, 5 | ||
| + |   Frame size: 640x480 | ||
| + |     Frame rates: 30, 25, 20, 15, 10, 5 | ||
| + |   Frame size: 800x600 | ||
| + |     Frame rates: 30, 25, 20, 15, 10, 5 | ||
| + |   Frame size: 960x720 | ||
| + |     Frame rates: 15, 10, 5 | ||
| + | Pixel format: YUYV (YUV 4:2:2 (YUYV); MIME type: video/x-raw-yuv) | ||
| + |   Frame size: 160x120 | ||
| + |     Frame rates: 30, 25, 20, 15, 10, 5 | ||
| + |   Frame size: 176x144 | ||
| + |     Frame rates: 30, 25, 20, 15, 10, 5 | ||
| + |   Frame size: 320x240 | ||
| + |     Frame rates: 30, 25, 20, 15, 10, 5 | ||
| + |   Frame size: 352x288 | ||
| + |     Frame rates: 30, 25, 20, 15, 10, 5 | ||
| + |   Frame size: 640x480 | ||
| + |     Frame rates: 30, 25, 20, 15, 10, 5 | ||
| + |   Frame size: 800x600 | ||
| + |     Frame rates: 25, 20, 15, 10, 5 | ||
| + |   Frame size: 960x720 | ||
| + |     Frame rates: 10, 5 | ||
| + |   Frame size: 1600x1200 | ||
| + |     Frame rates: 5 | ||
| + | </pre> | ||
| + | Voici pour ma WebCam logitech Web-Sphere | ||
| + | <br> | ||
| + | <br> | ||
| Pour lister les contrôles possibles du périphérique (par défaut /dev/video0 ) | Pour lister les contrôles possibles du périphérique (par défaut /dev/video0 ) | ||
| <br> | <br> | ||
| Ligne 61 : | Ligne 104 : | ||
|      Raw bits per pixel |      Raw bits per pixel | ||
| <br> | <br> | ||
| - | |||
| - | |||
| - | |||
| - | |||
| - | Pour avoir le detail des  | + | Pour avoir le detail des paramétres pour chaque option ( par defaut /dev/video0, si defferent ajouter l'option -d /dev/video9 ou autres ) | 
|    uvcdynctrl -c -v |    uvcdynctrl -c -v | ||
| Ligne 240 : | Ligne 279 : | ||
|     ERROR: Unable to retrieve control value: A Video4Linux2 API call returned an unexpected error 22. (Code: 12) |     ERROR: Unable to retrieve control value: A Video4Linux2 API call returned an unexpected error 22. (Code: 12) | ||
| Vous essayez de lire une valeur de position relative ( relative a elle meme), qui par définition est relative. C'est a dire égale a 0.<br> | Vous essayez de lire une valeur de position relative ( relative a elle meme), qui par définition est relative. C'est a dire égale a 0.<br> | ||
| - | On regrette donc ces 2 options soient en "CAN_READ" ce qui est de la responsabilité du constructeur ... | + | On regrette donc que ces 2 options soient en "CAN_READ", ce qui est de la responsabilité du constructeur ... | 
| - | + | vous ne pouvez les utiliser qu'en écriture. Exemple de commande a passer: | |
|      uvcdynctrl -d /dev/video0 -s 'Pan (relative)' -- -4480 |      uvcdynctrl -d /dev/video0 -s 'Pan (relative)' -- -4480 | ||
| Ligne 249 : | Ligne 288 : | ||
| La 2eme commande va tenter de deplacer vers le bas (+) de 1920 unités (le max accepter ) par rapport a la position actuelle. | La 2eme commande va tenter de deplacer vers le bas (+) de 1920 unités (le max accepter ) par rapport a la position actuelle. | ||
| - | ==Programmation UVC:  | + | ==Programmation UVC: des fonctions de libwebcam utilisées par uvcdynctrl== | 
| - |    <nowiki>#include <webcam.h><nowiki> | + |    <nowiki>#include <webcam.h></nowiki> | 
| - | + |    CResult c_get_control (CHandle hDevice, CControlId control_id, CControlValue *value) | |
| - | + |   CResult c_set_control (CHandle hDevice, CControlId control_id, const CControlValue *value) | |
| - | + |    CResult c_enum_events (CHandle hDevice, CEvent *events, unsigned int *size, unsigned int *count)  | |
| - | + |   CResult c_enum_frame_intervals(hDevice, pixelformat, framesize, NULL, &size, &count) | |
| + |   CResult c_enum_frame_sizes(hDevice, pixelformat, NULL, &size, &count); | ||
| + |    CResult c_enum_pixel_formats(hDevice, NULL, &size, &count); | ||
| + |   CResult c_enum_devices(devices, &req_size, &count); | ||
| + |   CHandle c_open_device (const char *device_name) | ||
| + |   CResult c_init(void) | ||
| + |   ... | ||
| a linker a libwebcam | a linker a libwebcam | ||
| + | |||
| + | ==Programmation UVC: un exemple d'utilisation de la libwebcam== | ||
| + | |||
| + | Un exemple de Ana Huamán tiré du tutorial de OpenCV ( http://docs.opencv.org/doc/tutorials/objdetect/cascade_classifier/cascade_classifier.html#cascade-classifier )  repris et modifié pour suivre un visage avec la motorisation. . L’idéal serait d'avoir réussi a faire fonctionner l'exemple d'origine. | ||
| + | <br><br> | ||
| + | ===Demo filmé sous youtube=== | ||
| + | <br>  | ||
| + | http://youtu.be/IRUDeyVWi6U | ||
| + | <br><br> | ||
| + | ===Code Sources=== | ||
| + | <br> | ||
| + | Nécessite d'avoir OpenCV d'installé (voir [[OpenCV]]), libwebcam-dev et Qt4 (Les lib d'openCV ont été créé avec l’utilisation de QT4). Une seul webcam doit être connecté a Linux, La WebSphere. Mon code ajouté est un exemple a ne pas suivre, il est codé comme du script et dans un mélange de c++ et c. J'en ai honte. Quand j'aurais un peu de temps, je le reprendrais. Milles excuses pour ce code merdique. Il est du aux multitudes d'essais nécessaires. Vous verrez également des tempo...du préhistorique rendu nécessaire par la motorisation de la webcam tres rustique.<br> | ||
| + | il est nécessite d'avoir le fichier haarcascade_frontalface_alt.xml de l’OpenCV dans le même répertoire que ce fichier exécutable. | ||
| + | |||
| + | <pre> | ||
| + | /** | ||
| + |  * @file objectDetection.cpp | ||
| + |  * @author A. Huaman ( based in the classic facedetect.cpp in samples/c ) | ||
| + |  * @brief A simplified version of facedetect.cpp, show how to load a cascade classifier and how to find objects (Face + eyes) in a video stream | ||
| + |  */ | ||
| + | #include "opencv2/objdetect/objdetect.hpp" | ||
| + | #include "opencv2/highgui/highgui.hpp" | ||
| + | #include "opencv2/imgproc/imgproc.hpp" | ||
| + | |||
| + | #include <webcam.h> | ||
| + | |||
| + | #include <iostream> | ||
| + | #include <stdio.h> | ||
| + | |||
| + | #include <unistd.h> | ||
| + | |||
| + | using namespace std; | ||
| + | using namespace cv; | ||
| + | |||
| + | /** Function Headers */ | ||
| + | void detectAndDisplay( Mat &frame ); | ||
| + | |||
| + | /** Global variables */ | ||
| + | |||
| + | String face_cascade_name = "haarcascade_frontalface_alt.xml"; | ||
| + | |||
| + | CascadeClassifier face_cascade; | ||
| + | |||
| + | string window_name = "Capture - Face detection"; | ||
| + | |||
| + | int hauteur=480; | ||
| + | int largeur=640; | ||
| + | int viseur_mot=100; | ||
| + | |||
| + | CHandle handle = 0; | ||
| + | int reset_centre=0; | ||
| + | |||
| + | /******************************************************************************************** | ||
| + |  * @function main | ||
| + |  *********************************************************************************************/ | ||
| + | int main( int argc, const char** argv ) | ||
| + | { | ||
| + |   printf("--(!)Debut\n"); | ||
| + |   CvCapture* capture; | ||
| + |   Mat frame; | ||
| + |    //-- 1. Load  cascade | ||
| + |    if( !face_cascade.load( face_cascade_name ) ) | ||
| + |        { | ||
| + |         printf("--(!)Erreur de lecture du fichier haarcascade_frontalface_alt.xml\n"); | ||
| + |         return -1;  | ||
| + |         } | ||
| + | |||
| + | ////////////////////////////////////////////////////////////////////////////////////////////// | ||
| + | //    ajouter pour gerer la motorisation logitech | ||
| + | //    avec libwebcam pour uvc | ||
| + | ////////////////////////////////////////////////////////////////////////////////////////////// | ||
| + |   CResult res = C_SUCCESS; | ||
| + |   res = c_init(); | ||
| + |   if (res)  | ||
| + |     {	 | ||
| + |     c_cleanup(); | ||
| + |     res = c_init(); | ||
| + |     if (res)  | ||
| + |       { | ||
| + |       printf("--(!)Erreur c_init de libwebcam\n"); | ||
| + |       return -1; | ||
| + |       } | ||
| + |     } | ||
| + | |||
| + | |||
| + |   handle=c_open_device ("/dev/video0"); | ||
| + |   printf("libwebcam handle=%i\n",handle); | ||
| + |   if ( ! handle)  | ||
| + |     { | ||
| + |     printf("--(!)Erreur open_device de libwebcam\n"); | ||
| + |     return -1; | ||
| + |     } | ||
| + | |||
| + |   //-- 2. Read the video stream | ||
| + |   capture = cvCreateCameraCapture(-1); | ||
| + |   printf("--(!)Creation de capture\n"); | ||
| + | |||
| + | /******************************************************************************************** | ||
| + |  * Effectue un Reset des motorisations | ||
| + |  *********************************************************************************************/ | ||
| + |   CControlValue CCContValue; | ||
| + |   CCContValue.value=0; | ||
| + |   c_set_control(handle, CC_PAN_RESET, &CCContValue); | ||
| + |   usleep(2500000); | ||
| + |   c_set_control(handle, CC_TILT_RESET, &CCContValue); | ||
| + |   usleep(2500000); | ||
| + | |||
| + | |||
| + | cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_WIDTH, static_cast<double>(largeur)); | ||
| + | cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_HEIGHT, static_cast<double>(hauteur)); | ||
| + | |||
| + |  printf("--(!)Definition de la hauteur et largeur\n"); | ||
| + |   if( capture ) | ||
| + |   { | ||
| + |      printf("--(!)Avant Entre boucle while\n"); | ||
| + | |||
| + |      while( true ) | ||
| + |     { | ||
| + | |||
| + |       frame = cvQueryFrame( capture ); | ||
| + | |||
| + |       //-- 3. Apply the classifier to the frame | ||
| + |       if( !frame.empty() ) | ||
| + |        { detectAndDisplay( frame ); } | ||
| + |       else | ||
| + |        { printf(" --(!) No captured frame -- Break!"); break; } | ||
| + | |||
| + |       int c = waitKey(10); | ||
| + |       if( (char)c == 'c' ) { break; } | ||
| + | |||
| + |     } | ||
| + |   } | ||
| + |   c_close_device (handle); | ||
| + |   c_cleanup(); | ||
| + |   return 0; | ||
| + | } | ||
| + | |||
| + | /** | ||
| + |  * @function detectAndDisplay | ||
| + |  */ | ||
| + | void detectAndDisplay( Mat &frame ) | ||
| + | { | ||
| + |    std::vector<Rect> faces; | ||
| + |    Mat frame_gray; | ||
| + |    CResult cresult_con; | ||
| + |    cvtColor( frame, frame_gray, CV_BGR2GRAY ); | ||
| + |    equalizeHist( frame_gray, frame_gray ); | ||
| + | |||
| + | //-- Carre de visé pour la motorisation | ||
| + |    rectangle( frame, cvPoint( (largeur - viseur_mot) / 2, (hauteur + viseur_mot) / 2), | ||
| + | 	      cvPoint( (largeur + viseur_mot) / 2 , (hauteur - viseur_mot) / 2), Scalar( 0, 0, 255 ),2 ); | ||
| + | |||
| + | //-- Detect faces  | ||
| + |    face_cascade.detectMultiScale( frame_gray, faces, 1.1, 2, 0|CV_HAAR_SCALE_IMAGE, Size(30, 30) ); | ||
| + |     if (faces.size() < 1 ) | ||
| + |     { | ||
| + |       reset_centre++; | ||
| + |       if (reset_centre > 200) | ||
| + |       { | ||
| + | 	  CControlValue CCContValue; | ||
| + | 	  CCContValue.value=1; | ||
| + | 	  c_set_control(handle, CC_TILT_RESET, &CCContValue); | ||
| + | 	  usleep(2500000); | ||
| + | 	  c_set_control(handle, CC_PAN_RESET, &CCContValue); | ||
| + | 	  usleep(2500000);  | ||
| + | 	  reset_centre=-500; | ||
| + |       } | ||
| + |     } | ||
| + | |||
| + |    for( int i = 0; i < faces.size(); i++ ) | ||
| + |     { | ||
| + |       Point center( faces[i].x + faces[i].width*0.5, faces[i].y + faces[i].height*0.5 ); | ||
| + |       ellipse( frame, center, Size( faces[i].width*0.4, faces[i].height*0.6), 0, 0, 360, Scalar( 255, 0, 255 ), 2, 8, 0 ); | ||
| + | |||
| + | if  (  faces.size() == 1 ) | ||
| + | {     // depasse en x | ||
| + |       CControlValue  CCContValue; | ||
| + |       if (center.x > ((largeur + viseur_mot) / 2))  | ||
| + |       {	 | ||
| + | 	CCContValue.type = CC_TYPE_WORD; | ||
| + | 	CCContValue.value = -70; | ||
| + | 	c_set_control(handle, CC_PAN_RELATIVE, &CCContValue); | ||
| + | 	goto next; | ||
| + |       } | ||
| + | |||
| + |       if (center.x < ((largeur - viseur_mot) / 2) )  | ||
| + |       {	 | ||
| + | 	CCContValue.type = CC_TYPE_WORD; | ||
| + | 	CCContValue.value = 70; | ||
| + | 	c_set_control(handle, CC_PAN_RELATIVE, &CCContValue); | ||
| + |         goto next; | ||
| + |       } | ||
| + | |||
| + |         if (center.y > ((hauteur + viseur_mot) / 2)  )  | ||
| + |       {	 | ||
| + | 	CCContValue.type = CC_TYPE_WORD; | ||
| + | 	CCContValue.value = 70; | ||
| + | 	c_set_control(handle, CC_TILT_RELATIVE, &CCContValue); | ||
| + | 	goto next; | ||
| + |       } | ||
| + |       if (center.y < ((hauteur - viseur_mot) / 2) )  | ||
| + |       {	 | ||
| + | 	CCContValue.type = CC_TYPE_WORD; | ||
| + | 	CCContValue.value = -70; | ||
| + | 	c_set_control(handle, CC_TILT_RELATIVE, &CCContValue); | ||
| + | 	goto next; | ||
| + |       } | ||
| + |       next: | ||
| + |       reset_centre=0; | ||
| + | }     | ||
| + | |||
| + |       Mat faceROI = frame_gray( faces[i] ); | ||
| + |       imshow( "face", faceROI ); | ||
| + | |||
| + |     } | ||
| + |    //-- Show what you got | ||
| + | //   imshow( "en_gris", frame_gray ); | ||
| + |    imshow( window_name, frame );   | ||
| + | } | ||
| + | </pre> | ||
| + | <br> | ||
| + | le fichier CMakeLists.txt a mettre dans le meme repertoire: | ||
| + | <pre> | ||
| + | project( CameraVisage ) | ||
| + | FIND_PACKAGE(OpenCV REQUIRED) | ||
| + | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ") | ||
| + | # Linking (add flags as needed) | ||
| + | add_executable( CameraVisage main.cpp ) | ||
| + | target_link_libraries( CameraVisage ${OpenCV_LIBS} /usr/lib/libwebcam.so ) | ||
| + | </pre> | ||
retour vers linux
| Sommaire | 
La QuickCam Orbit est reconnu comme un périphérique UVC.
UVC: USB Video Class  en anglais
http://fr.wikipedia.org/wiki/USB_video_device_class 
Linux n'est pas le seul concerné par cette norme. Solaris, Mac OS X, ... et Windows le sont aussi.
Le driver UVC est intégré au noyau depuis la version 2.6.26. Donc rien a faire a ce niveau :-) La WebCam fonctionne avec vos logiciels habituels. 
Pour ce qui est de la motorisation, c'est ci-dessous.
Pour l'installer:
apt-get install uvcdynctrl
cela peux nécessiter l'installation de paquets supplémentaires. Si c'est le cas, apt-get vous proposera de les installer:
libwebcam0 uvcdynctrl-data
débranché la Web-Sphere usb et rebranché la.
De façon générale, en cas de dysfonctionnement, n'hesitez pas a la débrancher et la rebrancher avant de pousser trop loin vos investigations. (il existe une autre solution par ligne de commande pour réinitialiser les périphériques usb avec les outils udev, mais je ne l'ai plus en mémoire.)
Cet outil, en ligne de commande est a utiliser en parallèle de votre logiciel favoris de visionnement de webcam UVC.
Pour lister les périphériques accessibles par la commande uvcdynctrl
uvcdynctrl -l
 Listing available devices:
   video0   UVC Camera (046d:0994)
     Media controller device /dev/media1 doesn't exist
 ERROR: Unable to list device entities: Invalid device or device cannot be opened. (Code: 5)
Les 2 dernières lignes ne sont pas importantes. uvcdynctrl recherche par défaut des periphériques sur /dev/media*
Pour lister les formats possible de votre périphérique (par défaut /dev/video0 sinon préciser -d /dev/video34 par exemple):
uvcdynctrl -f 
Listing available frame formats for device video0:
Pixel format: MJPG (MJPEG; MIME type: image/jpeg)
  Frame size: 160x120
    Frame rates: 30, 25, 20, 15, 10, 5
  Frame size: 176x144
    Frame rates: 30, 25, 20, 15, 10, 5
  Frame size: 320x240
    Frame rates: 30, 25, 20, 15, 10, 5
  Frame size: 352x288
    Frame rates: 30, 25, 20, 15, 10, 5
  Frame size: 640x480
    Frame rates: 30, 25, 20, 15, 10, 5
  Frame size: 800x600
    Frame rates: 30, 25, 20, 15, 10, 5
  Frame size: 960x720
    Frame rates: 15, 10, 5
Pixel format: YUYV (YUV 4:2:2 (YUYV); MIME type: video/x-raw-yuv)
  Frame size: 160x120
    Frame rates: 30, 25, 20, 15, 10, 5
  Frame size: 176x144
    Frame rates: 30, 25, 20, 15, 10, 5
  Frame size: 320x240
    Frame rates: 30, 25, 20, 15, 10, 5
  Frame size: 352x288
    Frame rates: 30, 25, 20, 15, 10, 5
  Frame size: 640x480
    Frame rates: 30, 25, 20, 15, 10, 5
  Frame size: 800x600
    Frame rates: 25, 20, 15, 10, 5
  Frame size: 960x720
    Frame rates: 10, 5
  Frame size: 1600x1200
    Frame rates: 5
Voici pour ma WebCam logitech Web-Sphere
Pour lister les contrôles possibles du périphérique (par défaut /dev/video0 )
uvcdynctrl -c
Listing available controls for device /dev/video0: Brightness Contrast Saturation White Balance Temperature, Auto Gain Power Line Frequency White Balance Temperature Sharpness Backlight Compensation Exposure, Auto Exposure (Absolute) Exposure, Auto Priority Pan (relative) Tilt (relative) Pan Reset Tilt Reset Focus LED1 Mode LED1 Frequency Disable video processing Raw bits per pixel
Pour avoir le detail des paramétres pour chaque option ( par defaut /dev/video0, si defferent ajouter l'option -d /dev/video9 ou autres )
uvcdynctrl -c -v
 Listing available controls for device /dev/video0:
 Brightness
   ID      : 0x00000001,
   Type    : Dword,
   Flags   : { CAN_READ, CAN_WRITE },
   Values  : [ 0 .. 255, step size: 1 ],
   Default : 128
 Contrast
   ID      : 0x00000002,
   Type    : Dword,
   Flags   : { CAN_READ, CAN_WRITE },
   Values  : [ 0 .. 255, step size: 1 ],
   Default : 32
 Saturation
   ID      : 0x00000004,
   Type    : Dword,
   Flags   : { CAN_READ, CAN_WRITE },
   Values  : [ 0 .. 255, step size: 1 ],
   Default : 32
 White Balance Temperature, Auto
   ID      : 0x00000009,
   Type    : Boolean,
   Flags   : { CAN_READ, CAN_WRITE },
   Values  : [ 0 .. 1, step size: 1 ],
   Default : 1
 Gain
   ID      : 0x00000003,
   Type    : Dword,
   Flags   : { CAN_READ, CAN_WRITE },
   Values  : [ 0 .. 255, step size: 1 ],
   Default : 0
 Power Line Frequency
   ID      : 0x0000000d,
   Type    : Choice,
   Flags   : { CAN_READ, CAN_WRITE },
   Values  : { 'Disabled'[0], '50 Hz'[1], '60 Hz'[2] },
   Default : 2
 White Balance Temperature
   ID      : 0x00000008,
   Type    : Dword,
   Flags   : { CAN_READ, CAN_WRITE },
   Values  : [ 0 .. 10000, step size: 10 ],
   Default : 4000
 Sharpness
   ID      : 0x00000007,
   Type    : Dword,
   Flags   : { CAN_READ, CAN_WRITE },
   Values  : [ 0 .. 255, step size: 1 ],
   Default : 224
 Backlight Compensation
   ID      : 0x0000000c,
   Type    : Dword,
   Flags   : { CAN_READ, CAN_WRITE },
   Values  : [ 0 .. 2, step size: 1 ],
   Default : 1
 Exposure, Auto
   ID      : 0x0000000f,
   Type    : Choice,
   Flags   : { CAN_READ, CAN_WRITE },
   Values  : { 'Manual Mode'[1], 'Aperture Priority Mode'[3] },
   Default : 3
 Exposure (Absolute)
   ID      : 0x00000011,
   Type    : Dword,
   Flags   : { CAN_READ, CAN_WRITE },
   Values  : [ 1 .. 10000, step size: 1 ],
   Default : 166
 Exposure, Auto Priority
   ID      : 0x00000010,
   Type    : Boolean,
   Flags   : { CAN_READ, CAN_WRITE },
   Values  : [ 0 .. 1, step size: 1 ],
   Default : 0
 Pan (relative)
   ID      : 0x0000001c,
   Type    : Dword,
   Flags   : { CAN_READ, CAN_WRITE },
   Values  : [ -4480 .. 4480, step size: 0 ],
   Default : 0
 Tilt (relative)
   ID      : 0x0000001e,
   Type    : Dword,
   Flags   : { CAN_READ, CAN_WRITE },
   Values  : [ -1920 .. 1920, step size: 0 ],
   Default : 0
 Pan Reset
   ID      : 0x00000022,
   Type    : Button,
   Flags   : { CAN_READ, CAN_WRITE },
   Values  : [ 0 .. 0, step size: 0 ],
   Default : 0
 Tilt Reset
   ID      : 0x00000023,
   Type    : Button,
   Flags   : { CAN_READ, CAN_WRITE },
   Values  : [ 0 .. 0, step size: 0 ],
   Default : 0
 Focus
   ID      : 0x00000014,
   Type    : Dword,
   Flags   : { CAN_READ, CAN_WRITE },
   Values  : [ 0 .. 255, step size: 1 ],
   Default : 0
 LED1 Mode
   ID      : 0x046d0003,
   Type    : Choice,
   Flags   : { CAN_READ, CAN_WRITE, IS_CUSTOM },
   Values  : { 'Off'[0], 'On'[1], 'Blinking'[2], 'Auto'[3] },
   Default : 3
 LED1 Frequency
   ID      : 0x046d0004,
   Type    : Dword,
   Flags   : { CAN_READ, CAN_WRITE, IS_CUSTOM },
   Values  : [ 0 .. 255, step size: 1 ],
   Default : 0
 Disable video processing
   ID      : 0x046d0005,
   Type    : Boolean,
   Flags   : { CAN_READ, CAN_WRITE, IS_CUSTOM },
   Values  : [ 0 .. 1, step size: 1 ],
   Default : 0
 Raw bits per pixel
   ID      : 0x046d0006,
   Type    : Dword,
   Flags   : { CAN_READ, CAN_WRITE, IS_CUSTOM },
   Values  : [ 0 .. 1, step size: 1 ],
   Default : 0
Pour la motorisation, se sont les 4 options lié a Pan et Tilt qui vont nous interesser (rien ne vous empeche de faire mumuse avec les autres :-) )
 Pan (relative)
   ID      : 0x0000001c,
   Type    : Dword,
   Flags   : { CAN_READ, CAN_WRITE },
   Values  : [ -4480 .. 4480, step size: 0 ],
   Default : 0
 Tilt (relative)
   ID      : 0x0000001e,
   Type    : Dword,
   Flags   : { CAN_READ, CAN_WRITE },
   Values  : [ -1920 .. 1920, step size: 0 ],
   Default : 0
 Pan Reset
   ID      : 0x00000022,
   Type    : Button,
   Flags   : { CAN_READ, CAN_WRITE },
   Values  : [ 0 .. 0, step size: 0 ],
   Default : 0
 Tilt Reset
   ID      : 0x00000023,
   Type    : Button,
   Flags   : { CAN_READ, CAN_WRITE },
   Values  : [ 0 .. 0, step size: 0 ],
   Default : 0
On peut voir que 'Pan Reset' et 'Tilt Reset' ne prennent qu'un paramètre: 0
Pour les utiliser on lancera donc la ligne de commande:
uvcdynctrl -d /dev/video0 -s 'Pan Reset' 0
Et vous verrez votre Web-Cam tourné horizontalement et revenir au centre.
uvcdynctrl -d /dev/video0 -s 'Tilt Reset' 0
Pour la voir se recentrer verticalement
Pour le paramètre 'Pan (relative)' les valeurs acceptées vont de -4480 à 4480 comme indique pour Values
Si vous tenter de lire la valeur actuel des 'Pan (relative)' et 'Tilt (relative)' par la commande
uvcdynctrl -d /dev/video0 -g 'Pan (relative)'
ou
uvcdynctrl -d /dev/video0 -g 'Tilt (relative)'
Vous aurez un beau message d'erreur:
ERROR: Unable to retrieve control value: A Video4Linux2 API call returned an unexpected error 22. (Code: 12)
Vous essayez de lire une valeur de position relative ( relative a elle meme), qui par définition est relative. C'est a dire égale a 0.
On regrette donc que ces 2 options soient en "CAN_READ", ce qui est de la responsabilité du constructeur ...
vous ne pouvez les utiliser qu'en écriture. Exemple de commande a passer:
uvcdynctrl -d /dev/video0 -s 'Pan (relative)' -- -4480
uvcdynctrl -d /dev/video0 -s 'Tilt (relative)' 1920
La 1ere commande va donc tenter de déplacer vers la droite (-) de 4480 unités ( le max accepté )par rapport a la position actuelle. La 2eme commande va tenter de deplacer vers le bas (+) de 1920 unités (le max accepter ) par rapport a la position actuelle.
#include <webcam.h> CResult c_get_control (CHandle hDevice, CControlId control_id, CControlValue *value) CResult c_set_control (CHandle hDevice, CControlId control_id, const CControlValue *value) CResult c_enum_events (CHandle hDevice, CEvent *events, unsigned int *size, unsigned int *count) CResult c_enum_frame_intervals(hDevice, pixelformat, framesize, NULL, &size, &count) CResult c_enum_frame_sizes(hDevice, pixelformat, NULL, &size, &count); CResult c_enum_pixel_formats(hDevice, NULL, &size, &count); CResult c_enum_devices(devices, &req_size, &count); CHandle c_open_device (const char *device_name) CResult c_init(void) ...
a linker a libwebcam
Un exemple de Ana Huamán tiré du tutorial de OpenCV ( http://docs.opencv.org/doc/tutorials/objdetect/cascade_classifier/cascade_classifier.html#cascade-classifier )  repris et modifié pour suivre un visage avec la motorisation. . L’idéal serait d'avoir réussi a faire fonctionner l'exemple d'origine.
Nécessite d'avoir OpenCV d'installé (voir OpenCV), libwebcam-dev et Qt4 (Les lib d'openCV ont été créé avec l’utilisation de QT4). Une seul webcam doit être connecté a Linux, La WebSphere. Mon code ajouté est un exemple a ne pas suivre, il est codé comme du script et dans un mélange de c++ et c. J'en ai honte. Quand j'aurais un peu de temps, je le reprendrais. Milles excuses pour ce code merdique. Il est du aux multitudes d'essais nécessaires. Vous verrez également des tempo...du préhistorique rendu nécessaire par la motorisation de la webcam tres rustique.
il est nécessite d'avoir le fichier haarcascade_frontalface_alt.xml de l’OpenCV dans le même répertoire que ce fichier exécutable.
/**
 * @file objectDetection.cpp
 * @author A. Huaman ( based in the classic facedetect.cpp in samples/c )
 * @brief A simplified version of facedetect.cpp, show how to load a cascade classifier and how to find objects (Face + eyes) in a video stream
 */
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <webcam.h>
#include <iostream>
#include <stdio.h>
#include <unistd.h>
using namespace std;
using namespace cv;
/** Function Headers */
void detectAndDisplay( Mat &frame );
/** Global variables */
String face_cascade_name = "haarcascade_frontalface_alt.xml";
CascadeClassifier face_cascade;
string window_name = "Capture - Face detection";
int hauteur=480;
int largeur=640;
int viseur_mot=100;
CHandle handle = 0;
int reset_centre=0;
/********************************************************************************************
 * @function main
 *********************************************************************************************/
int main( int argc, const char** argv )
{
  printf("--(!)Debut\n");
  CvCapture* capture;
  Mat frame;
   //-- 1. Load  cascade
   if( !face_cascade.load( face_cascade_name ) )
       {
        printf("--(!)Erreur de lecture du fichier haarcascade_frontalface_alt.xml\n");
        return -1; 
        }
//////////////////////////////////////////////////////////////////////////////////////////////
//    ajouter pour gerer la motorisation logitech
//    avec libwebcam pour uvc
//////////////////////////////////////////////////////////////////////////////////////////////
  CResult res = C_SUCCESS;
  res = c_init();
  if (res) 
    {	
    c_cleanup();
    res = c_init();
    if (res) 
      {
      printf("--(!)Erreur c_init de libwebcam\n");
      return -1;
      }
    }
  handle=c_open_device ("/dev/video0");
  printf("libwebcam handle=%i\n",handle);
  if ( ! handle) 
    {
    printf("--(!)Erreur open_device de libwebcam\n");
    return -1;
    }
  //-- 2. Read the video stream
  capture = cvCreateCameraCapture(-1);
  printf("--(!)Creation de capture\n");
/********************************************************************************************
 * Effectue un Reset des motorisations
 *********************************************************************************************/
  CControlValue CCContValue;
  CCContValue.value=0;
  c_set_control(handle, CC_PAN_RESET, &CCContValue);
  usleep(2500000);
  c_set_control(handle, CC_TILT_RESET, &CCContValue);
  usleep(2500000);
cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_WIDTH, static_cast<double>(largeur));
cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_HEIGHT, static_cast<double>(hauteur));
 printf("--(!)Definition de la hauteur et largeur\n");
  if( capture )
  {
     printf("--(!)Avant Entre boucle while\n");
     while( true )
    {
       
      frame = cvQueryFrame( capture );
      //-- 3. Apply the classifier to the frame
      if( !frame.empty() )
       { detectAndDisplay( frame ); }
      else
       { printf(" --(!) No captured frame -- Break!"); break; }
      int c = waitKey(10);
      if( (char)c == 'c' ) { break; }
    }
  }
  c_close_device (handle);
  c_cleanup();
  return 0;
}
/**
 * @function detectAndDisplay
 */
void detectAndDisplay( Mat &frame )
{
   std::vector<Rect> faces;
   Mat frame_gray;
   CResult cresult_con;
   cvtColor( frame, frame_gray, CV_BGR2GRAY );
   equalizeHist( frame_gray, frame_gray );
//-- Carre de visé pour la motorisation
   rectangle( frame, cvPoint( (largeur - viseur_mot) / 2, (hauteur + viseur_mot) / 2),
	      cvPoint( (largeur + viseur_mot) / 2 , (hauteur - viseur_mot) / 2), Scalar( 0, 0, 255 ),2 );
   
//-- Detect faces 
   face_cascade.detectMultiScale( frame_gray, faces, 1.1, 2, 0|CV_HAAR_SCALE_IMAGE, Size(30, 30) );
    if (faces.size() < 1 )
    {
      reset_centre++;
      if (reset_centre > 200)
      {
	  CControlValue CCContValue;
	  CCContValue.value=1;
	  c_set_control(handle, CC_TILT_RESET, &CCContValue);
	  usleep(2500000);
	  c_set_control(handle, CC_PAN_RESET, &CCContValue);
	  usleep(2500000); 
	  reset_centre=-500;
      }
    }
    
   for( int i = 0; i < faces.size(); i++ )
    {
      Point center( faces[i].x + faces[i].width*0.5, faces[i].y + faces[i].height*0.5 );
      ellipse( frame, center, Size( faces[i].width*0.4, faces[i].height*0.6), 0, 0, 360, Scalar( 255, 0, 255 ), 2, 8, 0 );
      
if  (  faces.size() == 1 )
{     // depasse en x
      CControlValue  CCContValue;
      if (center.x > ((largeur + viseur_mot) / 2)) 
      {	
	CCContValue.type = CC_TYPE_WORD;
	CCContValue.value = -70;
	c_set_control(handle, CC_PAN_RELATIVE, &CCContValue);
	goto next;
      }
      
      if (center.x < ((largeur - viseur_mot) / 2) ) 
      {	
	CCContValue.type = CC_TYPE_WORD;
	CCContValue.value = 70;
	c_set_control(handle, CC_PAN_RELATIVE, &CCContValue);
        goto next;
      }
        if (center.y > ((hauteur + viseur_mot) / 2)  ) 
      {	
	CCContValue.type = CC_TYPE_WORD;
	CCContValue.value = 70;
	c_set_control(handle, CC_TILT_RELATIVE, &CCContValue);
	goto next;
      }
      if (center.y < ((hauteur - viseur_mot) / 2) ) 
      {	
	CCContValue.type = CC_TYPE_WORD;
	CCContValue.value = -70;
	c_set_control(handle, CC_TILT_RELATIVE, &CCContValue);
	goto next;
      }
      next:
      reset_centre=0;
}    
      
      Mat faceROI = frame_gray( faces[i] );
      imshow( "face", faceROI );
    
    }
   //-- Show what you got
//   imshow( "en_gris", frame_gray );
   imshow( window_name, frame );  
}
le fichier CMakeLists.txt a mettre dans le meme repertoire:
project( CameraVisage )
FIND_PACKAGE(OpenCV REQUIRED)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ")
# Linking (add flags as needed)
add_executable( CameraVisage main.cpp )
target_link_libraries( CameraVisage ${OpenCV_LIBS} /usr/lib/libwebcam.so )