2020년 2월 21일 금요일

Camera - CSI Camera (Raspberry Pi camera V2)

So far, I have been using USB cameras mainly with Jetson Nano. In this post, I'll show you how to use the Raspberry Pi camera V2 and see how it differs from USB cameras.

Raspberry Pi Camera V2 connection


Raspberry Pi cameras connect using the Camera Serial Interface (CSI).
The video from JetsonHack can help you a lot. Make sure to turn off the Jetson Nano before connecting. When connecting, pay attention to the direction of the ribbon cable.



<Raspberry Pi Camera V2 and Jetson Nano>

After connecting, boot your Jetson Nano. Then check if the camera is connected with the following command. This command can check both USB camera and CSI camera.
In the previous post, I explained in detail how to check the camera.

root@spypiggy-nano:~# ls -al /dev/video*
crw-rw----+ 1 root video 81, 0  2 20 01:33 /dev/video0
root@spypiggy-nano:~# v4l2-ctl --list-devices
vi-output, imx219 6-0010 (platform:54080000.vi:0):
        /dev/video0

You can check the camera stats on the Raspberry Pi website:


Raspberry Camera supports V4L2 driver, so you can use v4l2-ctl command to check the camera. The image sensor of Raspberry Pi camera V2 is "SONY IMX219", and you can find this  in the ablove command output. So the Raspberry Pi camera is working correctly.

Test the camera

gstreamer usage

Jetson Nano uses a gstreamer to output camera input to the screen. We will test the camera using the gst-launch-1.0 program, the gstreamer test tool.


gst-launch passes the result of the plug-in corresponding to elements to the next element via a link.
For example, in the figure, Element1 can be either a camera plug-in or a source video file, and Element2 can be a plug-in that changes the size of the frame received through Element1, and mirrors front and back. And finally, Element3 can be a plug-in that receives the frame changed by Element2 and prints it to the screen or saves it to a file.

Test the Raspberry Pi camera V2

Run this command, you can see the camera video.

root@spypiggy-nano:~#gst-launch-1.0 nvarguscamerasrc ! 'video/x-raw(memory:NVMM),width=1280, height=720, framerate=30/1, format=NV12' ! nvegltransform ! nveglglessink -e


This command has the following meaning:

 

 Adjust camera settingsvi readme.txt

Perhaps the camera you see is upside down or left, right changed. In this case, you can do this by inserting a plug-in that controls flip.
The NVIDIA proprietary nvvidconv Gstreamer-1.0 plug-in also allows you to perform video rotation operations


flip-method
Property value
no flip
0
counterclockwise - 90 degrees
1
rotate - 180 degrees
2
clockwise - 90 degrees
3
 
Before passing to the plug-in responsible for the display, you can add a flip plug in as follows:

gst-launch-1.0 nvarguscamerasrc ! 'video/x-raw(memory:NVMM),width=1280, height=720, framerate=30/1, format=NV12' ! nvvidconv flip-method=1 ! nvegltransform ! nveglglessink -e

The NVIDIA proprietary nvvidconv Gstreamer-1.0 plug-in allows you to convert between OSS (raw) video formats and NVIDIA video formats. The nvvidconv plug-in currently supports the format conversions described in this section

Therefore, make sure to go through the nvvidconv plugin before passing it to the display like this.

gst-launch-1.0 nvarguscamerasrc ! 'video/x-raw(memory:NVMM),width=1280, height=720, framerate=30/1, format=NV12' ! nvvidconv flip-method=0 ! nvvidconv !nvegltransform ! nveglglessink -e

Supported resolutions

When you run the program above, the modes supported by the current camera are displayed on the screen as follows.

GST_ARGUS: Available Sensor modes :
GST_ARGUS: 3264 x 2464 FR = 21.000000 fps Duration = 47619048 ; Analog Gain range min 1.000000, max 10.625000; Exposure Range min 13000, max 683709000;
GST_ARGUS: 3264 x 1848 FR = 28.000001 fps Duration = 35714284 ; Analog Gain range min 1.000000, max 10.625000; Exposure Range min 13000, max 683709000;
GST_ARGUS: 1920 x 1080 FR = 29.999999 fps Duration = 33333334 ; Analog Gain range min 1.000000, max 10.625000; Exposure Range min 13000, max 683709000;
GST_ARGUS: 1280 x 720 FR = 59.999999 fps Duration = 16666667 ; Analog Gain range min 1.000000, max 10.625000; Exposure Range min 13000, max 683709000;
GST_ARGUS: 1280 x 720 FR = 120.000005 fps Duration = 8333333 ; Analog Gain range min 1.000000, max 10.625000; Exposure Range min 13000, max 683709000;


