Re: OpenCV Webcamera resolution

View: New views
3 Messages — Rating Filter:   Alert me  

Re: OpenCV Webcamera resolution

by Stephen DiVerdi :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


> If nobody complains I'll change cvCreateCameraCapture() to
>
> CVAPI(CvCapture*) cvCreateCameraCapture(int index, int width CV_DEFAULT(0),
> int height CV_DEFAULT(0), double framerate CV_DEFAULT(0));
>

hi, poking my head in here once again.  i haven't used OpenCV in around a
year now, as i finished my phd and went on to a job where we're using in
house computer vision code.  but a few years ago i submitted a patch
(against beta 5, so pre 1.0) that set up the API like this

typedef double CvCaptureProperties;

CVAPI(CvCapture*) cvCaptureFromCAM( int index, CvCaptureProperties *props = NULL );

#define CV_CAP_PROP_POS_MSEC           0
#define CV_CAP_PROP_POS_FRAMES         1
#define CV_CAP_PROP_POS_AVI_RATIO      2
#define CV_CAP_PROP_FRAME_WIDTH        3
#define CV_CAP_PROP_FRAME_HEIGHT       4
#define CV_CAP_PROP_FPS                5
#define CV_CAP_PROP_FOURCC             6
#define CV_CAP_PROP_FRAME_COUNT        7
#define CV_CAP_PROP_EXPOSURE           8
#define CV_CAP_PROP_WHITE_BALANCE_U_B  9
#define CV_CAP_PROP_WHITE_BALANCE_V_R  10
#define CV_CAP_PROP_GAIN               11

#define CV_CAP_PROP_AUTO    -1.0

#define CV_CAP_PROP_FOURCC_RGB     0x38424752  /* RGB8 */
#define CV_CAP_PROP_FOURCC_YUV444  0x32555949  /* IYU2 */
#define CV_CAP_PROP_FOURCC_YUV422  0x32323459  /* Y422 */
#define CV_CAP_PROP_FOURCC_YUV411  0x31555949  /* IYU1 */
#define CV_CAP_PROP_FOURCC_MONO    0x30303859  /* Y800 */
#define CV_CAP_PROP_FOURCC_MONO16  0x30363159  /* Y160 */
#define CV_CAP_PROP_FOURCC_RAW8    0x38305752  /* RW08 */
#define CV_CAP_PROP_FOURCC_RAW16   0x36315752  /* RW16 */

and let you write code like this to set your capture parameters

     CvCaptureProperties properties[ 9 ] = {
       CV_CAP_PROP_FOURCC,       CV_CAP_PROP_FOURCC_YUV411,
       CV_CAP_PROP_FRAME_WIDTH,  640,
       CV_CAP_PROP_FRAME_HEIGHT, 480,
       CV_CAP_PROP_FPS,          30.0,
       -1 };
     capture = cvCaptureFromCAM( 0, properties );

we used this code in our lab for a couple years, but i think people are
finally moving over to 1.0 now - as new projects start up, new students
are moving to a new codebase.  our old one was tied to gcc3.x, an old
ffmpeg, and beta 5 because of various changes to opencv we made, like the
above.  unfortunately, i don't believe the patches were ever ported to the
1.0 codebase.

anyway, the nice thing about using a properties struct is you can request
as many or as few features as you like without having to put a lot of
default property arguments into a function call because the one you want
to set happens to be at the end.  also, this provides a mechanism for
cvCaptureFromCAM to use the struct for output as well, to say what the
final properties are (to allow for making a best effort).  it might be
more useful to have a struct then, with a flags field that says which
properties are requested and which the user doesn't care about. *shrug*

happy coding. =)  i really appreciate all the hard work that's gone into
OpenCV - it made large portions of my thesis research a million times
easier.

-stephen diverdi
-stephen.diverdi@...

-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference
Don't miss this year's exciting event. There's still time to save $100.
Use priority code J8TL2D2.
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
_______________________________________________
Opencvlibrary-devel mailing list
Opencvlibrary-devel@...
https://lists.sourceforge.net/lists/listinfo/opencvlibrary-devel

Re: OpenCV Webcamera resolution

by Nils Hasler-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Stephen,

2008/4/27 Stephen DiVerdi <sdiverdi@...>:
>  > If nobody complains I'll change cvCreateCameraCapture() to
>
>  hi, poking my head in here once again.  i haven't used OpenCV in around a
>  year now, as i finished my phd and went on to a job where we're using in
>  house computer vision code.  but a few years ago i submitted a patch
>  (against beta 5, so pre 1.0) that set up the API like this

