Not getting proper size of image with /dev/video0

I am getting image from camera using OpenCV. The camera I am using is having maximum dimension 2304 x 1536.

I am facing one problem I am getting different size of image with changing the input parameters of

VideoCapture(index)
  1. If I use index = /dev/video0 or index = -1

cam=cv2.VideoCapture("/dev/video0") or cam=cv2.VideoCapture(-1)

I am getting Image size 640 x 480 always

Warning I am getting is

[ 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: Cannot identify device '/dev/video-1'.
[ WARN:0] global /home/nvidia/host/build_opencv/nv_opencv/modules/videoio/src/cap_gstreamer.cpp (886) open OpenCV | GStreamer warning: unable to start pipeline
[ 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
  1. If I use 'index = 0`

cam=cv2.VideoCapture(0)

I am getting proper image of size 2304 x 1536

Warning I am getting is

[ 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


The result of v4l2-ctl -d /dev/video0 --list-formats-ext command is

ioctl: VIDIOC_ENUM_FMT
	Index       : 0
	Type        : Video Capture
	Pixel Format: 'UYVY'
	Name        : UYVY 4:2:2
		Size: Discrete 1280x720
			Interval: Discrete 0.017s (60.000 fps)
			Interval: Discrete 0.033s (30.000 fps)
		Size: Discrete 1920x1080
			Interval: Discrete 0.017s (60.000 fps)
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
		Size: Discrete 2304x1296
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
		Size: Discrete 2304x1536
			Interval: Discrete 0.042s (24.000 fps)
			Interval: Discrete 0.083s (12.000 fps)
		Size: Discrete 640x480
			Interval: Discrete 0.017s (60.000 fps)
			Interval: Discrete 0.033s (30.000 fps)
		Size: Discrete 1920x1280
			Interval: Discrete 0.020s (50.000 fps)
			Interval: Discrete 0.040s (25.000 fps)
		Size: Discrete 1152x768
			Interval: Discrete 0.017s (60.000 fps)
			Interval: Discrete 0.033s (30.000 fps)
		Size: Discrete 2048x1536
			Interval: Discrete 0.024s (42.000 fps)
			Interval: Discrete 0.048s (21.000 fps)
		Size: Discrete 1280x960
			Interval: Discrete 0.017s (58.000 fps)
			Interval: Discrete 0.033s (30.000 fps)

	Index       : 1
	Type        : Video Capture
	Pixel Format: 'MJPG' (compressed)
	Name        : Motion-JPEG
		Size: Discrete 1280x720
			Interval: Discrete 0.017s (60.000 fps)
		Size: Discrete 1920x1080
			Interval: Discrete 0.017s (60.000 fps)
		Size: Discrete 2304x1296
			Interval: Discrete 0.017s (60.000 fps)
		Size: Discrete 2304x1536
			Interval: Discrete 0.021s (48.000 fps)
		Size: Discrete 640x480
			Interval: Discrete 0.017s (60.000 fps)
		Size: Discrete 1920x1280
			Interval: Discrete 0.020s (50.000 fps)
		Size: Discrete 1152x768
			Interval: Discrete 0.017s (60.000 fps)
		Size: Discrete 2048x1536
			Interval: Discrete 0.020s (50.000 fps)
		Size: Discrete 1280x960
			Interval: Discrete 0.017s (58.000 fps)

I am not sure about the reason. I want to use cam=cv2.VideoCapture("/dev/video0") to get the proper full size image. How can I get?

Opencv video capture may use various backends for accessing the video stream. If the backend is not specified, opencv may try to guess and may fail.
You would test if the camera has been successfully opened with cam.isOpened(). My guess is that in failing case it returns default 640x480p30 mode.

You may try:

1. Using V4L backend
The first argument would be the camera index (0 for /dev/video0, 1 for /dev/video1, … and -1 for /dev/video that would be a symbolic link to your favorite camera node such as /dev/video0 or 1,… ).
You may ensure you’re using V4L backend by specifying the backend as second argument. So you may use:

cam = cv2.VideoCapture(0, cv2.CAP_V4L2)

Note that the following warning is normal as a live stream has no duration and current position can therefore not be computed. This is harmless.

As OpenCv expects BGR format for most algorithms on color frames, opencv may perform the conversion with CPU that may not be so fast.

2. Using gstreamer backend.
You would build a pipeline from your source to appsink (ie opencv application) converting into BGR format. The following pipelines do conversion with jetson HW driven by nvvidconv plugin that requires frames to be in NVMM memory (dma-able). As BGR format is not supported by NVIDIA HW, you still need CPU videoconvert for removing the extra fourth byte from BGRx and provide BGR to opencv. You may try:

cam = cv2.VideoCapture("v4l2src device=/dev/video0 ! video/x-raw, format=UYVY, width=2304,height=1536,framerate=24/1 ! nvvidconv ! video/x-raw(memory:NVMM) ! nvvidconv ! video/x-raw, format=BGRx ! videoconvert ! video/x-raw,format=BGR ! appsink drop=1", cv2.CAP_GSTREAMER)

# If working, this may be better
cam = cv2.VideoCapture("nvv4l2camerasrc device=/dev/video0 ! video/x-raw(memory:NVMM), format=UYVY, width=2304,height=1536,framerate=24/1 ! nvvidconv ! video/x-raw, format=BGRx ! videoconvert ! video/x-raw,format=BGR ! appsink drop=1", cv2.CAP_GSTREAMER)