Using Raspberry Pi camera V2 with python OpenCV

We are familiar with camera processing using OpenCV. So let's see how to manipulate the Raspberry Pi camera in OpenCV.
Jetson Nano's OpenCV also supports cameras using gstreamer. Therefore, once you understand the pipeline described above, you can easily manipulate the Raspberry Pi camera in OpenCV.

# MIT License
# Copyright (c) 2019 JetsonHacks
# See license
# Using a CSI camera (such as the Raspberry Pi Version 2) connected to a
# NVIDIA Jetson Nano Developer Kit using OpenCV
# Drivers for the camera and OpenCV are included in the base image

import cv2

# gstreamer_pipeline returns a GStreamer pipeline for capturing from the CSI camera
# Defaults to 1280x720 @ 60fps
# Flip the image by setting the flip_method (most common values: 0 and 2)
# display_width and display_height determine the size of the window on the screen


def gstreamer_pipeline(
    capture_width=1280,
    capture_height=720,
    display_width=1280,
    display_height=720,
    framerate=60,
    flip_method=0,
):
    return (
        "nvarguscamerasrc ! "
        "video/x-raw(memory:NVMM), "
        "width=(int)%d, height=(int)%d, "
        "format=(string)NV12, framerate=(fraction)%d/1 ! "
        "nvvidconv flip-method=%d ! "
        "video/x-raw, width=(int)%d, height=(int)%d, format=(string)BGRx ! "
        "videoconvert ! "
        "video/x-raw, format=(string)BGR ! appsink"
        % (
            capture_width,
            capture_height,
            framerate,
            flip_method,
            display_width,
            display_height,
        )
    )


def show_camera():
    # To flip the image, modify the flip_method parameter (0 and 2 are the most common)
    print(gstreamer_pipeline(flip_method=0))
    cap = cv2.VideoCapture(gstreamer_pipeline(flip_method=0), cv2.CAP_GSTREAMER)
    if cap.isOpened():
        window_handle = cv2.namedWindow("CSI Camera", cv2.WINDOW_AUTOSIZE)
        # Window
        while cv2.getWindowProperty("CSI Camera", 0) >= 0:
            ret_val, img = cap.read()
            cv2.imshow("CSI Camera", img)
            # This also acts as
            keyCode = cv2.waitKey(30) & 0xFF
            # Stop the program on the ESC key
            if keyCode == 27:
                break
        cap.release()
        cv2.destroyAllWindows()
    else:
        print("Unable to open camera")


if __name__ == "__main__":
    show_camera()


The OpenCV installed on Jetson Nano is built to work with gstreamer, so the code above runs fine.

Note :

  • The use of cv2.CAP_GSTREAMER as the second parameter in the cv2.VideoCapture function is optional. The second parameter can be omitted.
  • In the gstreamer pipline string, last video format is "BGR", because the OpenCV's default color map is BGR.
  • Notice that the last pipeline is appsink, not the screen output(nvegltransform ! nveglglessink -e).

 

Using Raspberry Pi camera and Webcam simultaneously

First connect the USB webcam to the Jetson Nano, and check the cameras.

root@spypiggy-nano:/usr/local/src/study/csi_cam# ls -al /dev/video*
crw-rw----+ 1 root video 81, 0  2 20 01:33 /dev/video0
crw-rw----+ 1 root video 81, 3  2 21 21:49 /dev/video1
root@spypiggy-nano:/usr/local/src/study/csi_cam# v4l2-ctl --list-devices
vi-output, imx219 6-0010 (platform:54080000.vi:0):
        /dev/video0

UVC Camera (046d:0825) (usb-70090000.xusb-2.1):
        /dev/video1

Notice that the USB webcam is video1. I will compare two cameras at the same time.

# MIT License
# Copyright (c) 2019 JetsonHacks
# See license
# Using a CSI camera (such as the Raspberry Pi Version 2) connected to a
# NVIDIA Jetson Nano Developer Kit using OpenCV
# Drivers for the camera and OpenCV are included in the base image

import cv2

# gstreamer_pipeline returns a GStreamer pipeline for capturing from the CSI camera
# Defaults to 1280x720 @ 60fps
# Flip the image by setting the flip_method (most common values: 0 and 2)
# display_width and display_height determine the size of the window on the screen


