GStreamer frame rate not consistent when displaying USB webcam

I noticed that when I display my webcam (Logitech C270), the calculated frame rate is sometimes around 15 fps and if I restart it a few seconds later it jumps to around 30 fps. But usually it’s around 15 fps. Is there a way to deliver 30 fps every time I launch it?

I tried using “video/x-raw” and “image/jpeg” but get similar results. Also, I make sure that the only window open is the terminal. Here is the code with both “video/x-raw” and “image/jpeg” that can be commented out to run either one. I’d like to use “image/jpeg” because the Logitech C270 delivers it’s max size and fps with it and not with “video/x-raw” as per the properties listed when I use gst-device-monitor-1.0.

I also get the warning below and I’m not sure how to fix it.

from imutils.video import FPS
import time
import cv2

webcam = 'v4l2src device=/dev/video0 ! video/x-raw,width=640,height=480,framerate=30/1 ! videoconvert ! appsink'
#webcam = 'v4l2src device=/dev/video0 ! image/jpeg,width=640,height=480,framerate=30/1 ! jpegparse ! jpegdec ! videoconvert ! appsink'

vs = cv2.VideoCapture(webcam)

time.sleep(2.0)
fps = FPS().start()

while True:
    ret, frame = vs.read()
    cv2.imshow("window", frame)
    if cv2.waitKey(1) & 0xFF == ord("q"):
        break
    fps.update()

fps.stop()
print("*** Elapsed time: {:.2f}".format(fps.elapsed()))
print("*** Approx. FPS: {:.2f}".format(fps.fps()))
vs.release()
cv2.destroyAllWindows()

Warning:

[ WARN:0] global /tmp/build_opencv/opencv/modules/videoio/src/cap_gstreamer.cpp (935) open OpenCV | GStreamer warning: Cannot query video position: status=1, value=1, duration=-1
*** Elapsed time: 11.41
*** Approx. FPS: 15.34

Hi,
Could you check if the issue happens if you are in bright environment? Certain USB cameras may drop framerate to have enough exposure time in low-light condition.

Thanks! It looks like brightness was the issue. It now runs at 30 fps if I shine a light at the webcam. I’m going to try to set the exposure time manually instead.

I tried adding extra-controls=s,exposure_auto=1,exposure_absolute=0.01 to the pipeline with a higher exposure time than the fps setting but it didn’t seem to make any difference. I’ll keep researching unless someone else knows how to do it on here.