-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcamera.py
111 lines (91 loc) · 3.27 KB
/
camera.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
import time
from uuid import uuid4
import picamera2
import rawpy
from PIL import Image
def convert_dng_to_jpg(input_dng_file, output_jpg_file):
with rawpy.imread(input_dng_file) as raw:
rgb = raw.postprocess(
use_camera_wb=True,
output_color=rawpy.ColorSpace.sRGB,
)
image = Image.fromarray(rgb)
image.save(output_jpg_file, format="JPEG", quality=100)
SETTINGS = set(["exposure", "iso"])
class Camera:
def __init__(self, logger) -> None:
self.logger = logger
self.camera = picamera2.Picamera2()
self.config = self.camera.create_still_configuration(main={}, raw={})
self.settings = {
"exposure": 1000000,
"iso": 100,
}
self.refresh_controls()
self.init = False
def initialise_camera(self):
self.camera.start()
self.init = True
def release(self):
self.camera.stop()
def refresh_controls(self):
with self.camera.controls as ctrl:
ctrl.AnalogueGain = int(self.settings["iso"]) / 100
self.camera.shutter_speed = int(self.settings["exposure"]) * 1000
def step_preview(self):
impath = "static/preview/" + str(uuid4()) + ".png"
self.camera.start()
self.refresh_controls()
self.camera.capture_file(impath)
self.camera.stop()
return "../" + impath
def capture(self):
t = str(time.time())
impath = "static/captured-raw/" + t + ".dng"
impath_jpg = "static/captured/" + t + ".jpg"
if self.init:
self.release()
self.initialise_camera()
self.refresh_controls()
self.camera.capture_file(impath, "raw")
self.release()
self.logger.info(
f"[internals/_camera] Converting DNG to JPG for preview: {impath} -> {impath_jpg}"
)
convert_dng_to_jpg(impath, impath_jpg)
return "../" + impath_jpg
def setting(self, key, value):
if key not in SETTINGS:
self.logger.error(f"[internals/_camera] No such setting: {key}")
return "[!!]"
if key == "exposure":
try:
value = float(value)
if value <= 0:
self.logger.error(
f"[internals/_camera] Expected value > 0 for {key}, got {value}"
)
return "[!!]"
self.settings[key] = value
except Exception:
self.logger.error(
f"[internals/_camera] Cannot convert to float for {key}: {value}"
)
return "[!!]"
if key == "iso":
try:
value = int(value)
if value <= 0:
self.logger.error(
f"[internals/_camera] Expected natural number for {key}, got {value}"
)
return "[!!]"
self.settings[key] = value
except Exception:
self.logger.error(
f"[internals/_camera] Cannot convert to natural number: {value}"
)
return "[!!]"
self.refresh_controls()
self.logger.info(f"[internals/_camera] Setting {key} is now {value}!")
return "[OK]"