def gstreamer_pipeline(
    capture_width=1280,
    capture_height=720,
    display_width=640,
    display_height=480,
    framerate=60,
    flip_method=0,
):
    return (
        "nvarguscamerasrc ! "
        "video/x-raw(memory:NVMM), "
        "width=(int)%d, height=(int)%d, "
        "format=(string)NV12, framerate=(fraction)%d/1 ! "
        "nvvidconv flip-method=%d ! "
        "video/x-raw, width=(int)%d, height=(int)%d, format=(string)BGRx ! "
        "videoconvert ! "
        "video/x-raw, format=(string)BGR ! appsink"
        % (
            capture_width,
            capture_height,
            framerate,
            flip_method,
            display_width,
            display_height,
        )
    )

camSet='nvarguscamerasrc !  video/x-raw(memory:NVMM), width=3264, height=2464, format=NV12, framerate=21/1 ! nvvidconv flip-method=0 ! video/x-raw, width=640, height=480, format=BGRx ! videoconvert ! video/x-raw, format=BGR ! appsink'

def show_camera():
    # To flip the image, modify the flip_method parameter (0 and 2 are the most common)
    print(gstreamer_pipeline(flip_method=0))
    #cap = cv2.VideoCapture(gstreamer_pipeline(flip_method=0), cv2.CAP_GSTREAMER)
    csi_cap = cv2.VideoCapture(camSet)
    web_cap = cv2.VideoCapture(1)
    web_cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
    web_cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)

    if csi_cap.isOpened() and web_cap.isOpened():
        while True:
            ret_valw, imgw = web_cap.read()
            ret_val, img = csi_cap.read()
            cv2.imshow("Web Camera", imgw)
            cv2.imshow("CSI Camera", img)
           # This also acts as
            keyCode = cv2.waitKey(30) & 0xFF
            # Stop the program on the ESC key
            if keyCode == 27:
                break
        csi_cap.release()
        web_cap.release()
        cv2.destroyAllWindows()
    else:
        print("Unable to open camera")


if __name__ == "__main__":
    show_camera()
<csi_web_cam.py>



Run the code, you can see two windows for each camera.



Be careful : When I tested an old Logitech C270 Webcam, the Raspberry Pi camera output is delayed. I can't find the reason, but when I changed the webcam to the newest one, the delay has disappeared and two cameras were output at about the same time.





2020년 2월 7일 금요일

Camera - Search for supported resolutions of your webcam

There are many different types of webcams on the market. Therefore, knowing exactly what resolution your webcam supports will help you determine whether you can set the resolution you want. When implementing the edge-related Edge AI in the Jetson series, high resolution is not necessarily good. High resolution images not only require a lot of resources when importing images from the camera, but can also slow down processing in deep learning models. It is advisable to use the resolution recommended by your vision deep learning model. Therefore, you need to know if your webcam is capable of setting the resolution recommended by the deep learning model. This post will cover this.

Resolutions

The following table lists the usage share of display resolutions from several sources, as of May 2019. The numbers are not representative of computer users in general.

StandardAspect ratioWidth (px)Height (px)Steam[11] (%)StatCounter[12] (%)
nHD16:9640360n/a1.23
SVGA4:3800600n/a0.64
XGA4:310247680.503.76
WXGA16:912807200.373.71
WXGA16:1012808000.623.69
SXGA5:4128010241.783.52
HD≈16:913607681.701.69
HD≈16:9136676811.3924.55
WXGA+16:1014409003.157.15
other16:91536864n/a6.08
HD+16:916009003.195.03
WSXGA+16:10168010502.322.56
FHD16:91920108064.5019.70
WUXGA16:10192012000.851.16
QWXGA16:920481152n/a0.42
other≈21:9256010801.02n/a
QHD16:9256014404.711.82
other≈21:9344014400.59n/a
4K UHD16:9384021601.61n/a
Other


1.6913.31

Find your Webcam

Most webcams released today support PnP, so they are automatically detected the moment you connect to the Jetson series. The following command will list the USB devices currently connected to the Jetson device.


root@spypiggy-desktop:~# lsusb
Bus 002 Device 002: ID 0bda:0411 Realtek Semiconductor Corp.
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 003: ID 046d:0825 Logitech, Inc. Webcam C270
Bus 001 Device 004: ID 05a3:9230 ARC International
Bus 001 Device 002: ID 0bda:5411 Realtek Semiconductor Corp.
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

