Using the Raspberry Pi Camera in Python3/PyQt5 applications using picamera2 lib

Exercise to use the Raspberry Pi Camera in Python3/PyQt5 applications using picamera2 lib, with modification to make the preview match with captured images and enable Auto-Focus in Continuous. Tested on Raspberry Pi 5 running 64-bit Raspberry Pi OS (bookworm) with Camera Module 3. Please notice that currently only the Camera Module 3 provide Auto-Focus feature.


Firstly, Copy from the example in The Raspberry Pi official manual The Picamera2 Library (2023-11-27) Charpter 8.5 Using the camera in Qt applications, named Qt_Picamera2_App.py.

Qt_Picamera2_App.py listed here for reference.

"""
Copy from the example in
The Raspberry Pi official manual The Picamera2 Library (2023-11-27)
Charpter 8.5 Using the camera in Qt applications
"""
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QPushButton, QVBoxLayout, QApplication, QWidget
from picamera2.previews.qt import QGlPicamera2
from picamera2 import Picamera2

picam2 = Picamera2()
picam2.configure(picam2.create_preview_configuration())

def on_button_clicked():
    button.setEnabled(False)
    cfg = picam2.create_still_configuration()
    picam2.switch_mode_and_capture_file(cfg, "test.jpg", signal_function=qpicamera2.signal_done)
    
def capture_done(job):
    result = picam2.wait(job)
    button.setEnabled(True)
    
app = QApplication([])
qpicamera2 = QGlPicamera2(picam2, width=800, height=600, keep_ar=False)
button = QPushButton("Click to capture JPEG")
window = QWidget()
qpicamera2.done_signal.connect(capture_done)
button.clicked.connect(on_button_clicked)

layout_v = QVBoxLayout()
layout_v.addWidget(qpicamera2)
layout_v.addWidget(button)
window.setWindowTitle("Qt Picamera2 App")
window.resize(640, 480)
window.setLayout(layout_v)

picam2.start()
window.show()
app.exec()



Note that the preview doesn't cover the whole capture area, and the Auto-Focus disabled.

Qt_Picamera2_App_preview.py
, modified to make the preview match the capture area, and enable Auto-Focus in Continuous.
"""
Modify from the example in
The Raspberry Pi official manual The Picamera2 Library (2023-11-27)
Charpter 8.5 Using the camera in Qt applications,
to make the preview match the capture area.
"""
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QPushButton, QVBoxLayout, QApplication, QWidget
from picamera2.previews.qt import QGlPicamera2
from picamera2 import Picamera2
from libcamera import controls

import os

# hide the debug info generated by libcamera shown on shell
# such that not to confuse our own info shown
# 0 - DEBUG
# 1 - INFO
# 2 - WARN
# 3 - ERROR
# 4 - FATAL
os.environ["LIBCAMERA_LOG_LEVELS"] = "3"

picam2 = Picamera2()

def print_disct(dict_source):
    for keys, values in dict_source.items():
        print(keys, ":", values)
    

#======================================
# Make the preview area match with capture image.
# Also print the default preview_configuration/still_configuration for reference.

#picam2.configure(picam2.create_preview_configuration())

print("\n=== Default preview_configuration (for reference) ===")
default_preview_configuration = picam2.create_preview_configuration()
print_disct(default_preview_configuration)

print("\n=== Default still_configuration (for reference) ===")
default_still_configuration = picam2.create_still_configuration()
print_disct(default_still_configuration)

print("\n=== preview_config_raw ===")
preview_width= 800
preview_height = int(picam2.sensor_resolution[1] * preview_width/picam2.sensor_resolution[0])

preview_config_raw = picam2.create_preview_configuration(main={"size": (preview_width, preview_height)},
                                                         raw={"size": picam2.sensor_resolution})

print_disct(preview_config_raw)

picam2.configure(preview_config_raw)
#======================================
# Enable Auto-Focus in Continuous mode
picam2.set_controls({"AfMode": controls.AfModeEnum.Continuous})
#======================================
def on_button_clicked():
    button.setEnabled(False)
    cfg = picam2.create_still_configuration()
    picam2.switch_mode_and_capture_file(cfg, "test_x.jpg", signal_function=qpicamera2.signal_done)
    
def capture_done(job):
    result = picam2.wait(job)
    button.setEnabled(True)
    
app = QApplication([])
qpicamera2 = QGlPicamera2(picam2,
                          width=preview_width, height=preview_height,
                          keep_ar=True)
button = QPushButton("Click to capture JPEG")
window = QWidget()
qpicamera2.done_signal.connect(capture_done)
button.clicked.connect(on_button_clicked)

layout_v = QVBoxLayout()
layout_v.addWidget(qpicamera2)
layout_v.addWidget(button)
window.setWindowTitle(__file__)  # use script name as Window Title
window.resize(640, 480)
window.setLayout(layout_v)

picam2.start()
window.show()
app.exec()

Photo captured:


next:
Python/PyQt5 GUI to control Raspberry Pi Camera using picamera2 lib.
Python/PyQt5/Picamera2 to control Raspberry Pi Cameras with GUI, with camera_controls.
Python/PyQt5/Picamera2 to control Raspberry Pi Cameras with GUI, added White Balance setting.
Python 3/PyQt5 + picamera2 on Raspberry Pi, list available cameras.

Comments

Popular posts from this blog

480x320 TFT/ILI9488 SPI wih EP32C3 (arduino-esp32) using Arduino_GFX Library

Drive 320x240 ILI9341 SPI TFT using ESP32-S3 (NodeMCU ESP-S3-12K-Kit) using TFT_eSPI library, in Arduino Framework.