Control camera parameters in opencv using v4l2

Dear All,

We are using opencv to continuously capture images from e-con see3cam USB camera interfaced with jetson xavier nx device.We need to capture frames from camera and store the images into a buffer or queue in memory. We need to set camera parameters also to control exposure and white balance of the images.Using V4l2-ctl we are able to control camera parameters for our requirement. How to set camera parameters using v4l2 in opencv for camera interfaced with xavier?

Thanks and Regards

Probably @Dharmalingam.K would better advise if telling your cameras and/or adapters with your Jetson release.

From OpenCv with V4L backend, you would access a some properties to with cap.set or just use V4L API for setting these.
In any case, be sure to re-read set properties for being sure these are applied.

Hi Honey,
Thanks for the response. I have tried cap.set option of opencv to set exposure but it has failed.I have also tried python-v4l2capture module to set v4l2 parameters with opencv. I was able to set v4l2 parameters with that but could not able to change the image format to UYVY . I am also sharing the code i have used for testing.

import cv2
import time, os
import numpy as np
import v4l2capture
import select

prev_time = 0

def cur_milli_time():
	return round(time.time()*1000)
	
video = v4l2capture.Video_device("/dev/video0")

size_x, size_y = video.set_format(4208, 3120, fourcc='MJPG')
#size_x, size_y = video.set_format(1280, 720, fourcc='UYVY' )
print ("device chose {0}x{1} res".format(size_x, size_y))

video.set_exposure_auto(1)
video.set_exposure_absolute(40)
video.set_auto_white_balance(0)
video.set_white_balance_temperature(4200)
video.create_buffers(10)
video.queue_all_buffers()
video.start()

exposure = video.get_exposure_absolute()
print("exposure set is: ",exposure)

#cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)#4208
#cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 960)#3120

while(True):
	select.select((video,), (), ())
	image_data = video.read_and_queue()
	image = np.frombuffer(image_data, dtype=np.uint8)
	frame = cv2.imdecode(image, cv2.IMREAD_COLOR)
	
	#ret, frame = cap.read()
	cv2.imshow('preview',frame)
	cur_time = cur_milli_time()
	print("time taken:", (cur_time - prev_time),"ms")
	prev_time = cur_time
	#filename = "img_%s.jpg"%cur_time
	#cv2.imwrite(filename,frame)
	if cv2.waitKey(1) & 0xFF == ord('q'):
		break
	#time.sleep(.005)

#cap.release()
video.close()
cv2.destroyAllWindows()

OpenCV has been build using the V4l2. We can configure the UVC Settings say (Brightness , Contrast , Exposure , etc. ) as mentioned like a below Snippet.

if (cap.open(0)) // 0- Index of the Camera

{

            if (!cap.isOpened())

            {

                            cout << endl << "\t Camera Device not Initialised Successfully \n\n ";

                            return 0;

            }

}

/* - The Property MACRO varies according to the OpenCV Version as either CV_CAP_PROP_BRIGHTNESS or CAP_PROP_BRIGHTNES , For 3.3.1 and 3.4.1 , it will be CV_CAP_PROP_BRIGHTNESS */

cap.set(CV_CAP_PROP_BRIGHTNESS, 10); // To Configure the Brightness value as 10
cap.set(CV_CAP_PROP_CONTRAST, 15); // To Configure the Brightness value as 15

cap.set(CV_CAP_PROP_EXPOSURE, 3); // To Configure the Exposure value as 3

cap.release();

I have tried these options but could not set exposure with it.The Opencv version we are using here is 4.5.1 and code used is:

import cv2
import time, os
import numpy as np
from PIL import Image

prev_time = 0
cap = cv2.VideoCapture(0)

def cur_milli_time():
	return round(time.time()*1000)

if not (cap.isOpened()):
	print("could not open video device")

cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)#4208
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 960)#3120
cap.set(cv2.CAP_PROP_EXPOSURE, 40)

exposure = cap.get(cv2.CAP_PROP_EXPOSURE)
print("exposure set is: ",exposure)

#print("setting camera setup.....")
#camera_setup_result = os.system("v4l2-ctl --set-ctrl=exposure_auto=1,exposure_absolute=40,white_balance_temperature_auto=0,white_balance_temperature=4200,gain=1,zoom_absolute=100")
#print("Error = {}".format(camera_setup_result),end='\n\n')

while(True):
	#sleep
	ret, frame = cap.read()
	cv2.imshow('preview',frame)
	cur_time = cur_milli_time()
	#print("time taken:", (cur_time - prev_time),"ms")
	prev_time = cur_time
	#filename = "img_%s.jpg"%cur_time
	#cv2.imwrite(filename,frame)
	if cv2.waitKey(1) & 0xFF == ord('q'):
		break

cap.release()
cv2.destroyAllWindows()

Not sure for your case, but I’ve seen cases where I had to read a frame for having properties such as framerate to be updated.

checked set properties after reading frames also, but got same result as before. Also when i set exposure using cap.set got following response.

[ WARN:0] global /tmp/pip-build-bcpemu7y/opencv-python/opencv/modules/videoio/src/cap_gstreamer.cpp (1214) setProperty OpenCV | GStreamer warning: GStreamer: unhandled property

and when checked set exposure value using cap.get got the following response:

[ WARN:0] global /tmp/pip-build-bcpemu7y/opencv-python/opencv/modules/videoio/src/cap_gstreamer.cpp (1064) getProperty OpenCV | GStreamer warning: unhandled property: 15

Hi,
Generally we run a gstreamer pipeline in cv2.VideoCapture(). Please refer to
V4l2src using OpenCV Gstreamer is not working in Jetson Xavier NX - #3 by DaneLLL

See if you can apply this to your usecase.