I connected two USB webcams. One is Logitech C270, and the other is Chinese company Ailipu Technology's 2MP 1080p webcam. It is labeled ARC International in the above list. Two webcams are normally recognized as USB devices.

Linux exposes camera interfaces at /dev/video*. So check this directory.


root@spypiggy-desktop:~# ls -al /dev/video*
crw-rw---- 1 root video 81, 0  2  6 21:49 /dev/video0
crw-rw---- 1 root video 81, 1  2  6 21:50 /dev/video1

Yes, I can see 2 videos in that directory. These index numbers(0, 1) are very important later for OpenCV programming. Now you need to check whether index 0 is a Logitech webcam or another webcam. /dev/v4l/bu-id directory contains symbolic links that shows the information we need.


root@spypiggy-desktop:~# ls -al /dev/v4l/by-id
total 0
drwxr-xr-x 2 root root 80  2  6 21:50 .
drwxr-xr-x 4 root root 80  2  6 21:49 ..
lrwxrwxrwx 1 root root 12  2  6 21:49 usb-046d_0825_6B9CA2D0-video-index0 -> ../../video0
lrwxrwxrwx 1 root root 12  2  6 21:50 usb-HD_Camera_Manufacturer_USB_2.0_Camera-video-index0 -> ../../video1

You should now be able to find Index 0 as a Logitech webcam. So index 1 would be Ailipu Technology's webcam.

There is also a useful command called v4l2-ctl. To use this command, first install the v4l-utils.

root@spypiggy-nano:~# apt-get install v4l-utils
root@spypiggy-nano:~# lsusb
Bus 002 Device 002: ID 0bda:0411 Realtek Semiconductor Corp.
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 004: ID 046d:0825 Logitech, Inc. Webcam C270
Bus 001 Device 003: ID 046d:c534 Logitech, Inc. Unifying Receiver
Bus 001 Device 002: ID 0bda:5411 Realtek Semiconductor Corp.
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
root@spypiggy-nano:~# v4l2-ctl --list-devices
UVC Camera (046d:0825) (usb-70090000.xusb-2.3):
        /dev/video0

Get list of supported resolutions of your Webcam

The resolution of the webcam can be obtained using various commands. Some of these commands are only available if certain packages are installed. You can use one of several methods.
If you pass bus and divice values ​​with the -s option and -v(verbose), the lsusb command displays detailed information. These values ​​have already been obtained above with the lsusb command. This command displays a lot of information. Several wWidth and wHeight values ​​are displayed in the middle of the output value. These values ​​list the resolutions supported by the webcam.


root@spypiggy-desktop:~# lsusb -s 1:3 -v

Bus 001 Device 003: ID 046d:0825 Logitech, Inc. Webcam C270
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass          239 Miscellaneous Device
  bDeviceSubClass         2 ?
  bDeviceProtocol         1 Interface Association
  bMaxPacketSize0        64
  idVendor           0x046d Logitech, Inc.
  idProduct          0x0825 Webcam C270
  bcdDevice            0.10
  iManufacturer           0
  iProduct                0
  iSerial                 2 6B9CA2D0
  bNumConfigurations      1

.................
.................

      VideoStreaming Interface Descriptor:
        bLength                            50
        bDescriptorType                    36
        bDescriptorSubtype                  5 (FRAME_UNCOMPRESSED)
        bFrameIndex                         9
        bmCapabilities                   0x01
          Still image supported
        wWidth                        640
        wHeight                       360
        dwMinBitRate                 18432000
        dwMaxBitRate                110592000
        dwMaxVideoFrameBufferSize      460800
        dwDefaultFrameInterval         333333
        bFrameIntervalType                  6
        dwFrameInterval( 0)            333333
        dwFrameInterval( 1)            400000
        dwFrameInterval( 2)            500000
        dwFrameInterval( 3)            666666
        dwFrameInterval( 4)           1000000
        dwFrameInterval( 5)           2000000

.................
.................


Use the egrep command together to select only the lines you need.

root@spypiggy-desktop:~# lsusb -s 1:4 -v |egrep "wWidth|wHeight"
        wWidth                           1920
        wHeight                          1080
        wWidth                           1280
        wHeight                           720
        wWidth                           1024
        wHeight                           768
        wWidth                            640
        wHeight                           480
        wWidth                            800
        wHeight                           600
        wWidth                           1280
        wHeight                          1024
        wWidth                            320
        wHeight                           240
        wWidth                           1920
        wHeight                          1080
        wWidth                           1280
        wHeight                           720
        wWidth                           1024
        wHeight                           768
        wWidth                            640
        wHeight                           480
        wWidth                            800
        wHeight                           600
        wWidth                           1280
        wHeight                          1024
        wWidth                            320
        wHeight                           240
        wWidth( 0)                       1920
        wHeight( 0)                      1080


