Capturing 1080p at 30fps from logitech c920 with openCV 2.4.3
Asked Answered
G

3

24

I'm trying to capture the video stream off of my Logitech C920 in OpenCV. With Labview I can access an MJPG stream at 30fps 1080p. In opencv I am limited to either 5fps or 640x480.

Here is the code relevant to the camera settings:

this->camRef.set(CV_CAP_PROP_FRAME_WIDTH, 1920);
this->camRef.set(CV_CAP_PROP_FRAME_HEIGHT, 1080);
this->camRef.set(CV_CAP_PROP_FOURCC,CV_FOURCC('M','J','P','G'));

These all return 1, yet I get a 5fps stream of 1080p which corresponds to the YUY2 stream.
If I add the following line:

this->camRef.set(CV_CAP_PROP_FPS, 30);

This returns 0. I get a 30 fps stream at 640x480. To me it looks like the MJPG setting isn't be accepted but I don't know what to do or how to fix that.

EDIT: The following crashes the program.

 this->camRef.read(this->image);
 std::cout<< this->camRef.get(CV_CAP_PROP_FOURCC)                            << std::endl;
 std::cout<< this->camRef.set(CV_CAP_PROP_FRAME_WIDTH, config.width)         << std::endl;
 std::cout<< this->camRef.set(CV_CAP_PROP_FRAME_HEIGHT, config.height)       << std::endl;
 std::cout<< this->camRef.set(CV_CAP_PROP_FOURCC,CV_FOURCC('M','J','P','G')) << std::endl;
 std::cout<< this->camRef.get(CV_CAP_PROP_FOURCC)                            << std::endl;

Then in my run code I have the following:

void camera::run()
{
    while(true)
    {
        if(this->camRef.read(this->image) == 0)
        {
           if(this->capture)
            {
                cv::imwrite(fileName,this->image);
                this->count++;
            }
        }
        msleep(15);
    }
}

EDIT2: Solution is to set the fourCC codec before setting camera height and width.

Giorgia answered 18/4, 2013 at 20:49 Comment(2)
if you want to set fps(must be supported by camera), you have to do it after codec setting, but before width/height settingsFayalite
Sounds like your EDIT2 gave you 1080p at 30fps. Should be turned into an answer and accepted then to make the problem appear solved.Battleax
F
15

As the author of the post already found the solution but didn't add it as an answer I will put the solution here.

You have to set the codec before you set the wanted resolution:

this->camRef.set(CV_CAP_PROP_FOURCC,CV_FOURCC('M','J','P','G'));
this->camRef.set(CV_CAP_PROP_FRAME_WIDTH, 1920);
this->camRef.set(CV_CAP_PROP_FRAME_HEIGHT, 1080);
Fez answered 18/4, 2013 at 20:49 Comment(1)
Thanks! It worked as stated! On the other hand, I'd like to mention that although this will allow the fullHD@30 resolution, image quality may be very poor (compression rate has to be high in order to meet with the bandwidth restriction of USB 2.0)Countryside
S
3

working with logitech c922, needed:

capture.open(CV_CAP_DSHOW);
capture.set(CV_CAP_PROP_FOURCC, CV_FOURCC('M', 'J', 'P', 'G'));
capture.set(CV_CAP_PROP_FRAME_WIDTH, 1920);
capture.set(CV_CAP_PROP_FRAME_HEIGHT, 1080);
Sup answered 19/8, 2018 at 15:46 Comment(0)
C
1

Try to get first frame from capture before setting anything:

VideoCapture cap(0);
if(!cap.isOpened()) 
return -1;  

Mat frame;
cap >> frame;
double fps;
cap.set(CV_CAP_PROP_FRAME_HEIGHT, 1080.0);
cap.set(CV_CAP_PROP_FRAME_WIDTH, 1920.0);
//add the loop here

and check whether it will work without setting MJPG. If it will work, try with MJPG.

For me it's a bit weird that you have to get first frame before setting anything, but it's the only way it's working for me (windows 7 32bit).



//edit:
Yo may try to use different API - see second part of my answer here: https://mcmap.net/q/473671/-opencv-on-mac-is-not-opening-usb-web-camera OpenCV is trying to use the best API by default, but maybe in your case some other API will work better.

Concinnity answered 18/4, 2013 at 22:56 Comment(2)
Thank you for the reply. I tried what you said and now my code crashes before displaying an image. cap.read returns 1 and then it crashes when it tries to read again from the camera.Giorgia
I've updated the original question to show the code you requested.Giorgia

© 2022 - 2024 — McMap. All rights reserved.