Thanks for complaining. I like your approach. I have also found the
original thread. Everybody seemed to like it but apparently nobody
checked it in. Unfortunately, SourceForge does not archive attachments
and my personal archives don't go that far back. So your patch is
basically lost.

You don't by any chance still have the original patch, do you?
The last version of your patch was sent on 2006-04-18.


cheers,
nils

--
Max-Planck-Institut Informatik
Campus E1 4, D-66123 Saarbrücken
Phone: +49 681 9325-420
www.mpi-inf.mpg.de/~hasler

-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference
Don't miss this year's exciting event. There's still time to save $100.
Use priority code J8TL2D2.
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
_______________________________________________
Opencvlibrary-devel mailing list
Opencvlibrary-devel@...
https://lists.sourceforge.net/lists/listinfo/opencvlibrary-devel

Parent Message unknown Re: OpenCV Webcamera resolution

by Stephen DiVerdi :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

>
> Thanks for complaining. I like your approach. I have also found the
> original thread. Everybody seemed to like it but apparently nobody
> checked it in. Unfortunately, SourceForge does not archive attachments
> and my personal archives don't go that far back. So your patch is
> basically lost.
>
> You don't by any chance still have the original patch, do you?
> The last version of your patch was sent on 2006-04-18.
>
Yep, I do - it's attached.

There are a few things about it that are less than ideal...like the fact that
CvCaptureProperties is a double, and that all those #defs are passed in through
a double array.  Better would be an int array, but the reason I did double was
because of framerates like 7.5.  There are #defs for framerates like
FRAMERATE_7_5, but they're not exposed as part of the OpenCV API (they're part
of dc1394?).  I just didn't feel like writing the lines to make
CV_CAP_PROP_FRAMERATE_7_5, but that'd probably be a better way to go...and then
to make the last element of the array 0, which is slightly more standard when
using arrays to pass variable numbers of arguments like this (hmm, but looking
back the problem here is CV_CAP_PROP_POS_MSEC is alreadly #def'd to 0, so
that's a conflict).

As to how to handle making requests and reporting what's available, OpenGL does
something where you create a format query and then ask "hey can you support
this" and the API returns yes or no.  Can make it difficult to guess a
compatible format, but on the other hand, somehow trying to return a set of
ranged values that intersect w/ one another is quite complicated - e.g. the
camera I used before supported 640x480 at 30Hz only at yuv411, but at 15Hz at
RGB (or something like that).

I guess what you'd _really_ like is to be able to say "these are the hard
requirements for my video, and these are my preferences for the remainders."
So you could say that you require 640x480 and you want the best framerate, but
you don't care so much about color fidelity - then it could pick 640x480, 30Hz,
yuv411.  On the other hand, if color fidelity was more important, it would pick
15Hz, RGB.  But that might be getting to the point of unecessarily complicated
- how many people use OpenCV to work with any camera they come across w/o
tuning?

Some other thoughts...some of these paramters are things that should be
settable dynamically, not just at initialization, like white balance, exposure
and gain.  So the cvSetCaptureProperty function is still good (if it were
actually implemented - I may have a patch for that around somewhere too).
Whereas setting stuff like framerate or resolution dynamically would likely
require reinitializing the camera (dc1394 does, for instance) - in these cases,
cvSetCaptureProperty should _really_ return an error code or some indication
that it's not suppported.

Also, with the ability to request non-RGB color formats, it would be nice if
cvQueryFrame didn't always return a 3-channel image.  Case in point is if you
have a camera (which we did) that supports super fast pre-bayer filtered 8-bit
images, then you need to de-bayer it manually.  However, de-bayering code often
expects 1-channel images.  Not that you couldn't extract one channel and use
that, but the fact that three channels are being set is unecessary.  You may
also want "raw" yuv411 instead of converted into rgb (say you only want the u
and v channels).  In general, these kinds of considerations came up a fair
amount as we were trying to keep the performance footprint of the camera code
as small as possible, and found ourselves doing a lot of work converting
formats around (and on the CPU!  if we were doing GPU processing, this kind of
stuff was never a problem).

Anyway, that's my brain dump from two years ago I guess. =)

-stephen diverdi
-stephen.diverdi@...
diff -urN opencv-0.9.7.orig/otherlibs/highgui/cvcap.cpp opencv-0.9.7/otherlibs/highgui/cvcap.cpp
--- opencv-0.9.7.orig/otherlibs/highgui/cvcap.cpp 2005-07-26 06:14:23.000000000 -0700
+++ opencv-0.9.7/otherlibs/highgui/cvcap.cpp 2006-04-11 11:55:36.000000000 -0700
@@ -914,7 +914,7 @@
 //#endif //WIN32
 
 
-CV_IMPL CvCapture* cvCaptureFromCAM( int index )
+CV_IMPL CvCapture* cvCaptureFromCAM( int index, CvCaptureProperties properties )
 {
     int i, domains[] = { CV_CAP_IEEE1394, CV_CAP_VFW, CV_CAP_MIL, -1 };
 
@@ -1452,7 +1452,7 @@
 #endif  // HAVE_FFMPEG
 
 
-CV_IMPL CvCapture* cvCaptureFromCAM( int index )
+CV_IMPL CvCapture* cvCaptureFromCAM( int index, CvCaptureProperties *properties )
 {
     CvCapture* cap = NULL;
 #if !defined HAVE_DC1394 && !defined HAVE_CAMV4L
@@ -1460,7 +1460,7 @@
                      "(rebuild with DC1394 and/or V4L support)\n" );
 #else
 #ifdef HAVE_DC1394
-    cap = icvOpenCAM_DC1394( index );
+    cap = icvOpenCAM_DC1394( index, properties );
 #endif
 #ifdef HAVE_CAMV4L
     if( !cap )
diff -urN opencv-0.9.7.orig/otherlibs/highgui/cvcap_dc1394.cpp opencv-0.9.7/otherlibs/highgui/cvcap_dc1394.cpp
--- opencv-0.9.7.orig/otherlibs/highgui/cvcap_dc1394.cpp 2004-09-02 00:01:39.000000000 -0700
+++ opencv-0.9.7/otherlibs/highgui/cvcap_dc1394.cpp 2006-04-17 20:19:25.000000000 -0700
@@ -205,7 +205,180 @@
    }
 };
 