If you use "bDescriptorSubtype" together, it's much easier to understand the output.

root@spypiggy-desktop:~# lsusb -s 1:4 -v |egrep "bDescriptorSubtype|wWidth|wHeight"
        bDescriptorSubtype      1 (HEADER)
        bDescriptorSubtype      3 (OUTPUT_TERMINAL)
        bDescriptorSubtype      6 (EXTENSION_UNIT)
        bDescriptorSubtype      2 (INPUT_TERMINAL)
        bDescriptorSubtype      5 (PROCESSING_UNIT)
        bDescriptorSubtype                  1 (INPUT_HEADER)
        bDescriptorSubtype                  6 (FORMAT_MJPEG)
        bDescriptorSubtype                  7 (FRAME_MJPEG)
        wWidth                           1920
        wHeight                          1080
        bDescriptorSubtype                  7 (FRAME_MJPEG)
        wWidth                           1280
        wHeight                           720
        bDescriptorSubtype                  7 (FRAME_MJPEG)
        wWidth                           1024
        wHeight                           768
        bDescriptorSubtype                  7 (FRAME_MJPEG)
        wWidth                            640
        wHeight                           480
        bDescriptorSubtype                  7 (FRAME_MJPEG)
        wWidth                            800
        wHeight                           600
        bDescriptorSubtype                  7 (FRAME_MJPEG)
        wWidth                           1280
        wHeight                          1024
        bDescriptorSubtype                  7 (FRAME_MJPEG)
        wWidth                            320
        wHeight                           240
        bDescriptorSubtype                 13 (COLORFORMAT)
        bDescriptorSubtype                  4 (FORMAT_UNCOMPRESSED)
        bDescriptorSubtype                  5 (FRAME_UNCOMPRESSED)
        wWidth                           1920
        wHeight                          1080
        bDescriptorSubtype                  5 (FRAME_UNCOMPRESSED)
        wWidth                           1280
        wHeight                           720
        bDescriptorSubtype                  5 (FRAME_UNCOMPRESSED)
        wWidth                           1024
        wHeight                           768
        bDescriptorSubtype                  5 (FRAME_UNCOMPRESSED)
        wWidth                            640
        wHeight                           480
        bDescriptorSubtype                  5 (FRAME_UNCOMPRESSED)
        wWidth                            800
        wHeight                           600
        bDescriptorSubtype                  5 (FRAME_UNCOMPRESSED)
        wWidth                           1280
        wHeight                          1024
        bDescriptorSubtype                  5 (FRAME_UNCOMPRESSED)
        wWidth                            320
        wHeight                           240
        bDescriptorSubtype                  3 (STILL_IMAGE_FRAME)
        wWidth( 0)                       1920
        wHeight( 0)                      1080
        bDescriptorSubtype                 13 (COLORFORMAT)


You can also use a "v4l2-ctl" command .


root@spypiggy-nano:/usr/local/src/jetson-inference/python/examples# v4l2-ctl --list-devices
UVC Camera (046d:0825) (usb-70090000.xusb-2.3):
        /dev/video0

root@spypiggy-nano:/usr/local/src/jetson-inference/python/examples# v4l2-ctl --device /dev/video0 --list-formats-ext
ioctl: VIDIOC_ENUM_FMT
        Index       : 0
        Type        : Video Capture
        Pixel Format: 'YUYV'
        Name        : YUYV 4:2:2
                Size: Discrete 640x480
                        Interval: Discrete 0.033s (30.000 fps)
                        Interval: Discrete 0.040s (25.000 fps)
                        Interval: Discrete 0.050s (20.000 fps)
                        Interval: Discrete 0.067s (15.000 fps)
                        Interval: Discrete 0.100s (10.000 fps)
                        Interval: Discrete 0.200s (5.000 fps)
                Size: Discrete 160x120
                        Interval: Discrete 0.033s (30.000 fps)
                        Interval: Discrete 0.040s (25.000 fps)
                        Interval: Discrete 0.050s (20.000 fps)
                        Interval: Discrete 0.067s (15.000 fps)
                        Interval: Discrete 0.100s (10.000 fps)
                        Interval: Discrete 0.200s (5.000 fps)
                Size: Discrete 176x144
                        Interval: Discrete 0.033s (30.000 fps)
                        Interval: Discrete 0.040s (25.000 fps)
                        Interval: Discrete 0.050s (20.000 fps)
                        Interval: Discrete 0.067s (15.000 fps)
                        Interval: Discrete 0.100s (10.000 fps)
                        Interval: Discrete 0.200s (5.000 fps)
                Size: Discrete 320x176
                        Interval: Discrete 0.033s (30.000 fps)
                        Interval: Discrete 0.040s (25.000 fps)
                        Interval: Discrete 0.050s (20.000 fps)
                        Interval: Discrete 0.067s (15.000 fps)
                        Interval: Discrete 0.100s (10.000 fps)
                        Interval: Discrete 0.200s (5.000 fps)
                 ............ 
                 ............

