Ask Your Question

Revision history [back]

Can't set resolution and FPS during capturing and recording Logitech C920

Hi there, New here, I'm using Logitech C920 and OpenCV 4.1.1 with C++ and I'm trying to both capture stream from webcam using VideoCapture class and record it using VideoWriter class. I'm having problems setting my video to a desired resolution of 1280x720 (I wouldn't mind it being higher) and a framerate of 30 fps. I either get the desired resolution with a very low framerate or (I have no idea how it happens but) a resolution of 640x480 with the desired framerate. I know that this webcam is capable of streaming and recording 1920x1080@30fps because I have used Logitech's Capture software and it gets the job done, but I need to process the stream with OpenCV. I have searched online and seen that it has something to do with either the camera API or the fourCC, so I have done the following:

  • Tried to change capture fourCC using capture.set(CAP_PROP_FOURCC,....); to both MJPG and H264 but a quick check through the debugger shows that the method returns false and stays YUY2 no matter what. I have included "openh264-1.8.0-win64.dll" in the project directory
  • Tried to open the camera using CAP_DSHOW but it doesn't seem to change much at all, other APIs just fail to open the capture

Here is my code:

#include <opencv2/highgui.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/core.hpp>
#include <iostream>

#define MY_CAPTURE_WIDTH 1280
#define MY_CAPTURE_HEIGHT 720
#define MY_FPS 30

using namespace std;



int main(int argc, char* argv[])
{
cv::namedWindow("RECORDING", cv::WINDOW_AUTOSIZE);
cv::VideoCapture capture;
cv::Mat src;
capture.open(1); // the c920 is not the default webcam
if (!capture.isOpened()) {
    cerr << "ERROR! Unable to open camera\n";
    return -1;
}
// get one frame from camera to know frame size and type
capture >> src;
// check if we succeeded
if (src.empty()) {
    cerr << "ERROR! blank frame grabbed\n";
    return -1;
}
bool isColor = (src.type() == CV_8UC3);
int codec = cv::VideoWriter::fourcc('H', '2', '6', '4');
capture.set(cv::CAP_PROP_FOURCC, codec);
capture.set(cv::CAP_PROP_FRAME_WIDTH, MY_CAPTURE_WIDTH);
capture.set(cv::CAP_PROP_FRAME_HEIGHT, MY_CAPTURE_HEIGHT);
capture.set(cv::CAP_PROP_FPS, MY_FPS);
double fps = capture.get(cv::CAP_PROP_FPS);
cv::Size size(
    (int)capture.get(cv::CAP_PROP_FRAME_WIDTH),
    (int)capture.get(cv::CAP_PROP_FRAME_HEIGHT)
);
double realFOURCC = capture.get(cv::CAP_PROP_FOURCC); // checking the real stream fourCC
cv::VideoWriter writer;
writer.open("out.avi", codec,fps, size, isColor);
cv::Mat in_frame;
for (;;)
{
    capture >> in_frame;
    if (in_frame.empty())
        break;
    cv::imshow("RECORDING", in_frame);
    writer.write(in_frame);
    char c = cv::waitKey((int)(((double)(1/ fps)) * 1000));
    if (c == 27)
        break;
}
capture.release();
writer.release();
cv::destroyWindow("RECORDING");
  }

Help would be appreciated