-CvCapture* icvOpenCAM_DC1394( int index ){
+typedef struct
+{
+  // input
+  int width;
+  int height;
+  float fps;
+  int fourcc;
+
+  // output
+  int format;
+  int mode;
+  int frame_rate;
+} CvCapturePropertiesRequest_DC1394;
+
+void icvModeFromProperties_DC1394( CvCaptureProperties *prop,
+                                   CvCapturePropertiesRequest_DC1394 *req )
+{
+  if( prop == NULL || req == NULL )
+    return;
+
+  for( int i = 0 ; ( int )prop[ i ] >= 0 ; ++i )
+  {
+    switch( ( int )prop[ i ] )
+    {
+    case CV_CAP_PROP_FRAME_WIDTH:
+      req->width = ( int )prop[ ++i ];
+      break;
+
+    case CV_CAP_PROP_FRAME_HEIGHT:
+      req->height = ( int )prop[ ++i ];
+      break;
+
+    case CV_CAP_PROP_FOURCC:
+      req->fourcc = ( int )prop[ ++i ];
+      break;
+
+    case CV_CAP_PROP_FPS:
+      req->fps = ( float )prop[ ++i ];
+      break;
+
+    default:
+      return;
+      break;
+    }
+  }
+
+  if( req->fps == 1.857 )
+    req->frame_rate = FRAMERATE_1_875;
+  else if( req->fps == 3.75 )
+    req->frame_rate = FRAMERATE_3_75;
+  else if( req->fps == 7.5 )
+    req->frame_rate = FRAMERATE_7_5;
+  else if( req->fps == 15 )
+    req->frame_rate = FRAMERATE_15;
+  else if( req->fps == 30 )
+    req->frame_rate = FRAMERATE_30;
+  else if( req->fps == 60 )
+    req->frame_rate = FRAMERATE_60;
+  else if( req->fps == 120 )
+    req->frame_rate = FRAMERATE_120;
+  else if( req->fps == 240 )
+    req->frame_rate = FRAMERATE_240;
+
+  enum { _160x120 = 0, _320x240, _640x480, _800x600, _1024x768, _1280x960, _1600x1200 } dim;
+
+  if( req->width == 160 && req->height == 120 )
+    dim = _160x120;
+  else if( req->width == 320 && req->height == 240 )
+    dim = _320x240;
+  else if( req->width == 640 && req->height == 480 )
+    dim = _640x480;
+  else if( req->width == 800 && req->height == 600 )
+    dim = _800x600;
+  else if( req->width == 1024 && req->height == 768 )
+    dim = _1024x768;
+  else if( req->width == 1280 && req->height == 960 )
+    dim = _1280x960;
+  else if( req->width == 1600 && req->height == 1200 )
+    dim = _1600x1200;
+  else
+    return;
+
+  switch( dim )
+  {
+  case _160x120:
+  case _320x240:
+  case _640x480:
+    req->format = FORMAT_VGA_NONCOMPRESSED;
+    break;
+
+  case _800x600:
+  case _1024x768:
+    req->format = FORMAT_SVGA_NONCOMPRESSED_1;
+    break;
+
+  case _1280x960:
+  case _1600x1200:
+    req->format = FORMAT_SVGA_NONCOMPRESSED_2;
+    break;
+  }
+
+  switch( req->fourcc )
+  {
+  case CV_CAP_PROP_FOURCC_RGB:
+    switch( dim )
+    {
+    case _640x480:   req->mode = MODE_640x480_RGB;   break;
+    case _800x600:   req->mode = MODE_800x600_RGB;   break;
+    case _1024x768:  req->mode = MODE_1024x768_RGB;  break;
+    case _1280x960:  req->mode = MODE_1280x960_RGB;  break;
+    case _1600x1200: req->mode = MODE_1600x1200_RGB; break;
+    default: break;
+    }
+    break;
+
+  case CV_CAP_PROP_FOURCC_YUV444:
+    switch( dim )
+    {
+    case _160x120: req->mode = MODE_160x120_YUV444; break;
+    default: break;
+    }
+    break;
+
+  case CV_CAP_PROP_FOURCC_YUV422:
+    switch( dim )
+    {
+    case _320x240:   req->mode = MODE_320x240_YUV422;   break;
+    case _640x480:   req->mode = MODE_640x480_YUV422;   break;
+    case _800x600:   req->mode = MODE_800x600_YUV422;   break;
+    case _1024x768:  req->mode = MODE_1024x768_YUV422;  break;
+    case _1280x960:  req->mode = MODE_1280x960_YUV422;  break;
+    case _1600x1200: req->mode = MODE_1600x1200_YUV422; break;
+    default: break;
+    }
+    break;
+
+  case CV_CAP_PROP_FOURCC_YUV411:
+    switch( dim )
+    {
+    case _640x480: req->mode = MODE_640x480_YUV411; break;
+    default: break;
+    }
+    break;
+
+  case CV_CAP_PROP_FOURCC_MONO:
+    switch( dim )
+    {
+    case _640x480:   req->mode = MODE_640x480_MONO;   break;
+    case _800x600:   req->mode = MODE_800x600_MONO;   break;
+    case _1024x768:  req->mode = MODE_1024x768_MONO;  break;
+    case _1280x960:  req->mode = MODE_1280x960_MONO;  break;
+    case _1600x1200: req->mode = MODE_1600x1200_MONO; break;
+    default: break;
+    }
+    break;
+
+  case CV_CAP_PROP_FOURCC_MONO16:
+    switch( dim )
+    {
+    case _640x480:   req->mode = MODE_640x480_MONO16;   break;
+    case _800x600:   req->mode = MODE_800x600_MONO16;   break;
+    case _1024x768:  req->mode = MODE_1024x768_MONO16;  break;
+    case _1280x960:  req->mode = MODE_1280x960_MONO16;  break;
+    case _1600x1200: req->mode = MODE_1600x1200_MONO16; break;
+    default: break;
+    }
+    break;
+
+  default:
+    break;
+  }
+}
+
+CvCapture* icvOpenCAM_DC1394( int index, CvCaptureProperties *properties ){
     quadlet_t framerates, modes[8], formats;
     int i;
 
@@ -248,6 +421,32 @@
    int format = -1;
    int format_min = 0;
 
+   CvCapturePropertiesRequest_DC1394 propreq;
+   propreq.width      = 0;
+   propreq.height     = 0;
+   propreq.fps        = 0;
+   propreq.fourcc     = 0;
+   propreq.format     = 0;
+   propreq.mode       = 0;
+   propreq.frame_rate = 0;
+
+   // try out what we got from the properties
+   if( properties != NULL )
+   {
+      icvModeFromProperties_DC1394( properties, &propreq );
+      if( propreq.format != 0 && propreq.mode != 0 )
+      {
+         format = propreq.format - FORMAT_MIN;
+         format_min = MODE_FORMAT0_MIN + 32 * format;
+         if( ( formats & ( 0x1 << ( 31 - format ) ) ) &&
+             ( modes[ format ] & ( 0x1 << ( 31 - ( propreq.mode - format_min ) ) ) ) )
+         {
+            pcap->format = propreq.format;
+            pcap->mode = propreq.mode;
+         }
+      }
+   }
+
    // scan the list of preferred modes, and find a supported one
    for(i=0; (pcap->mode == 0) && (preferred_modes[i] != 0); i++) {
        if((preferred_modes[i] >= FORMAT_MIN) && (preferred_modes[i] <= FORMAT_MAX)) {
@@ -333,7 +532,15 @@
        fprintf(stderr,"%s:%d: Could not query supported framerates\n",__FILE__,__LINE__);
        framerates = 0;
    }
-   for (int f=FRAMERATE_MAX; f>=FRAMERATE_MIN; f--) {
+
+   // try what was requested by the properties first
+   if( propreq.frame_rate > 0 &&
+       ( framerates & ( 0x1 << ( 31 - ( propreq.frame_rate - FRAMERATE_MIN ) ) ) ) )
+   {
+     pcap->frame_rate = propreq.frame_rate;
+   }
+  
+   for (int f=FRAMERATE_MAX; pcap->frame_rate == 0 && f>=FRAMERATE_MIN; f--) {
        if (framerates & (0x1<< (31-(f-FRAMERATE_MIN)))) {
            pcap->frame_rate = f;
            f = FRAMERATE_MIN;
diff -urN opencv-0.9.7.orig/otherlibs/highgui/_highgui.h opencv-0.9.7/otherlibs/highgui/_highgui.h
--- opencv-0.9.7.orig/otherlibs/highgui/_highgui.h 2005-02-01 03:33:24.000000000 -0800
+++ opencv-0.9.7/otherlibs/highgui/_highgui.h 2006-04-11 11:56:08.000000000 -0700
@@ -104,7 +104,7 @@
 CvCapture* icvOpenCAM_V4L( int wIndex );
 #endif
 #ifdef HAVE_DC1394
-CvCapture* icvOpenCAM_DC1394( int wIndex );
+CvCapture* icvOpenCAM_DC1394( int wIndex, CvCaptureProperties *properties );
 #endif
 #endif
 
diff -urN opencv-0.9.7.orig/otherlibs/highgui/highgui.h opencv-0.9.7/otherlibs/highgui/highgui.h
--- opencv-0.9.7.orig/otherlibs/highgui/highgui.h 2005-07-05 08:52:50.000000000 -0700
+++ opencv-0.9.7/otherlibs/highgui/highgui.h 2006-04-11 11:56:04.000000000 -0700
@@ -212,8 +212,10 @@
 #define CV_CAP_DC1394   300
 #define CV_CAP_CMU1394  300
 
+typedef float CvCaptureProperties;
+
 /* start capturing frames from camera: index = camera_index + domain_offset (CV_CAP_*) */
-CVAPI(CvCapture*) cvCaptureFromCAM( int index );
+CVAPI(CvCapture*) cvCaptureFromCAM( int index, CvCaptureProperties *props = NULL );
 
 /* grab a frame, return 1 on success, 0 on fail.
   this function is thought to be fast               */  
@@ -241,6 +243,13 @@
 #define CV_CAP_PROP_FOURCC         6
 #define CV_CAP_PROP_FRAME_COUNT    7
 
+#define CV_CAP_PROP_FOURCC_RGB     0x32424752
+#define CV_CAP_PROP_FOURCC_YUV444  0x32555949
+#define CV_CAP_PROP_FOURCC_YUV422  0x32323459
+#define CV_CAP_PROP_FOURCC_YUV411  0x31555949
+#define CV_CAP_PROP_FOURCC_MONO    0x30303859
+#define CV_CAP_PROP_FOURCC_MONO16  0x30363159
+
 /* retrieve or set capture properties */
 CVAPI(double) cvGetCaptureProperty( CvCapture* capture, int property_id );
 CVAPI(int)    cvSetCaptureProperty( CvCapture* capture, int property_id, double value );

-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference
Don't miss this year's exciting event. There's still time to save $100.
Use priority code J8TL2D2.
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
_______________________________________________
Opencvlibrary-devel mailing list
Opencvlibrary-devel@...
https://lists.sourceforge.net/lists/listinfo/opencvlibrary-devel
LightInTheBox - Buy quality products at wholesale price