Testing resolutions with OpenCV

Use OpenCV to check if the resolutions listed above are actually available.

VideoCapture function

To open a webcam or video stream, use the VideoCapture function. Depending on the parameters this function accepts, it works as follows:

VideoCapture ()

Default constructor. More...

VideoCapture (const String &filename)

Open video file or image file sequence or a capturing device or a IP video stream for video capturing. More...

VideoCapture (const String &filename, int apiPreference)

Open video file or a capturing device or a IP video stream for video capturing with API Preference. More...

VideoCapture (int index)

Open a camera for video capturing. More...

VideoCapture (int index, int apiPreference)

Opens a camera for video capturing. More...

Of these, the last two things to watch out for in order to use a webcam are:
In general, use the VideoCapture (int index) function, but you should also look at the following VideoCapture (int index, int apiPeference) function.

apiPreference parameter

This parameter is one of these values:
CAP_ANY 
Python: cv.CAP_ANY
Auto detect == 0.
CAP_VFW
Python: cv.CAP_VFW
Video For Windows (platform native), == 200
CAP_V4L 
Python: cv.CAP_V4L
V4L/V4L2 capturing support via libv4l. == 200
CAP_V4L2 
Python: cv.CAP_V4L2
Same as CAP_V4L. == 200
CAP_FIREWIRE
Python: cv.CAP_FIREWIRE
IEEE 1394 drivers.
CAP_FIREWARE
Python: cv.CAP_FIREWARE
Same as CAP_FIREWIRE.
CAP_IEEE1394
Python: cv.CAP_IEEE1394
Same as CAP_FIREWIRE.
CAP_DC1394
Python: cv.CAP_DC1394
Same as CAP_FIREWIRE.
CAP_CMU1394
Python: cv.CAP_CMU1394
Same as CAP_FIREWIRE.
CAP_QT
Python: cv.CAP_QT
QuickTime.
CAP_UNICAP
Python: cv.CAP_UNICAP
Unicap drivers.
CAP_DSHOW 
Python: cv.CAP_DSHOW
DirectShow (via videoInput) == 700
CAP_PVAPI
Python: cv.CAP_PVAPI
PvAPI, Prosilica GigE SDK.
CAP_OPENNI
Python: cv.CAP_OPENNI
OpenNI (for Kinect)
CAP_OPENNI_ASUS
Python: cv.CAP_OPENNI_ASUS
OpenNI (for Asus Xtion)
CAP_ANDROID
Python: cv.CAP_ANDROID
Android - not used.
CAP_XIAPI
Python: cv.CAP_XIAPI
XIMEA Camera API.
CAP_AVFOUNDATION
Python: cv.CAP_AVFOUNDATION
AVFoundation framework for iOS (OS X Lion will have the same API)
CAP_GIGANETIX
Python: cv.CAP_GIGANETIX
Smartek Giganetix GigEVisionSDK.
CAP_MSMF 
Python: cv.CAP_MSMF
Microsoft Media Foundation (via videoInput) == 1400
CAP_WINRT
Python: cv.CAP_WINRT
Microsoft Windows Runtime using Media Foundation.
CAP_INTELPERC
Python: cv.CAP_INTELPERC
Intel Perceptual Computing SDK.
CAP_OPENNI2
Python: cv.CAP_OPENNI2
OpenNI2 (for Kinect)
CAP_OPENNI2_ASUS
Python: cv.CAP_OPENNI2_ASUS
OpenNI2 (for Asus Xtion and Occipital Structure sensors)
CAP_GPHOTO2
Python: cv.CAP_GPHOTO2
gPhoto2 connection
CAP_GSTREAMER 
Python: cv.CAP_GSTREAMER
GStreamer. == 1800
CAP_FFMPEG 
Python: cv.CAP_FFMPEG
Open and record video file or stream using the FFMPEG library.
CAP_IMAGES
Python: cv.CAP_IMAGES
OpenCV Image Sequence (e.g. img_%02d.jpg)
CAP_ARAVIS
Python: cv.CAP_ARAVIS
Aravis SDK.
CAP_OPENCV_MJPEG
Python: cv.CAP_OPENCV_MJPEG
Built-in OpenCV MotionJPEG codec.
CAP_INTEL_MFX
Python: cv.CAP_INTEL_MFX
Intel MediaSDK.
CAP_XINE
Python: cv.CAP_XINE
XINE engine (Linux)

