4K resolution in OpenCV with DELL UltraShap


I’ve recently been experimenting with computer vision using OpenCV, and for my setup, I’m using a Dell UltraSharp webcam to capture images. Out of the box, OpenCV makes it easy to grab frames at 1920×1080 (Full HD), which is great—but according to the camera’s specifications, it should support 3840×2160 (4K) resolution.

Interestingly, when I tested the webcam with Cheese, 4K worked perfectly. That means the hardware and drivers support it – so why not OpenCV?

It turns out that most applications for webcams uses the device driver V4L2 (OpenCV, ffmpeg, gstreamer), when these programs are used on Ubuntu. So, how does one change the settings in V4L2? First step is to list the possible video formats for the device:

v4l2-ctl --list-formats-ext --device 9

The possible formats for the Dell UltraSharp is

ioctl: VIDIOC_ENUM_FMT
	Type: Video Capture
	[0]: 'YUYV' (YUYV 4:2:2)
		Size: Discrete 640x480
			Interval: Discrete 0.033s (30.000 fps)
		Size: Discrete 640x360
			Interval: Discrete 0.033s (30.000 fps)
		Size: Discrete 1280x720
			Interval: Discrete 0.042s (24.000 fps)
			Interval: Discrete 0.033s (30.000 fps)
		Size: Discrete 1920x1080
			Interval: Discrete 0.042s (24.000 fps)
			Interval: Discrete 0.033s (30.000 fps)
	[1]: 'MJPG' (Motion-JPEG, compressed)
		Size: Discrete 640x480
			Interval: Discrete 0.033s (30.000 fps)
		Size: Discrete 1280x720
			Interval: Discrete 0.042s (24.000 fps)
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.017s (60.000 fps)
		Size: Discrete 1920x1080
			Interval: Discrete 0.042s (24.000 fps)
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.017s (60.000 fps)
		Size: Discrete 2560x1440
			Interval: Discrete 0.042s (24.000 fps)
			Interval: Discrete 0.033s (30.000 fps)
		Size: Discrete 3840x2160
			Interval: Discrete 0.042s (24.000 fps)
			Interval: Discrete 0.033s (30.000 fps)
	[2]: 'NV12' (Y/UV 4:2:0)
		Size: Discrete 640x480
			Interval: Discrete 0.033s (30.000 fps)
		Size: Discrete 640x360
			Interval: Discrete 0.033s (30.000 fps)
		Size: Discrete 1280x720
			Interval: Discrete 0.033s (30.000 fps)
		Size: Discrete 1920x1080
			Interval: Discrete 0.033s (30.000 fps)

This indicates that the camera must be switched to MJPG to use the highest resolution. In Python this is done by:

fourcc_mjpg = cv2.VideoWriter_fourcc(*'MJPG')
cap.set(cv2.CAP_PROP_FOURCC, fourcc_mjpg)

And in Java:

int fourcc_mjpg = VideoWriter.fourcc('M','J','P','G');
capture.set(Videoio.CAP_PROP_FOURCC, fourcc_mjpg);

Here is a complete example in Python:

import cv2

# 1) Open the camera explicitly with the V4L2 backend
cap = cv2.VideoCapture(9, cv2.CAP_V4L2)

if not cap.isOpened():
    raise RuntimeError("Cannot open camera with V4L2 backend")

# 2) Request MJPG from the camera
#    Note: set FOURCC *after* opening the device.
fourcc_mjpg = cv2.VideoWriter_fourcc(*'MJPG')
print ("MJPG setting:")
print (fourcc_mjpg)
cap.set(cv2.CAP_PROP_FOURCC, fourcc_mjpg)

# (Optional) Set resolution/fps to modes that the camera supports in MJPG
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 3840)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 2160)
cap.set(cv2.CAP_PROP_FPS, 1)

# 3) Verify what you actually got
applied_fourcc = int(cap.get(cv2.CAP_PROP_FOURCC))
applied = "".join([chr((applied_fourcc >> (8 * i)) & 0xFF) for i in range(4)])
print("Applied FOURCC:", applied)  # Expect "MJPG" if accepted

backend = int(cap.get(cv2.CAP_PROP_BACKEND))
print("Backend:", backend)  # Should match cv2.CAP_V4L2

# Read frames
while True:
    ok, frame = cap.read()
    if not ok:
        print("Frame read failed")
        break
    cv2.imshow("MJPG stream", frame)
    if cv2.waitKey(1) == 27:  # ESC
        break

cap.release()
cv2

And here is one in Java

import org.opencv.core.Mat;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.videoio.VideoCapture;
import org.opencv.videoio.VideoWriter;
import org.opencv.videoio.Videoio;

nu.pattern.OpenCV.loadLocally();

VideoCapture capture = new VideoCapture(9, Videoio.CAP_V4L2);
assertTrue(capture.isOpened());

// Set the camera into MJPG because that allows high resolution
int fourcc_mjpg = VideoWriter.fourcc('M', 'J', 'P', 'G');
capture.set(Videoio.CAP_PROP_FOURCC, fourcc_mjpg);

// Set resolution as high as possible
// Dell UltraSharp Webcam 3840 x 2160
capture.set(Videoio.CAP_PROP_FRAME_WIDTH, 3840);
capture.set(Videoio.CAP_PROP_FRAME_HEIGHT, 2160);
capture.set(Videoio.CAP_PROP_FPS, 2);

// Verify the settings
int height = (int)capture.get(Videoio.CAP_PROP_FRAME_HEIGHT);
int width = (int)capture.get(Videoio.CAP_PROP_FRAME_WIDTH);
System.out.println("Camera started. Width = "+width+" Height = "+height);
System.out.println(" Backend name: "+capture.getBackendName());
System.out.println(" FPS = " + capture.get(Videoio.CAP_PROP_FPS));

// This is the variable where the image will be stored
Mat frame = new Mat();

// Take some pictures to allow the webcam to focus.
int c = 0;
while (c < 100){
    if (capture.read(frame)) c++;
}

// Save the last image
Imgcodecs.imwrite("OpenCVcapture.jpg", frame);

Leave a Reply

Your email address will not be published. Required fields are marked *