From 39fb6f7d83b2a3def07304e63f9f914a18815a01 Mon Sep 17 00:00:00 2001 From: William Vinnicombe Date: Tue, 12 Dec 2023 18:24:59 +0000 Subject: [PATCH 1/2] Add stereo preview example Add an example demonstrating the use of stride, where the stride is set to twice the image width to allow an image from a second camera to be copied into the empty space, creating a stereo image Signed-off-by: William Vinnicombe --- examples/stereo_preview.py | 69 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100755 examples/stereo_preview.py diff --git a/examples/stereo_preview.py b/examples/stereo_preview.py new file mode 100755 index 00000000..31243f9f --- /dev/null +++ b/examples/stereo_preview.py @@ -0,0 +1,69 @@ +#!/usr/bin/python3 + +import time + +from picamera2 import MappedArray, Picamera2, libcamera + +cam2_request = None + + +def pre_callback(request): + # Set the size, to make preview window and MappedArray remapping work + request.config["main"]["size"] = full_size + request.stream_map["main"].configuration.size = libcamera.Size(*full_size) + + +def copy_image(request): + global cam2_request + request_2 = cam2_request + if request_2 is None: + return + request_2.acquire() + # Copy second image into right hand side of main image + with MappedArray(request, "main") as m1, MappedArray(request_2, "main") as m2: + a1 = m1.array + a2 = m2.array + a1[:, -a2.shape[1]:] = a2 + request_2.release() + + +def save_request(request): + # Store most recent request for use by other camera + global cam2_request + if cam2_request is not None: + cam2_request.release() + request.acquire() + cam2_request = request + + +picam2a = Picamera2(0) + +full_size = (1920, 1080) +half_size = (full_size[0] // 2, full_size[1]) +# Calculate stride for full frame +full_config = picam2a.create_preview_configuration({"size": full_size}) +picam2a.configure(full_config) +stride = picam2a.camera_config["main"]["stride"] + +# Configure as half frame, with full frame stride so right side is blank +picam2a.pre_callback = pre_callback +picam2a.post_callback = copy_image +main_config = picam2a.create_preview_configuration( + main={"size": half_size, "stride": stride}, + controls={"ScalerCrop": (0, 0, picam2a.sensor_resolution[0], picam2a.sensor_resolution[1])} +) +picam2a.configure(main_config) +picam2a.start_preview(True) + +# Configure as half frame normally +picam2b = Picamera2(1) +picam2b.post_callback = save_request +half_config = picam2a.create_preview_configuration( + main={"size": half_size}, + controls={"ScalerCrop": (0, 0, picam2a.sensor_resolution[0], picam2a.sensor_resolution[1])} +) +picam2b.configure(half_config) + +picam2a.start() +picam2b.start() +time.sleep(10) From 50b4ed15e17b9d08266497bffbfb9679bc7c5e32 Mon Sep 17 00:00:00 2001 From: William Vinnicombe Date: Wed, 13 Dec 2023 17:14:28 +0000 Subject: [PATCH 2/2] Add stride test Add a test to check the stride is being set correctly when provided in the stream configuration Signed-off-by: William Vinnicombe --- tests/stride_test.py | 41 +++++++++++++++++++++++++++++++++++++++++ tests/test_list.txt | 1 + 2 files changed, 42 insertions(+) create mode 100755 tests/stride_test.py diff --git a/tests/stride_test.py b/tests/stride_test.py new file mode 100755 index 00000000..b1b7e4ea --- /dev/null +++ b/tests/stride_test.py @@ -0,0 +1,41 @@ +#!/usr/bin/python3 + +import time + +from picamera2 import MappedArray, Picamera2, libcamera + + +def pre_callback(request): + # Set the size, to make preview window and MappedArray remapping work + assert request.config["main"]["stride"] == stride + request.config["main"]["size"] = full_size + request.stream_map["main"].configuration.size = libcamera.Size(*full_size) + + +def post_callback(request): + # Make right side grey + with MappedArray(request, "main") as m1: + a1 = m1.array + a1[:, -a1.shape[1] // 2:] = 70 + + +picam2 = Picamera2(0) + +full_size = (1920, 1080) +half_size = (full_size[0] // 2, full_size[1]) +# Calculate stride for full frame +full_config = picam2.create_preview_configuration({"size": full_size}) +picam2.configure(full_config) +stride = picam2.camera_config["main"]["stride"] + +# Configure as half frame, with full frame stride so right side is blank +picam2.pre_callback = pre_callback +picam2.post_callback = post_callback +main_config = picam2.create_preview_configuration( + main={"size": half_size, "stride": stride} +) +picam2.configure(main_config) +picam2.start_preview(True) + +picam2.start() +time.sleep(2) diff --git a/tests/test_list.txt b/tests/test_list.txt index 49f72cc2..556c4ef4 100644 --- a/tests/test_list.txt +++ b/tests/test_list.txt @@ -77,3 +77,4 @@ tests/qt_gl_preview_test.py tests/stop_slow_framerate.py tests/allocator_test.py tests/allocator_leak_test.py +tests/stride_test.py