- read metadata in callback

- clamp shutter speed to frame duration minimum
This commit is contained in:
2024-07-15 17:27:24 +02:00
parent 10a4a9a3de
commit 06be8c83ea
2 changed files with 63 additions and 42 deletions
+59 -38
View File
@@ -1,6 +1,7 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
from typing import Union, overload from typing import Union, overload
from picamera2 import Picamera2, MappedArray from picamera2 import Picamera2, MappedArray, Metadata
from pprint import pprint from pprint import pprint
import json import json
import cv2 import cv2
@@ -38,11 +39,10 @@ picam2 = Picamera2()
pprint(picam2.sensor_modes) pprint(picam2.sensor_modes)
settings = {'NoiseReductionMode': 0, 'AeExposureMode': 0, 'ExposureTime': 10000, 'AnalogueGain': 1, 'FrameRate': picam2.sensor_modes[0]['fps']} settings = {'NoiseReductionMode': 0, 'AeExposureMode': 0, 'ExposureTime': 10000, 'AnalogueGain': 1, 'FrameRate': picam2.sensor_modes[0]['fps']}
caps = {"FrameRate": (1, picam2.sensor_modes[0]['fps'], None)} caps = {"FrameRate": (1, picam2.sensor_modes[0]['fps'], None)}
fps = 0
def load_settings(): def load_settings():
_result = None _result = {}
try: try:
with open("settings.json", "r") as fp: with open("settings.json", "r") as fp:
_result = json.load(fp) _result = json.load(fp)
@@ -77,23 +77,38 @@ def set_value(item: str, value):
def get_value(item: str): def get_value(item: str):
return picam2.camera_controls[item] return picam2.camera_controls[item]
fps_ist = 0
fps_soll = 0
def process(request): def process(request):
global fps
timestamp = time.strftime("%Y-%m-%d %X") timestamp = time.strftime("%Y-%m-%d %X")
# read metadata from request
metadata = Metadata(request.get_metadata())
# Clamp our shutter value to minimum of FrameDuration
caps["ExposureTime"] = (caps["ExposureTime"][0], metadata.FrameDuration)
with MappedArray(request, "main") as m: with MappedArray(request, "main") as m:
# Display timestamp on frame # Display timestamp on frame
cv2.putText(m.array, timestamp, (0, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2) cv2.putText(m.array, timestamp, (0, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
if metadata is not None:
# Display exposure time
cv2.putText(m.array, f"ExposureTime : {metadata.ExposureTime:.1f}/{shutter:.1f}", (20, m.array.shape[0] - 80), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 240, 0), 2)
# Display frame time
cv2.putText(m.array, f"FrameDuration : {metadata.FrameDuration:.1f}", (20, m.array.shape[0] - 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 240, 0), 2)
# Display FPS on frame # Display FPS on frame
cv2.putText(m.array, "FPS : " + str(int(fps)), (20, m.array.shape[0] - 20), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 240, 0), 2) cv2.putText(m.array, f"Frame rate : {fps_ist:.1f}/{fps_soll:.1f}", (20, m.array.shape[0] - 20), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 240, 0), 2)
if __name__ == '__main__': if __name__ == '__main__':
for item in items: for item in items:
try: try:
caps[item] = picam2.camera_controls[item] caps[item] = (picam2.camera_controls[item][0], picam2.camera_controls[item][1])
except KeyError: except KeyError:
print(f"{item}: Not implemented") print(f"{item}: Not implemented")
@@ -102,25 +117,32 @@ if __name__ == '__main__':
camera_config = picam2.create_preview_configuration({'format': 'XRGB8888', 'size': (800, 600)}) camera_config = picam2.create_preview_configuration({'format': 'XRGB8888', 'size': (800, 600)})
picam2.configure(camera_config) picam2.configure(camera_config)
# Load and apply our settings
settings |= load_settings() settings |= load_settings()
shutter = settings['ExposureTime']
gain = settings['AnalogueGain']
fps = settings['FrameRate']
apply_settings(settings) apply_settings(settings)
# Init vars
shutter = settings['ExposureTime']
gain = settings['AnalogueGain']
fps_soll = settings['FrameRate']
# Print status
pprint(f"Capabilities: {caps}") pprint(f"Capabilities: {caps}")
pprint(f"Settings: {settings}") pprint(f"Settings: {settings}")
pprint(f"Camera config: {picam2.camera_configuration()}") pprint(f"Camera config: {picam2.camera_configuration()}")
# Start # Register OCV processing callback
picam2.pre_callback = process picam2.pre_callback = process
# Start
picam2.start() picam2.start()
while True: while True:
# Start timer # Start timer
timer = cv2.getTickCount() timer = cv2.getTickCount()
# Capture frame
frame = picam2.capture_array("main") frame = picam2.capture_array("main")
# Process the frame using OpenCV operations # Process the frame using OpenCV operations
@@ -132,63 +154,62 @@ if __name__ == '__main__':
break break
elif key == ord('w'): elif key == ord('w'):
shutter -= 1000 shutter -= 1000
shutter = set_value('ExposureTime', shutter)
print(f"Shutter: {shutter}") print(f"Shutter: {shutter}")
elif key == ord('s'): elif key == ord('s'):
shutter -= 100 shutter -= 100
shutter = set_value('ExposureTime', shutter)
print(f"Shutter: {shutter}") print(f"Shutter: {shutter}")
elif key == ord('x'): elif key == ord('x'):
shutter -= 1 shutter -= 1
shutter = set_value('ExposureTime', shutter)
print(f"Shutter: {shutter}") print(f"Shutter: {shutter}")
elif key == ord('e'): elif key == ord('e'):
shutter += 1000 shutter += 1000
shutter = set_value('ExposureTime', shutter)
print(f"Shutter: {shutter}") print(f"Shutter: {shutter}")
elif key == ord('d'): elif key == ord('d'):
shutter += 100 shutter += 100
shutter = set_value('ExposureTime', shutter)
print(f"Shutter: {shutter}") print(f"Shutter: {shutter}")
elif key == ord('c'): elif key == ord('c'):
shutter += 1 shutter += 1
shutter = set_value('ExposureTime', shutter)
print(f"Shutter: {shutter}") print(f"Shutter: {shutter}")
elif key == ord('h'): elif key == ord('h'):
gain -= 1 gain -= 1
gain = set_value('AnalogueGain', gain)
print(f"Gain: {gain}") print(f"Gain: {gain}")
elif key == ord('j'): elif key == ord('j'):
gain += 1 gain += 1
gain = set_value('AnalogueGain', gain)
print(f"Gain: {gain}") print(f"Gain: {gain}")
elif key == ord('r'): elif key == ord('r'):
fps -= 1 fps_soll -= 1
fps = set_value('FrameRate', fps) print(f"FPS: {fps_soll}")
print(f"FPS: {fps}")
elif key == ord('f'): elif key == ord('f'):
fps -= 0.1 fps_soll -= 0.1
fps = set_value('FrameRate', fps) print(f"FPS: {fps_soll}")
print(f"FPS: {fps}")
elif key == ord('v'): elif key == ord('v'):
fps -= 0.01 fps_soll -= 0.01
fps = set_value('FrameRate', fps) print(f"FPS: {fps_soll}")
print(f"FPS: {fps}")
elif key == ord('t'): elif key == ord('t'):
fps += 1 fps_soll += 1
fps = set_value('FrameRate', fps) print(f"FPS: {fps_soll}")
print(f"FPS: {fps}")
elif key == ord('g'): elif key == ord('g'):
fps += 0.1 fps_soll += 0.1
fps = set_value('FrameRate', fps) print(f"FPS: {fps_soll}")
print(f"FPS: {fps}")
elif key == ord('b'): elif key == ord('b'):
fps += 0.01 fps_soll += 0.01
fps = set_value('FrameRate', fps) print(f"FPS: {fps_soll}")
print(f"FPS: {fps}")
# Update control settings and keep vars within ranges
shutter = set_value('ExposureTime', shutter)
gain = set_value('AnalogueGain', gain)
fps_soll = set_value('FrameRate', fps_soll)
# Write contrrols to camera
with picam2.controls as controls:
controls.ExposureTime = shutter
controls.AnalogueGain = gain
controls.FrameRate = fps_soll
# Calculate Frames per second (FPS) # Calculate Frames per second (FPS)
fps = cv2.getTickFrequency() / (cv2.getTickCount() - timer) fr = cv2.getTickFrequency() / (cv2.getTickCount() - timer)
alpha = 0.2
fps_ist = (1-alpha)*fps_ist + alpha*fr
# Release the capture and close windows # Release the capture and close windows
+2 -2
View File
@@ -1,7 +1,7 @@
{ {
"NoiseReductionMode": 0, "NoiseReductionMode": 0,
"AeExposureMode": 0, "AeExposureMode": 0,
"ExposureTime": 75030, "ExposureTime": 10000,
"AnalogueGain": 1.0, "AnalogueGain": 1.0,
"FrameRate": 10.580000000000002 "FrameRate": 60.38
} }