Python/PyQt5/Picamera2 to control Raspberry Pi Cameras with GUI, with camera_controls.
Follow my previous exercise Python/PyQt5 GUI to control Raspberry Pi Camera using picamera2 lib, added function to change camera_controls for brightness at runtime.
This video also show two instances run to control two cameras at the same time.
Because my Camera Module 3 (with Auto-Focus) is assigned to Picamera2(1), so I make 1 as default. If you have one camera only, or you want 0 as default, set:
picam2_qt5_2024-01-13.py
Updated 2024-01-15: Add camera_controls: brightness, Contrast, ExposureValue, Saturation & Sharpness.
picam2_qt5_2024-01-15.py
next:
~ Python/PyQt5/Picamera2 to control Raspberry Pi Cameras with GUI, added White Balance setting.
~ Python 3/PyQt5 + picamera2 on Raspberry Pi, list available cameras.
This video also show two instances run to control two cameras at the same time.
Because my Camera Module 3 (with Auto-Focus) is assigned to Picamera2(1), so I make 1 as default. If you have one camera only, or you want 0 as default, set:
DEFAULT_CAM_NUM = 0
picam2_qt5_2024-01-13.py
"""
Python 3/PyQt5 + picamera2 to control Raspberry Pi Camera Modules
Tested on Raspberry Pi 5/64-bit Raspberry Pi OS (bookworm)
# in my setup:
# Picamera2(0) - HQ Camera
# Picamera2(1) - Camera Module 3
picam2_qt5_2023-12-28.py first exercise
picam2_qt5_2024-01-03.py Added Auto-Focus feature detection, and switch AF Mode between Continuous & Manual
picam2_qt5_2024-01-07.py Display Preview in seperated window, both Main/Preview windows have Capture button.
picam2_qt5_2024-01-13.py Add camera_controls to adjust brightness at runtime.
Handle sys.argv, such that user can select cam at command line.
"""
import sys, platform, os
from PyQt5.QtWidgets import (QMainWindow, QApplication, QPushButton, QLabel, QCheckBox,
QWidget, QTabWidget, QVBoxLayout, QGridLayout,
QGroupBox, QSlider)
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QFont
from picamera2 import Picamera2
from picamera2.previews.qt import QGlPicamera2
from picamera2 import __name__ as picamera2_name
from libcamera import controls
import time
from importlib.metadata import version
os.environ["LIBCAMERA_LOG_LEVELS"] = "3"
"""
Because my Camera Module 3 (with Auto-Focus) is assigned to Picamera2(1),
so I make 1 as default
command line usage:
python picam2_qt5_xxx.py # using default cam
python picam2_qt5_xxx.py 0 # using cam 0
python picam2_qt5_xxx.py 1 # using cam 1
"""
DEFAULT_CAM_NUM = 1
cam_num = DEFAULT_CAM_NUM # default Picamera2(DEFAULT_CAM_NUM)
if len(sys.argv)==2:
if sys.argv[1] == "1":
cam_num = 1
if sys.argv[1] == "0":
cam_num = 0
print("picam2 = Picamera2("+str(cam_num)+")")
picam2 = Picamera2(cam_num)
#picam2 = Picamera2() #default to Picamera2(0) without parameter passed
#picam2 = Picamera2(1)
#=====================================
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})
picam2.configure(preview_config_raw)
#=====================================
#Detect if AF function is available
AF_Function = True
AF_Enable = True
try:
picam2.set_controls({"AfMode": controls.AfModeEnum.Continuous})
print("Auto-Focus Function Enabled")
except RuntimeError as err:
print("RuntimeError:", err)
AF_Function = False
#=====================================
class App(QMainWindow):
def __init__(self):
super().__init__()
self.title = sys.argv[0] #__file__
self.left = 0
self.top = 0
self.setWindowTitle(self.title)
self.main_widget = MyMainWidget(self)
self.setCentralWidget(self.main_widget)
self.show()
# factors to convert control's values in float to int for PyQt5 Widgets
FACTOR_BRIGHTNESS = 10
class MyMainWidget(QWidget):
#--- MyPreviewWidget ---
#inner class for Preview Window
class MyPreviewWidget(QWidget):
def __init__(self, subLayout):
super(QWidget, self).__init__()
self.setLayout(subLayout)
#--- End of MyPreviewWidget ---
def read_f(self, file):
with open(file, encoding='UTF-8') as reader:
content = reader.read()
return content
def read_pretty_name(self):
with open("/etc/os-release", encoding='UTF-8') as f:
os_release = {}
for line in f:
k,v = line.rstrip().split("=")
os_release[k] = v.strip('"')
return os_release['PRETTY_NAME']
def AF_Enable_CheckBox_onStateChanged(self):
if self.AF_Enable_CheckBox.isChecked():
picam2.set_controls({"AfMode": controls.AfModeEnum.Continuous})
else:
picam2.set_controls({"AfMode": controls.AfModeEnum.Manual})
def on_Brightness_valueChanged(self):
sender = self.sender()
valueBrightness = float(sender.value())/FACTOR_BRIGHTNESS
self.labelBrightness.setText("Brightness: " + str(valueBrightness))
def on_Brightness_sliderReleased(self):
sender = self.sender()
valueBrightness = float(sender.value())/FACTOR_BRIGHTNESS
with picam2.controls as controls:
controls.Brightness = valueBrightness
print("on_Brightness_sliderReleased:", valueBrightness)
def on_Capture_Clicked(self):
# There are two buttons on Main/Child Window connected here,
# identify the sender for info only, no actual use.
sender = self.sender()
if sender is self.btnCapture:
print("Capture button on Main Window clicked")
if sender is self.btnChildCapture:
print("Capture button on Child Preview Window clicked")
self.btnCapture.setEnabled(False)
cfg = picam2.create_still_configuration()
timeStamp = time.strftime("%Y%m%d-%H%M%S")
targetPath="/home/pi/Desktop/img_"+timeStamp+".jpg"
print("- Capture image:", targetPath)
picam2.switch_mode_and_capture_file(cfg, targetPath, signal_function=self.qpicamera2.signal_done)
def capture_done(self, job):
result = picam2.wait(job)
self.btnCapture.setEnabled(True)
print("- capture_done.")
print(result)
def __init__(self, parent):
super(QWidget, self).__init__(parent)
#--- Prepare child Preview Window ----------
self.childPreviewLayout = QVBoxLayout()
# Check Auto-Focus feature
if AF_Function:
self.AF_Enable_CheckBox = QCheckBox("Auto-Focus (Continuous)")
self.AF_Enable_CheckBox.setChecked(True)
self.AF_Enable_CheckBox.setEnabled(True)
self.AF_Enable_CheckBox.stateChanged.connect(self.AF_Enable_CheckBox_onStateChanged)
self.childPreviewLayout.addWidget(self.AF_Enable_CheckBox)
print("show Auto-Focus Mode Change QCheckBox")
else:
self.AF_Enable_CheckBox = QCheckBox("No Auto-Focus function")
self.AF_Enable_CheckBox.setChecked(False)
self.AF_Enable_CheckBox.setEnabled(False)
print("No Auto-Focus Mode Change QCheckBox")
# Preview qpicamera2
self.qpicamera2 = QGlPicamera2(picam2,
width=preview_width, height=preview_height,
keep_ar=True)
self.qpicamera2.done_signal.connect(self.capture_done)
self.childPreviewLayout.addWidget(self.qpicamera2)
# Capture button on Child Window
self.btnChildCapture = QPushButton("Capture Image" + str(cam_num))
self.btnChildCapture.setFont(QFont("Helvetica", 13, QFont.Bold))
self.btnChildCapture.clicked.connect(self.on_Capture_Clicked)
self.childPreviewLayout.addWidget(self.btnChildCapture)
# pass layout to child Preview Window
self.myPreviewWindow = self.MyPreviewWidget(self.childPreviewLayout)
# roughly set Preview windows size according to preview_width x preview_height
self.myPreviewWindow.setGeometry(10, 10, preview_width+10, preview_height+100)
self.myPreviewWindow.setWindowTitle("Preview size (" + str(cam_num) + ") - " +
str(preview_width) + " x " + str(preview_height))
self.myPreviewWindow.show()
#--- End of Prepare child Preview Window ---
self.layout = QVBoxLayout()
# Initialize tab screen
self.tabs = QTabWidget()
self.tabControl = QWidget()
self.tabInfo = QWidget()
# Add tabs
self.tabs.addTab(self.tabControl,"Control")
self.tabs.addTab(self.tabInfo, " Info ")
#=== Tab Capture ===
# Create first tab
self.tabControl.layout = QVBoxLayout()
self.btnCapture = QPushButton("Capture Image " + str(cam_num))
self.btnCapture.setFont(QFont("Helvetica", 15, QFont.Bold))
self.btnCapture.clicked.connect(self.on_Capture_Clicked)
self.tabControl.layout.addWidget(self.btnCapture)
# Prepre camera_controls
cam_controls = picam2.camera_controls
# gboxCamControls: QGroupBox to hold all controls
self.gboxCamControls = QGroupBox()
self.gboxCamControls.setTitle("picam2.camera_controls")
self.vboxCamControls = QVBoxLayout()
self.gboxCamControls.setLayout(self.vboxCamControls)
self.tabControl.layout.addWidget(self.gboxCamControls)
# - Control Brightness -
self.sliderBrightness = QSlider(Qt.Horizontal)
self.sliderBrightness.setMinimum(int(cam_controls["Brightness"][0]*FACTOR_BRIGHTNESS))
self.sliderBrightness.setMaximum(int(cam_controls["Brightness"][1]*FACTOR_BRIGHTNESS))
value = cam_controls["Brightness"][2]
self.sliderBrightness.setValue(int(value*FACTOR_BRIGHTNESS))
self.sliderBrightness.setTickPosition(QSlider.TicksBelow)
self.sliderBrightness.setTickInterval(1)
self.sliderBrightness.sliderReleased.connect(self.on_Brightness_sliderReleased)
self.sliderBrightness.valueChanged.connect(self.on_Brightness_valueChanged)
self.labelBrightness = QLabel("Brightness: " + str(value))
self.vboxCamControls.addWidget(self.labelBrightness)
self.vboxCamControls.addWidget(self.sliderBrightness)
# - End of Control Brightness -
self.labelMore = QLabel("...more controls will be placed here in coming exercises.")
self.vboxCamControls.addWidget(self.labelMore)
# End of Prepre camera_controls
self.tabControl.layout.addStretch()
self.tabControl.setLayout(self.tabControl.layout)
#=== Tab Info ===
self.tabInfo.layout = QVBoxLayout()
infoGridLayout = QGridLayout()
rowSpan = 1
columnSpan0 = 1
columnSpan1 = 5
infoGridLayout.addWidget(QLabel('Python', self), 0, 0, rowSpan, columnSpan0)
infoGridLayout.addWidget(QLabel(platform.python_version(), self), 0, 1, rowSpan, columnSpan1)
infoGridLayout.addWidget(QLabel(picamera2_name, self), 1, 0, rowSpan, columnSpan0)
infoGridLayout.addWidget(QLabel(version(picamera2_name), self), 1, 1, rowSpan, columnSpan1)
infoGridLayout.addWidget(QLabel(' ', self), 2, 0, rowSpan, columnSpan0)
infoGridLayout.addWidget(QLabel('Camera Module:', self), 3, 0, rowSpan, columnSpan0)
cam_properties = picam2.camera_properties
cam_Model = cam_properties['Model']
infoGridLayout.addWidget(QLabel('Model', self), 4, 0, rowSpan, columnSpan0)
infoGridLayout.addWidget(QLabel(cam_Model, self), 4, 1, rowSpan, columnSpan1)
cam_PixelArraySize = str(cam_properties['PixelArraySize'][0]) + " x " + str(cam_properties['PixelArraySize'][1])
infoGridLayout.addWidget(QLabel('PixelArraySize', self), 5, 0, rowSpan, columnSpan0)
infoGridLayout.addWidget(QLabel(cam_PixelArraySize, self), 5, 1, rowSpan, columnSpan1)
infoGridLayout.addWidget(QLabel(' ', self), 6, 0, rowSpan, columnSpan0)
infoGridLayout.addWidget(QLabel('Machine:', self), 7, 0, rowSpan, columnSpan0)
infoGridLayout.addWidget(QLabel('Board', self), 8, 0, rowSpan, columnSpan0, Qt.AlignTop)
board_def = "/proc/device-tree/model"
board_info = self.read_f("/proc/device-tree/model") +"\n(" + board_def +")"
infoGridLayout.addWidget(QLabel(board_info, self), 8, 1, rowSpan, columnSpan0)
infoGridLayout.addWidget(QLabel('OS', self), 9, 0, rowSpan, columnSpan0, Qt.AlignTop)
os_info = self.read_pretty_name() + "\n" + os.uname()[3] +"\n" + os.uname()[4] \
+ (" (64-bit)" if sys.maxsize > 2**32 else " (32-bit)")
infoGridLayout.addWidget(QLabel(os_info, self), 9, 1, rowSpan, columnSpan1)
self.tabInfo.layout.addLayout(infoGridLayout)
self.tabInfo.layout.addStretch()
self.tabInfo.setLayout(self.tabInfo.layout)
#==================================
# Add tabs to widget
self.layout.addWidget(self.tabs)
self.setLayout(self.layout)
picam2.start()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = App()
sys.exit(app.exec_())
Updated 2024-01-15: Add camera_controls: brightness, Contrast, ExposureValue, Saturation & Sharpness.
picam2_qt5_2024-01-15.py
"""
Python 3/PyQt5 + picamera2 to control Raspberry Pi Camera Modules
Tested on Raspberry Pi 5/64-bit Raspberry Pi OS (bookworm)
# in my setup:
# Picamera2(0) - HQ Camera
# Picamera2(1) - Camera Module 3
picam2_qt5_2023-12-28.py first exercise
picam2_qt5_2024-01-03.py Added Auto-Focus feature detection, and switch AF Mode between Continuous & Manual
picam2_qt5_2024-01-07.py Display Preview in seperated window, both Main/Preview windows have Capture button.
picam2_qt5_2024-01-13.py Add camera_controls to adjust brightness at runtime.
Handle sys.argv, such that user can select cam at command line.
picam2_qt5_2024-01-15.py Add camera_controls: brightness, Contrast, ExposureValue, Saturation & Sharpness.
"""
import sys, platform, os
from PyQt5.QtWidgets import (QMainWindow, QApplication, QPushButton, QLabel, QCheckBox,
QWidget, QTabWidget, QVBoxLayout, QGridLayout,
QGroupBox, QSlider)
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QFont
from picamera2 import Picamera2
from picamera2.previews.qt import QGlPicamera2
from picamera2 import __name__ as picamera2_name
from libcamera import controls
import time
from importlib.metadata import version
os.environ["LIBCAMERA_LOG_LEVELS"] = "3"
"""
Because my Camera Module 3 (with Auto-Focus) is assigned to Picamera2(1),
so I make 1 as default
command line usage:
python picam2_qt5_xxx.py # using default cam
python picam2_qt5_xxx.py 0 # using cam 0
python picam2_qt5_xxx.py 1 # using cam 1
"""
DEFAULT_CAM_NUM = 1
cam_num = DEFAULT_CAM_NUM # default Picamera2(DEFAULT_CAM_NUM)
if len(sys.argv)==2:
if sys.argv[1] == "1":
cam_num = 1
if sys.argv[1] == "0":
cam_num = 0
print("picam2 = Picamera2("+str(cam_num)+")")
picam2 = Picamera2(cam_num)
#picam2 = Picamera2() #default to Picamera2(0) without parameter passed
#picam2 = Picamera2(1)
#=====================================
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})
picam2.configure(preview_config_raw)
#=====================================
#Detect if AF function is available
AF_Function = True
AF_Enable = True
try:
picam2.set_controls({"AfMode": controls.AfModeEnum.Continuous})
print("Auto-Focus Function Enabled")
except RuntimeError as err:
print("RuntimeError:", err)
AF_Function = False
#=====================================
class App(QMainWindow):
def __init__(self):
super().__init__()
self.title = sys.argv[0] #__file__
self.left = 0
self.top = 0
self.setWindowTitle(self.title)
self.main_widget = MyMainWidget(self)
self.setCentralWidget(self.main_widget)
self.show()
# factors to convert control's values in float to int for PyQt5 Widgets
FACTOR_Brighness = 10
FACTOR_1 = 1
FACTOR_10 = 10
class MyMainWidget(QWidget):
#--- MyPreviewWidget ---
#inner class for Preview Window
class MyPreviewWidget(QWidget):
def __init__(self, subLayout):
super(QWidget, self).__init__()
self.setLayout(subLayout)
#--- End of MyPreviewWidget ---
# --- SliderSetting ---
#inner class for picam2.controls of float with slider setting
class SliderSetting:
def on_Setting_valueChanged(self):
value = float(self.sliderSetting.value())/self.factor
self.labelSetting.setText(self.setting_name + ": " + str(value))
def on_Setting_sliderReleased(self):
valueSetting = float(self.sliderSetting.value())/self.factor
self.callback(self.setting_name, valueSetting)
def __init__(self, setting_name, factor, callback):
self.setting_name = setting_name
self.factor = factor
self.callback = callback
cam_controls = picam2.camera_controls
self.sliderSetting = QSlider(Qt.Horizontal)
self.sliderSetting.setMinimum(int(cam_controls[self.setting_name][0]*self.factor))
self.sliderSetting.setMaximum(int(cam_controls[self.setting_name][1]*self.factor))
value = cam_controls[self.setting_name][2]
self.sliderSetting.setValue(int(value*self.factor))
self.sliderSetting.setTickPosition(QSlider.TicksBelow)
self.sliderSetting.setTickInterval(1)
self.sliderSetting.sliderReleased.connect(self.on_Setting_sliderReleased)
self.sliderSetting.valueChanged.connect(self.on_Setting_valueChanged)
self.labelSetting = QLabel(self.setting_name + ": " + str(value))
#--- End of SliderSetting ---
def read_f(self, file):
with open(file, encoding='UTF-8') as reader:
content = reader.read()
return content
def read_pretty_name(self):
with open("/etc/os-release", encoding='UTF-8') as f:
os_release = {}
for line in f:
k,v = line.rstrip().split("=")
os_release[k] = v.strip('"')
return os_release['PRETTY_NAME']
def AF_Enable_CheckBox_onStateChanged(self):
with picam2.controls as cam_controls:
if self.AF_Enable_CheckBox.isChecked():
cam_controls.AfMode = controls.AfModeEnum.Continuous
else:
cam_controls.AfMode = controls.AfModeEnum.Manual
def on_Capture_Clicked(self):
# There are two buttons on Main/Child Window connected here,
# identify the sender for info only, no actual use.
sender = self.sender()
if sender is self.btnCapture:
print("Capture button on Main Window clicked")
if sender is self.btnChildCapture:
print("Capture button on Child Preview Window clicked")
self.btnCapture.setEnabled(False)
cfg = picam2.create_still_configuration()
timeStamp = time.strftime("%Y%m%d-%H%M%S")
targetPath="/home/pi/Desktop/img" + str(cam_num) + "_"+timeStamp+".jpg"
print("- Capture image:", targetPath)
picam2.switch_mode_and_capture_file(cfg, targetPath, signal_function=self.qpicamera2.signal_done)
def capture_done(self, job):
result = picam2.wait(job)
self.btnCapture.setEnabled(True)
print("- capture_done.")
print(result)
def __init__(self, parent):
super(QWidget, self).__init__(parent)
#--- Prepare child Preview Window ----------
self.childPreviewLayout = QVBoxLayout()
# Check Auto-Focus feature
if AF_Function:
self.AF_Enable_CheckBox = QCheckBox("Auto-Focus (Continuous)")
self.AF_Enable_CheckBox.setChecked(True)
self.AF_Enable_CheckBox.setEnabled(True)
self.AF_Enable_CheckBox.stateChanged.connect(self.AF_Enable_CheckBox_onStateChanged)
self.childPreviewLayout.addWidget(self.AF_Enable_CheckBox)
print("show Auto-Focus Mode Change QCheckBox")
else:
self.AF_Enable_CheckBox = QCheckBox("No Auto-Focus function")
self.AF_Enable_CheckBox.setChecked(False)
self.AF_Enable_CheckBox.setEnabled(False)
print("No Auto-Focus Mode Change QCheckBox")
# Preview qpicamera2
self.qpicamera2 = QGlPicamera2(picam2,
width=preview_width, height=preview_height,
keep_ar=True)
self.qpicamera2.done_signal.connect(self.capture_done)
self.childPreviewLayout.addWidget(self.qpicamera2)
# Capture button on Child Window
self.btnChildCapture = QPushButton("Capture Image" + str(cam_num))
self.btnChildCapture.setFont(QFont("Helvetica", 13, QFont.Bold))
self.btnChildCapture.clicked.connect(self.on_Capture_Clicked)
self.childPreviewLayout.addWidget(self.btnChildCapture)
# pass layout to child Preview Window
self.myPreviewWindow = self.MyPreviewWidget(self.childPreviewLayout)
# roughly set Preview windows size according to preview_width x preview_height
self.myPreviewWindow.setGeometry(10, 10, preview_width+10, preview_height+100)
self.myPreviewWindow.setWindowTitle("Preview size (" + str(cam_num) + ") - " +
str(preview_width) + " x " + str(preview_height))
self.myPreviewWindow.show()
#--- End of Prepare child Preview Window ---
self.layout = QVBoxLayout()
# Initialize tab screen
self.tabs = QTabWidget()
self.tabControl = QWidget()
self.tabInfo = QWidget()
# Add tabs
self.tabs.addTab(self.tabControl,"Control")
self.tabs.addTab(self.tabInfo, " Info ")
#=== Tab Capture ===
# Create first tab
self.tabControl.layout = QVBoxLayout()
self.btnCapture = QPushButton("Capture Image " + str(cam_num))
self.btnCapture.setFont(QFont("Helvetica", 15, QFont.Bold))
self.btnCapture.clicked.connect(self.on_Capture_Clicked)
self.tabControl.layout.addWidget(self.btnCapture)
# Prepre camera_controls
cam_controls = picam2.camera_controls
# gboxCamControls: QGroupBox to hold all controls
self.gboxCamControls = QGroupBox()
self.gboxCamControls.setTitle("picam2.camera_controls")
self.vboxCamControls = QVBoxLayout()
self.gboxCamControls.setLayout(self.vboxCamControls)
self.tabControl.layout.addWidget(self.gboxCamControls)
# - More Control Setting -
#Brightness
def callback_Brightness(setting_name, value):
with picam2.controls as cam_controls:
cam_controls.Brightness = value
print(str(value), "=>", setting_name, "=", str(cam_controls.Brightness))
self.sliderBrightness = self.SliderSetting("Brightness", 10, callback_Brightness)
self.vboxCamControls.addWidget(self.sliderBrightness.labelSetting)
self.vboxCamControls.addWidget(self.sliderBrightness.sliderSetting)
#Contrast
def callback_Contrast(setting_name, value):
with picam2.controls as cam_controls:
cam_controls.Contrast = value
print(str(value), "=>", setting_name, "=", str(cam_controls.Contrast))
self.sliderContrast = self.SliderSetting("Contrast", 1, callback_Contrast)
self.vboxCamControls.addWidget(self.sliderContrast.labelSetting)
self.vboxCamControls.addWidget(self.sliderContrast.sliderSetting)
#ExposureValue
def callback_ExposureValue(setting_name, value):
with picam2.controls as cam_controls:
cam_controls.ExposureValue = value
print(str(value), "=>", setting_name, "=", str(cam_controls.ExposureValue))
self.sliderExposureValue = self.SliderSetting("ExposureValue", 1, callback_ExposureValue)
self.vboxCamControls.addWidget(self.sliderExposureValue.labelSetting)
self.vboxCamControls.addWidget(self.sliderExposureValue.sliderSetting)
#Saturation
def callback_Saturation(setting_name, value):
with picam2.controls as cam_controls:
cam_controls.Saturation = value
print(str(value), "=>", setting_name, "=", str(cam_controls.Saturation))
self.sliderSaturation = self.SliderSetting("Saturation", 1, callback_Saturation)
self.vboxCamControls.addWidget(self.sliderSaturation.labelSetting)
self.vboxCamControls.addWidget(self.sliderSaturation.sliderSetting)
#Sharpness
def callback_Sharpness(setting_name, value):
with picam2.controls as cam_controls:
cam_controls.Sharpness = value
print(str(value), "=>", setting_name, "=", str(cam_controls.Sharpness))
self.sliderSharpness = self.SliderSetting("Sharpness", 1, callback_Sharpness)
self.vboxCamControls.addWidget(self.sliderSharpness.labelSetting)
self.vboxCamControls.addWidget(self.sliderSharpness.sliderSetting)
# - End of Control Setting -
self.labelMore = QLabel("...more controls will be placed here in coming exercises.")
self.vboxCamControls.addWidget(self.labelMore)
# End of Prepre camera_controls
self.tabControl.layout.addStretch()
self.tabControl.setLayout(self.tabControl.layout)
#=== Tab Info ===
self.tabInfo.layout = QVBoxLayout()
infoGridLayout = QGridLayout()
rowSpan = 1
columnSpan0 = 1
columnSpan1 = 5
infoGridLayout.addWidget(QLabel('Python', self), 0, 0, rowSpan, columnSpan0)
infoGridLayout.addWidget(QLabel(platform.python_version(), self), 0, 1, rowSpan, columnSpan1)
infoGridLayout.addWidget(QLabel(picamera2_name, self), 1, 0, rowSpan, columnSpan0)
infoGridLayout.addWidget(QLabel(version(picamera2_name), self), 1, 1, rowSpan, columnSpan1)
infoGridLayout.addWidget(QLabel(' ', self), 2, 0, rowSpan, columnSpan0)
infoGridLayout.addWidget(QLabel('Camera Module:', self), 3, 0, rowSpan, columnSpan0)
cam_properties = picam2.camera_properties
cam_Model = cam_properties['Model']
infoGridLayout.addWidget(QLabel('Model', self), 4, 0, rowSpan, columnSpan0)
infoGridLayout.addWidget(QLabel(cam_Model, self), 4, 1, rowSpan, columnSpan1)
cam_PixelArraySize = str(cam_properties['PixelArraySize'][0]) + " x " + str(cam_properties['PixelArraySize'][1])
infoGridLayout.addWidget(QLabel('PixelArraySize', self), 5, 0, rowSpan, columnSpan0)
infoGridLayout.addWidget(QLabel(cam_PixelArraySize, self), 5, 1, rowSpan, columnSpan1)
infoGridLayout.addWidget(QLabel(' ', self), 6, 0, rowSpan, columnSpan0)
infoGridLayout.addWidget(QLabel('Machine:', self), 7, 0, rowSpan, columnSpan0)
infoGridLayout.addWidget(QLabel('Board', self), 8, 0, rowSpan, columnSpan0, Qt.AlignTop)
board_def = "/proc/device-tree/model"
board_info = self.read_f("/proc/device-tree/model") +"\n(" + board_def +")"
infoGridLayout.addWidget(QLabel(board_info, self), 8, 1, rowSpan, columnSpan0)
infoGridLayout.addWidget(QLabel('OS', self), 9, 0, rowSpan, columnSpan0, Qt.AlignTop)
os_info = self.read_pretty_name() + "\n" + os.uname()[3] +"\n" + os.uname()[4] \
+ (" (64-bit)" if sys.maxsize > 2**32 else " (32-bit)")
infoGridLayout.addWidget(QLabel(os_info, self), 9, 1, rowSpan, columnSpan1)
self.tabInfo.layout.addLayout(infoGridLayout)
self.tabInfo.layout.addStretch()
self.tabInfo.setLayout(self.tabInfo.layout)
#==================================
# Add tabs to widget
self.layout.addWidget(self.tabs)
self.setLayout(self.layout)
picam2.start()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = App()
sys.exit(app.exec_())
next:
~ 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
Post a Comment