Capturing 1080p at 30fps from logitech c920 with o

2019-02-01 08:19发布

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.

3条回答
Juvenile、少年°
2楼-- · 2019-02-01 09:07

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);
查看更多
我只想做你的唯一
3楼-- · 2019-02-01 09:11

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);
查看更多
冷血范
4楼-- · 2019-02-01 09:14

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://stackoverflow.com/a/14188280/1598485 OpenCV is trying to use the best API by default, but maybe in your case some other API will work better.

查看更多
登录 后发表回答