Jetson nano USB camera uses openCv to open low frame rate problem

Jetson nano USB camera uses openCv to open low frame rate problem


Recently, when I was playing Jetson Nano, I found that the frame rate of openCv when opening the USB camera was only 5 frames, but it could run 30 frames under Windows. I searched the Internet for the reason and found that the default reading format of the camera is wrong. I need to change the frame rate to MJPG format before it can go up. So I used the code I found on CSDN, but none of it worked. After struggling for a long time, I suddenly thought of going to stacoverflow to have a look. I didn't expect that it was actually solved. I will record it here.

First check if the camera device exists

1.Installation tools

sudo apt install v4l-utils 

2. Check the camera

ls /dev/video* 

3. Check the detailed parameters of the camera to see if it is supported

v4l2-ctl --device=/dev/video0 --list-formats-ext

The following are the parameters of my camera. OpenCV opens in YUYV format by default, so the frame rate is low, only 5 frames.
View camera parameters
The frame rate in the default open mode. The connection solution
The default is 5 frames, stuck in ppt
to the reference website is posted below.

Complete code

Give the complete code, test it can be used, the maximum is 30 frames, because my camera can only support 30 frames

import cv2
import time

width = 640
height = 480

gs_pipeline = f"v4l2src device=/dev/video0 io-mode=2 " \
              f"! image/jpeg, width={
      
      width}, height={
      
      height}, framerate=30/1, format=MJPG " \
              f"! nvv4l2decoder mjpeg=1 " \
              f"! nvvidconv " \
              f"! video/x-raw, format=BGRx " \
              f"! videoconvert " \
              f"! video/x-raw, format=BGR " \
              f"! appsink drop=1"

cap = cv2.VideoCapture(gs_pipeline, cv2.CAP_GSTREAMER)

# 每0.1S计算一次帧率
t = 0.1
counter = 0
fps = 0
start_time = time.time()

while (True):
    ret, frame = cap.read()
    img = frame.copy()
    # 测帧率
    counter += 1
    if (time.time() - start_time) > t:
        fps = counter / (time.time() - start_time)
        fps = str(fps)
        counter = 0
        start_time = time.time()
    cv2.putText(frame, "FPS {0}".format(fps), (10, 30), 1, 1.5, (255, 0, 255), 2)

    cv2.imshow('frame', frame)
    if cv2.waitKey(1) & 0xFF == 27:
        break
cap.release()
cv2.destroyAllWindows()

This code is critical

gs_pipeline = f"v4l2src device=/dev/video0 io-mode=2 " \
              f"! image/jpeg, width={
      
      width}, height={
      
      height}, framerate=30/1, format=MJPG " \
              f"! nvv4l2decoder mjpeg=1 " \
              f"! nvvidconv " \
              f"! video/x-raw, format=BGRx " \
              f"! videoconvert " \
              f"! video/x-raw, format=BGR " \
              f"! appsink drop=1"

The explanation given by the great god:

nvvidconv doesn’t support BGR, only BGRx (thus the videoconvert for BGRx->BGR). Caps also lacks a comma. Last, videoconvert only supports system memory, so have nvvidconv to output into system memory rather than NVMM memory.

The frame rate calculation is based on the code on CSDN.
Insert image description here
Now it can run 30 frames, and you're done!

Guess you like

Origin blog.csdn.net/qq_37422050/article/details/130614438