Usually, if you omit this parameter value, the first CAP_ANY is used. In this case, select the appropriate parameter in OpenCV. In most cases it works fine without this parameter. Not all of these values ​​can be used. You need to specify whether to include the CMake switch at OpenCV build time (eg : -DWITH_MSMF = ON -DWITH_VFW = ON ...)
In some cases, however, you may need to set this value yourself. Consider the following examples
I tested with the Logitech C270 webcam on Jetson Nano.


Jetson Nano (Jetpack 4.3) Example




import cv2
import sys, time
import argparse


parser = argparse.ArgumentParser(description='Webcam resolution Test')
parser.add_argument('--api', type=int, default=200, help='cv2.CAP_GSTREAMER=1800,  cv2.CAP_V4L2 = 200 ')
parser.add_argument('--width', type=int, default=1280)
parser.add_argument('--height', type=int, default=960)
args = parser.parse_args()

print('Webcam Test')
cap = cv2.VideoCapture(0,  args.api)
if (cap.isOpened() == False): 
    print("Unable to read camera feed")
    sys.exit(0)
ret = cap.set(cv2.CAP_PROP_FRAME_WIDTH, args.width)
print('apiReference[%d] WebCAM width  set :%d'%(args.api, ret))
ret = cap.set(cv2.CAP_PROP_FRAME_HEIGHT, args.height)
print('apiReference[%d] WebCAM height set :%d'%(args.api, ret))
ret, img = cap.read()
if ret == False:
    print('WebCAM Read Error')    
    sys.exit(0)
h, w, c = img.shape
print('Video Frame shape H:%d, W:%d, Channel:%d'%(h, w, c))


count = 1
while cap.isOpened():
    try:
        start = time.time()
        ret, img = cap.read()
        if ret == False:
            break
        count += 1
        cv2.waitKey(1)
        cv2.imshow('webcam', img)
        end = time.time()
        print('FPS : %f'%(1 / (end - start)))
        if count > 10:
            break
    except KeyboardInterrupt:
        print('Ctrl + C')
        break

print('Webcam Frame read End. Total Frames are : %d'%(count))
cv2.destroyAllWindows()
cap.release()
<webcam_capability.py>

I tested this program with cv2.CAP_GSTREAMER, cv2.CAP_V4L2 parameters. If I use cv2.CAP_GSTREAMER option, cap.set(cv2.CAP_PROP_FRAME_WIDTH, args.width) function fails, but the capture resolution has changed. If I use cv2.CAP_V4L2 option, cap.set(cv2.CAP_PROP_FRAME_WIDTH, args.width) function successes, and the capture resolution has also changed. This is a bit odd.


spypiggy@spypiggy-nano:/usr/local/src/study/webcam_test$ python3 webcam.py --width=1280 --height=960 --api=200
Webcam Test
apiReference[200] WebCAM width  set :1
apiReference[200] WebCAM height set :1
Video Frame shape H:960, W:1280, Channel:3
FPS : 5.295792
FPS : 14.249086
FPS : 7.164093
FPS : 7.888464
FPS : 6.887923
FPS : 7.774774
FPS : 7.695109
FPS : 7.614115
FPS : 7.541189
FPS : 7.332135
Webcam Frame read End. Total Frames are : 11
spypiggy@spypiggy-nano:/usr/local/src/study/webcam_test$ python3 webcam.py --width=1280 --height=960 --api=1800
Webcam Test
[ WARN:0] global /home/nvidia/host/build_opencv/nv_opencv/modules/videoio/src/cap_gstreamer.cpp (933) open OpenCV | GStreamer warning: Cannot query video position: status=0, value=-1, duration=-1
apiReference[1800] WebCAM width  set :0
apiReference[1800] WebCAM height set :0
Video Frame shape H:960, W:1280, Channel:3
FPS : 5.056150
FPS : 15.758937
FPS : 7.625869
FPS : 7.402074
FPS : 6.682095
FPS : 8.054770
FPS : 7.539793
FPS : 7.610565
FPS : 7.562755
FPS : 7.365483
Webcam Frame read End. Total Frames are : 11

