Add exposure control for picam
This commit is contained in:
parent
df0193a689
commit
85d31def6f
|
@ -154,9 +154,9 @@ class webcam():
|
||||||
capture_ok = cv2.imwrite(img_path, self.og_frame)
|
capture_ok = cv2.imwrite(img_path, self.og_frame)
|
||||||
return capture_ok
|
return capture_ok
|
||||||
|
|
||||||
def increment_setting(self, setting:str, value:int=-1):
|
def increment_setting(self, setting:str, inc:int=-1):
|
||||||
# If value has default -1 value, increment setting
|
# If value has default -1 value, increment setting
|
||||||
if value == -1:
|
if inc == -1:
|
||||||
if setting in self.camera_current_settings:
|
if setting in self.camera_current_settings:
|
||||||
if self.camera_current_settings[setting]['value'] + self.camera_current_settings[setting]['step'] in range(self.camera_current_settings[setting]['min'],self.camera_current_settings[setting]['max']+1):
|
if self.camera_current_settings[setting]['value'] + self.camera_current_settings[setting]['step'] in range(self.camera_current_settings[setting]['min'],self.camera_current_settings[setting]['max']+1):
|
||||||
self.camera_current_settings[setting]['value'] += self.camera_current_settings[setting]['step']
|
self.camera_current_settings[setting]['value'] += self.camera_current_settings[setting]['step']
|
||||||
|
@ -202,7 +202,7 @@ class webcam():
|
||||||
v4l2_ctl_process = subprocess.Popen(cmd.split(' '))
|
v4l2_ctl_process = subprocess.Popen(cmd.split(' '))
|
||||||
return v4l2_ctl_process
|
return v4l2_ctl_process
|
||||||
|
|
||||||
def apply_setting(self, to_set:list=None, inc:bool=False):
|
def apply_setting(self, to_set:list=None, inc:int=0):
|
||||||
cmd = self.build_v4l2_cmd(to_set)
|
cmd = self.build_v4l2_cmd(to_set)
|
||||||
self.run_v4l2_ctl(cmd)
|
self.run_v4l2_ctl(cmd)
|
||||||
return self.camera_current_settings
|
return self.camera_current_settings
|
||||||
|
@ -233,7 +233,7 @@ class showmewebcam(webcam):
|
||||||
'video_bitrate': dict(min=25000000, max=25000000, step=10000, default=camera_settings['video_bitrate'], value=camera_settings['video_bitrate']),
|
'video_bitrate': dict(min=25000000, max=25000000, step=10000, default=camera_settings['video_bitrate'], value=camera_settings['video_bitrate']),
|
||||||
}
|
}
|
||||||
|
|
||||||
def apply_setting(self, to_set:list=None, inc:bool=False):
|
def apply_setting(self, to_set:list=None, inc:int=0):
|
||||||
self.cmd, self.args = self.build_v4l2_cmd(to_set)
|
self.cmd, self.args = self.build_v4l2_cmd(to_set)
|
||||||
self.serialutils.send_serial_cmd(self.serialutils.find_cam_port(), self.cmd.format(*self.args))
|
self.serialutils.send_serial_cmd(self.serialutils.find_cam_port(), self.cmd.format(*self.args))
|
||||||
return self.camera_current_settings
|
return self.camera_current_settings
|
||||||
|
@ -246,13 +246,16 @@ class picam():
|
||||||
'white_balance_auto_preset': dict(min=0, max=7, step=1, default=camera_settings['white_balance_auto_preset'], value=camera_settings['white_balance_auto_preset']),
|
'white_balance_auto_preset': dict(min=0, max=7, step=1, default=camera_settings['white_balance_auto_preset'], value=camera_settings['white_balance_auto_preset']),
|
||||||
'horizontal_flip': dict(min=0, max=1, step=1, default=camera_settings['hflip'], value=camera_settings['hflip']),
|
'horizontal_flip': dict(min=0, max=1, step=1, default=camera_settings['hflip'], value=camera_settings['hflip']),
|
||||||
'vertical_flip': dict(min=0, max=1, step=1, default=camera_settings['vflip'], value=camera_settings['vflip']),
|
'vertical_flip': dict(min=0, max=1, step=1, default=camera_settings['vflip'], value=camera_settings['vflip']),
|
||||||
'anti_flicker': dict(min=0, max=2, step=1, default=1, value=1),
|
'anti_flicker': dict(min=0, max=20000, step=1000, default=0, value=0),
|
||||||
|
'exposure' : dict(min=0, max=50000, step=1000, default=0, value=0)
|
||||||
}
|
}
|
||||||
# Map generic config name to specific picamera setting name
|
# Map generic config name to specific picamera setting name
|
||||||
self.cam_settings_map = {
|
self.cam_settings_map = {
|
||||||
'white_balance_auto_preset': 'AwbMode',
|
'white_balance_auto_preset': 'AwbMode',
|
||||||
'auto_exposure':'AeExposureMode',
|
'auto_exposure':'AeExposureMode',
|
||||||
'anti_flicker' : 'AeFlickerMode',
|
'exposure':'ExposureTime',
|
||||||
|
# ~ 'anti_flicker' : 'AeFlickerMode',
|
||||||
|
'anti_flicker' : 'AeFlickerPeriod',
|
||||||
'lenspos' : 'LensPosition',
|
'lenspos' : 'LensPosition',
|
||||||
}
|
}
|
||||||
self.has_liveview = True
|
self.has_liveview = True
|
||||||
|
@ -269,12 +272,12 @@ class picam():
|
||||||
self.liveview_only = False
|
self.liveview_only = False
|
||||||
# Pi Cam V3 setup
|
# Pi Cam V3 setup
|
||||||
self.Picamera2 = getattr(import_module('picamera2'), 'Picamera2')
|
self.Picamera2 = getattr(import_module('picamera2'), 'Picamera2')
|
||||||
|
self.Metadata = getattr(import_module('picamera2'), 'Metadata')
|
||||||
self.Transform = getattr(import_module('libcamera'), 'Transform')
|
self.Transform = getattr(import_module('libcamera'), 'Transform')
|
||||||
# Cam setup
|
# Cam setup
|
||||||
self.cam = self.Picamera2()
|
self.cam = self.Picamera2()
|
||||||
self.picam_config = self.cam.create_video_configuration(main={"format": 'RGB888',"size": (camera_settings['cam_w'], camera_settings['cam_h'])})
|
self.picam_config = self.cam.create_video_configuration(main={"format": 'RGB888',"size": (camera_settings['cam_w'], camera_settings['cam_h'])})
|
||||||
self.picam_config["transform"] = self.Transform(vflip=self.camera_current_settings['vertical_flip']['value'],hflip=self.camera_current_settings['horizontal_flip']['value'])
|
self.picam_config["transform"] = self.Transform(vflip=self.camera_current_settings['vertical_flip']['value'],hflip=self.camera_current_settings['horizontal_flip']['value'])
|
||||||
|
|
||||||
self.cam.configure(self.picam_config)
|
self.cam.configure(self.picam_config)
|
||||||
# Autofocus, get lens position and switch to manual mode
|
# Autofocus, get lens position and switch to manual mode
|
||||||
# Set Af mode to Auto then Manual (0). Default is Continuous (2), Auto is 1
|
# Set Af mode to Auto then Manual (0). Default is Continuous (2), Auto is 1
|
||||||
|
@ -286,18 +289,24 @@ class picam():
|
||||||
self.camera_default_settings = {'AfMode': 0,
|
self.camera_default_settings = {'AfMode': 0,
|
||||||
'AwbEnable': 1,
|
'AwbEnable': 1,
|
||||||
'AwbMode': self.camera_current_settings['white_balance_auto_preset']['default'],
|
'AwbMode': self.camera_current_settings['white_balance_auto_preset']['default'],
|
||||||
|
# Disable Autoexposure
|
||||||
'AeEnable': 1,
|
'AeEnable': 1,
|
||||||
|
'ExposureTime': 0,
|
||||||
'AeExposureMode': self.camera_current_settings['auto_exposure']['default'],
|
'AeExposureMode': self.camera_current_settings['auto_exposure']['default'],
|
||||||
# Enable flicker avoidance due to mains
|
# Enable flicker avoidance due to mains
|
||||||
|
# AeFlickerModeEnum { FlickerOff = 0, FlickerManual = 1, FlickerAuto = 2 }
|
||||||
'AeFlickerMode': 1,
|
'AeFlickerMode': 1,
|
||||||
# Mains 50hz = 10000, 60hz = 8333
|
# Mains 50hz = 10000, 60hz = 8333
|
||||||
# ~ 'AeFlickerPeriod': 8333,
|
# ~ 'AeFlickerPeriod': 8333,
|
||||||
'AeFlickerPeriod': 10000,
|
'AeFlickerPeriod': self.camera_current_settings['anti_flicker']['default'],
|
||||||
# Format is (min, max, default) in ms
|
# Format is (min, max, default) in ms
|
||||||
# here: (60fps, 12fps, None)
|
# here: (60fps, 12fps, None)
|
||||||
# ~ 'FrameDurationLimits':(16666,83333,None)
|
# ~ 'FrameDurationLimits':(16666,83333,None)
|
||||||
}
|
}
|
||||||
self.cam.set_controls(self.camera_default_settings)
|
self.cam.set_controls(self.camera_default_settings)
|
||||||
|
# Get current exposure value and store it in settings
|
||||||
|
metadata = self.Metadata(self.cam.capture_metadata())
|
||||||
|
self.camera_current_settings['exposure']['value'] = self.camera_current_settings['exposure']['default'] = metadata.ExposureTime
|
||||||
|
|
||||||
def test_device(self, source):
|
def test_device(self, source):
|
||||||
pass
|
pass
|
||||||
|
@ -330,12 +339,18 @@ class picam():
|
||||||
capture_ok = cv2.imwrite(img_path, self.og_frame)
|
capture_ok = cv2.imwrite(img_path, self.og_frame)
|
||||||
return capture_ok
|
return capture_ok
|
||||||
|
|
||||||
def increment_setting(self, setting:str):
|
def increment_setting(self, setting:str, inc:int=1):
|
||||||
if setting in self.camera_current_settings:
|
if setting in self.camera_current_settings:
|
||||||
if self.camera_current_settings[setting]['value'] + self.camera_current_settings[setting]['step'] in range(self.camera_current_settings[setting]['min'],self.camera_current_settings[setting]['max']+1):
|
if inc == -1:
|
||||||
self.camera_current_settings[setting]['value'] += self.camera_current_settings[setting]['step']
|
if self.camera_current_settings[setting]['value'] - self.camera_current_settings[setting]['step'] in range(self.camera_current_settings[setting]['min'],self.camera_current_settings[setting]['max']+1):
|
||||||
else:
|
self.camera_current_settings[setting]['value'] -= self.camera_current_settings[setting]['step']
|
||||||
self.camera_current_settings[setting]['value'] = self.camera_current_settings[setting]['min']
|
else:
|
||||||
|
self.camera_current_settings[setting]['value'] = self.camera_current_settings[setting]['max']
|
||||||
|
elif inc == 1:
|
||||||
|
if self.camera_current_settings[setting]['value'] + self.camera_current_settings[setting]['step'] in range(self.camera_current_settings[setting]['min'],self.camera_current_settings[setting]['max']+1):
|
||||||
|
self.camera_current_settings[setting]['value'] += self.camera_current_settings[setting]['step']
|
||||||
|
else:
|
||||||
|
self.camera_current_settings[setting]['value'] = self.camera_current_settings[setting]['min']
|
||||||
# Special cases
|
# Special cases
|
||||||
# Autoexposure
|
# Autoexposure
|
||||||
if setting == 'autoexposure' and self.camera_current_settings['autoexposure']['value'] == 4:
|
if setting == 'autoexposure' and self.camera_current_settings['autoexposure']['value'] == 4:
|
||||||
|
@ -343,20 +358,16 @@ class picam():
|
||||||
else:
|
else:
|
||||||
self.cam.set_controls({'AeEnable': 0})
|
self.cam.set_controls({'AeEnable': 0})
|
||||||
self.cam.set_controls({"AeExposureMode": self.camera_current_settings['auto_exposure']['value']})
|
self.cam.set_controls({"AeExposureMode": self.camera_current_settings['auto_exposure']['value']})
|
||||||
# Antiflicker
|
return True
|
||||||
if setting == 'anti_flicker' and self.camera_current_settings['anti_flicker']['value'] == 0:
|
|
||||||
self.cam.set_controls({'AeFlickerMode': 0})
|
|
||||||
elif self.camera_current_settings['anti_flicker']['value'] == 1:
|
|
||||||
self.cam.set_controls({'AeFlickerMode': 1, 'AeFlickerPeriod':8333})
|
|
||||||
else:
|
|
||||||
self.cam.set_controls({'AeFlickerMode': 1, 'AeFlickerPeriod':10000})
|
|
||||||
|
|
||||||
def apply_setting(self, to_set:list=None, inc:bool=False):
|
def apply_setting(self, to_set:list=None, inc:int=0):
|
||||||
|
set_controls = False
|
||||||
if to_set is not None:
|
if to_set is not None:
|
||||||
for setting in to_set:
|
for setting in to_set:
|
||||||
if inc:
|
if inc != 0:
|
||||||
self.increment_setting(setting)
|
set_controls = self.increment_setting(setting, inc)
|
||||||
self.cam.set_controls({self.cam_settings_map[setting] : self.camera_current_settings[setting]['value']})
|
if set_controls:
|
||||||
|
self.cam.set_controls({self.cam_settings_map[setting] : self.camera_current_settings[setting]['value']})
|
||||||
|
|
||||||
def flip_image(self):
|
def flip_image(self):
|
||||||
self.cam.stop()
|
self.cam.stop()
|
||||||
|
@ -376,8 +387,11 @@ class picam():
|
||||||
print(_("-Lens pos: {}".format(self.lenspos)))
|
print(_("-Lens pos: {}".format(self.lenspos)))
|
||||||
|
|
||||||
def reset_picture_settings(self):
|
def reset_picture_settings(self):
|
||||||
for setting in self.camera_default_settings:
|
# ~ for setting in self.camera_default_settings:
|
||||||
self.cam.set_controls({setting : self.camera_default_settings[setting]})
|
# ~ self.cam.set_controls({setting : self.camera_default_settings[setting]})
|
||||||
|
self.cam.set_controls(self.camera_default_settings)
|
||||||
|
metadata = self.Metadata(self.cam.capture_metadata())
|
||||||
|
self.camera_current_settings['exposure']['value'] = self.camera_current_settings['exposure']['default'] = metadata.ExposureTime
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
self.cam.close()
|
self.cam.close()
|
||||||
|
@ -535,14 +549,14 @@ class dslr():
|
||||||
except:
|
except:
|
||||||
print("Configuration error while setting {} to {}".format(setting, select_setting))
|
print("Configuration error while setting {} to {}".format(setting, select_setting))
|
||||||
|
|
||||||
def increment_setting(self, setting:str):
|
def increment_setting(self, setting:str, inc:int=-1):
|
||||||
if setting in self.camera_current_settings:
|
if setting in self.camera_current_settings:
|
||||||
if self.camera_current_settings[setting]['value'] + self.camera_current_settings[setting]['step'] in range(self.camera_current_settings[setting]['min'],self.camera_current_settings[setting]['max']+1):
|
if self.camera_current_settings[setting]['value'] + self.camera_current_settings[setting]['step'] in range(self.camera_current_settings[setting]['min'],self.camera_current_settings[setting]['max']+1):
|
||||||
self.camera_current_settings[setting]['value'] += self.camera_current_settings[setting]['step']
|
self.camera_current_settings[setting]['value'] += self.camera_current_settings[setting]['step']
|
||||||
else:
|
else:
|
||||||
self.camera_current_settings[setting]['value'] = self.camera_current_settings[setting]['min']
|
self.camera_current_settings[setting]['value'] = self.camera_current_settings[setting]['min']
|
||||||
|
|
||||||
def apply_setting(self, to_set:list=None, inc:bool=False):
|
def apply_setting(self, to_set:list=None, inc:int=0):
|
||||||
self.camera_current_config = self.gp.check_result(self.gp.gp_camera_get_config(self.cam))
|
self.camera_current_config = self.gp.check_result(self.gp.gp_camera_get_config(self.cam))
|
||||||
# iterate over the settings dictionary
|
# iterate over the settings dictionary
|
||||||
if to_set is None:
|
if to_set is None:
|
||||||
|
@ -568,7 +582,7 @@ class dslr():
|
||||||
self.frame = cv2.flip(self.frame, -1)
|
self.frame = cv2.flip(self.frame, -1)
|
||||||
|
|
||||||
def focus(self, direction:str='-'):
|
def focus(self, direction:str='-'):
|
||||||
self.apply_setting(['shutterspeed'], True)
|
self.apply_setting(['shutterspeed'], 1)
|
||||||
|
|
||||||
def reset_picture_settings(self):
|
def reset_picture_settings(self):
|
||||||
self.camera_current_config = self.gp.check_result(self.gp.gp_camera_get_config(self.cam))
|
self.camera_current_config = self.gp.check_result(self.gp.gp_camera_get_config(self.cam))
|
||||||
|
@ -1020,11 +1034,11 @@ def main(args):
|
||||||
# Key w / 7 - cycle wb
|
# Key w / 7 - cycle wb
|
||||||
elif (k%256 == 119) or (k%256 == 55) or (k%256 == 183):
|
elif (k%256 == 119) or (k%256 == 55) or (k%256 == 183):
|
||||||
print(_("White balance mode"))
|
print(_("White balance mode"))
|
||||||
cam.apply_setting(['white_balance_auto_preset'], True)
|
cam.apply_setting(['white_balance_auto_preset'], 1)
|
||||||
# Key x / 1 - cycle exposure
|
# Key x / 1 - cycle exposure
|
||||||
elif (k%256 == 120) or (k%256 == 49) or (k%256 == 177):
|
elif (k%256 == 120) or (k%256 == 49) or (k%256 == 177):
|
||||||
print(_("Exp. mode"))
|
print(_("Exp. mode"))
|
||||||
cam.apply_setting(['auto_exposure'], True)
|
cam.apply_setting(['auto_exposure'], 1)
|
||||||
# Key f / 3 - flip image
|
# Key f / 3 - flip image
|
||||||
elif (k%256 == 102) or (k%256 == 51) or (k%256 == 179):
|
elif (k%256 == 102) or (k%256 == 51) or (k%256 == 179):
|
||||||
print(_("Flip image"))
|
print(_("Flip image"))
|
||||||
|
@ -1094,9 +1108,16 @@ def main(args):
|
||||||
elif (k%256 == 113):
|
elif (k%256 == 113):
|
||||||
print(_("Anti-flicker mode"))
|
print(_("Anti-flicker mode"))
|
||||||
cam.apply_setting(['anti_flicker'], True)
|
cam.apply_setting(['anti_flicker'], True)
|
||||||
# Unused : key S
|
print(cam.camera_current_settings['anti_flicker']['value'])
|
||||||
elif (k%256 == 115):
|
# Exposure : key S or maj A
|
||||||
pass
|
elif (k%256 == 115) or (k%256 == 65):
|
||||||
|
print(_("Inc. exposure"))
|
||||||
|
cam.apply_setting(['exposure'], 1)
|
||||||
|
print(cam.camera_current_settings['exposure']['value'])
|
||||||
|
elif (k%256 == 90):
|
||||||
|
print(_("Dec. exposure"))
|
||||||
|
cam.apply_setting(['exposure'], -1)
|
||||||
|
print(cam.camera_current_settings['exposure']['value'])
|
||||||
# SPACE or numpad 0 pressed
|
# SPACE or numpad 0 pressed
|
||||||
elif (k%256 == 32) or (k%256 == 48) or (k%256 == 176):
|
elif (k%256 == 32) or (k%256 == 48) or (k%256 == 176):
|
||||||
print(_("Capture frame"))
|
print(_("Capture frame"))
|
||||||
|
|
Loading…
Reference in New Issue