This time, let's test using a resolution that is not supported.


spypiggy@spypiggy-nano:/usr/local/src/study/webcam_test$ python3 webcam.py --width=1288 --height=966 --api=200
Webcam Test
apiReference[200] WebCAM width  set :1
apiReference[200] WebCAM height set :1
Video Frame shape H:960, W:1280, Channel:3
FPS : 5.445239
FPS : 13.088222
FPS : 7.367735
FPS : 7.533780
FPS : 7.028237
FPS : 7.775639
FPS : 7.582731
FPS : 7.634516
FPS : 7.544106
FPS : 7.364164
Webcam Frame read End. Total Frames are : 11
spypiggy@spypiggy-nano:/usr/local/src/study/webcam_test$ python3 webcam.py --width=1288 --height=966 --api=1800
Webcam Test
[ WARN:0] global /home/nvidia/host/build_opencv/nv_opencv/modules/videoio/src/cap_gstreamer.cpp (933) open OpenCV | GStreamer warning: Cannot query video position: status=0, value=-1, duration=-1
[ WARN:0] global /home/nvidia/host/build_opencv/nv_opencv/modules/videoio/src/cap_gstreamer.cpp (1757) handleMessage OpenCV | GStreamer warning: Embedded video playback halted; module v4l2src0 reported: Internal data stream error.
[ WARN:0] global /home/nvidia/host/build_opencv/nv_opencv/modules/videoio/src/cap_gstreamer.cpp (515) startPipeline OpenCV | GStreamer warning: unable to start pipeline
apiReference[1800] WebCAM width  set :0
[ WARN:0] global /home/nvidia/host/build_opencv/nv_opencv/modules/videoio/src/cap_gstreamer.cpp (1055) setProperty OpenCV | GStreamer warning: no pipeline
apiReference[1800] WebCAM height set :0
WebCAM Read Error
[ WARN:0] global /home/nvidia/host/build_opencv/nv_opencv/modules/videoio/src/cap_gstreamer.cpp (480) isPipelinePlaying OpenCV | GStreamer warning: GStreamer: pipeline have not been created

When using the cv2.CAP_V4L2 option, the cap.set (cv2.CAP_PROP_FRAME_WIDTH, args.width) function succeeds and sets the closest resolution even if you use a non-clearer resolution. However, when using the cv2.CAP_GSTREAMER option, an error occurs when using a resolution that is not supported. This is also a bit odd.


FPS Comparing

This time, use the cv2.CAP_V4L2 option to change the resolution and compare the speed of reading frames.

spypiggy@spypiggy-nano:/usr/local/src/study/webcam_test$ python3 webcam.py --width=1280 --height=960 --api=200
Webcam Test
apiReference[200] WebCAM width  set :1
apiReference[200] WebCAM height set :1
Video Frame shape H:960, W:1280, Channel:3
FPS : 5.474221
FPS : 13.026355
FPS : 7.411112
FPS : 7.641457
FPS : 6.995345
FPS : 7.628199
FPS : 7.724943
FPS : 7.595487
FPS : 7.562278
FPS : 7.386458
Webcam Frame read End. Total Frames are : 11
spypiggy@spypiggy-nano:/usr/local/src/study/webcam_test$ python3 webcam.py --width=640 --height=480 --api=200
Webcam Test
apiReference[200] WebCAM width  set :1
apiReference[200] WebCAM height set :1
Video Frame shape H:480, W:640, Channel:3
FPS : 8.379993
FPS : 88.221273
FPS : 14.520197
FPS : 14.759737
FPS : 13.776569
FPS : 14.644712
FPS : 15.116189
FPS : 14.696024
FPS : 14.573322
FPS : 14.823062
Webcam Frame read End. Total Frames are : 11

Reducing the capture resolution to half both horizontally and vertically increases the processing speed by about twice.

Wrapping up

We can see that the processing results are subtly different depending on the webcam's capture options. But I do not know the exact cause of this phenomenon. Knowing these subtle phenomena, you can adjust the webcam's resolution to suit your needs.