DSLR capture, initialize working
This commit is contained in:
parent
c302f17087
commit
8bc52eae04
|
@ -1,6 +1,6 @@
|
||||||
[DEFAULT]
|
[DEFAULT]
|
||||||
# Camera type - can be : showmewebcam, picam, webcam, dslr
|
# Camera type - can be : showmewebcam, picam, webcam, dslr
|
||||||
cam_type = 'picam'
|
cam_type = 'dslr'
|
||||||
use_date_for_folder = false
|
use_date_for_folder = false
|
||||||
file_extension = 'jpg'
|
file_extension = 'jpg'
|
||||||
jpg_quality = 88
|
jpg_quality = 88
|
||||||
|
|
|
@ -0,0 +1,148 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
# python-gphoto2 - Python interface to libgphoto2
|
||||||
|
# http://github.com/jim-easterbrook/python-gphoto2
|
||||||
|
# Copyright (C) 2015-22 Jim Easterbrook jim@jim-easterbrook.me.uk
|
||||||
|
#
|
||||||
|
# This file is part of python-gphoto2.
|
||||||
|
#
|
||||||
|
# python-gphoto2 is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License as
|
||||||
|
# published by the Free Software Foundation, either version 3 of the
|
||||||
|
# License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# python-gphoto2 is distributed in the hope that it will be useful, but
|
||||||
|
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
# Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public
|
||||||
|
# License along with python-gphoto2. If not, see
|
||||||
|
# <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import logging
|
||||||
|
import locale
|
||||||
|
import os
|
||||||
|
# ~ import subprocess
|
||||||
|
import sys
|
||||||
|
|
||||||
|
import gphoto2 as gp
|
||||||
|
|
||||||
|
camera_current_settings = {
|
||||||
|
'capturemode' : 3, # use IR remote
|
||||||
|
'imagesize' : 2, # use size S (1936x1296)
|
||||||
|
'whitebalance' : 1, # Natural light
|
||||||
|
'capturetarget' : 0, # Internal memory
|
||||||
|
'nocfcardrelease' : 0, # Allow capture without sd card
|
||||||
|
'recordingmedia' : 1, # Write to RAM
|
||||||
|
}
|
||||||
|
|
||||||
|
def initialize_camera():
|
||||||
|
camera = gp.check_result(gp.gp_camera_new())
|
||||||
|
try:
|
||||||
|
gp.check_result(gp.gp_camera_init(camera))
|
||||||
|
# get configuration tree
|
||||||
|
current_camera_config = gp.check_result(gp.gp_camera_get_config(camera))
|
||||||
|
except:
|
||||||
|
camera.exit()
|
||||||
|
camera = None
|
||||||
|
current_camera_config = None
|
||||||
|
return camera, current_camera_config
|
||||||
|
|
||||||
|
|
||||||
|
def apply_gphoto_setting(config, setting, new_value):
|
||||||
|
# find the $setting config item
|
||||||
|
try:
|
||||||
|
cur_setting = gp.check_result(gp.gp_widget_get_child_by_name(config, setting))
|
||||||
|
# find corresponding choice
|
||||||
|
cur_setting_choice = gp.check_result(gp.gp_widget_get_choice(cur_setting, new_value))
|
||||||
|
# set config value
|
||||||
|
gp.check_result(gp.gp_widget_set_value(cur_setting, cur_setting_choice))
|
||||||
|
except:
|
||||||
|
print("Configuration error while setting {} to {}".format(setting, new_value))
|
||||||
|
|
||||||
|
|
||||||
|
def apply_dslr_settings(camera_settings):
|
||||||
|
camera, config = initialize_camera()
|
||||||
|
# iterate over the settings dictionary
|
||||||
|
for setting in camera_settings:
|
||||||
|
print(setting)
|
||||||
|
print(camera_settings[setting])
|
||||||
|
apply_gphoto_setting(config, setting, camera_settings[setting])
|
||||||
|
# validate config
|
||||||
|
status = gp.check_result(gp.gp_camera_set_config(camera, config))
|
||||||
|
# close camera
|
||||||
|
camera.exit()
|
||||||
|
return status
|
||||||
|
|
||||||
|
|
||||||
|
def check_status_value(config, value, optimal_value=None):
|
||||||
|
cur_check = gp.check_result(gp.gp_widget_get_child_by_name(config, value))
|
||||||
|
cur_check_value = gp.check_result(gp.gp_widget_get_value(cur_check))
|
||||||
|
if optimal_value is not None:
|
||||||
|
cur_check_choice = gp.check_result(gp.gp_widget_get_choice(cur_check, optimal_value[value]))
|
||||||
|
return [cur_check_value, cur_check_choice]
|
||||||
|
else:
|
||||||
|
return cur_check_value
|
||||||
|
|
||||||
|
|
||||||
|
# ~ def check_status(camera, config):
|
||||||
|
# ~ for value in camera_status:
|
||||||
|
# ~ cur_check_value, cur_check_choice = check_status_value(config, value, camera_status)
|
||||||
|
# ~ if cur_check_value == cur_check_choice:
|
||||||
|
# ~ return True
|
||||||
|
# ~ else:
|
||||||
|
# ~ # Some values are not optimal
|
||||||
|
# ~ return False
|
||||||
|
|
||||||
|
|
||||||
|
def find_file_ext(gp_name:str, full_path:str):
|
||||||
|
# extract dir path
|
||||||
|
dirname = os.path.dirname(full_path)
|
||||||
|
# extract filename from path
|
||||||
|
new_name = os.path.basename(full_path)
|
||||||
|
# if the path does'nt contain file name, return camera's FS filename
|
||||||
|
if not full_path.endswith(('.jpg', '.JPG', '.raw')):
|
||||||
|
return gp_name
|
||||||
|
suffix = gp_name.split('.')[-1]
|
||||||
|
prefix = new_name.split('.')[:-1]
|
||||||
|
prefix.insert(len(prefix), suffix)
|
||||||
|
print(suffix)
|
||||||
|
print(prefix)
|
||||||
|
return os.path.join(dirname, '.'.join(prefix))
|
||||||
|
|
||||||
|
|
||||||
|
def capture_and_download(target:str='/tmp'):
|
||||||
|
camera, current_camera_config = initialize_camera()
|
||||||
|
# Check battery level
|
||||||
|
battery_level = int(check_status_value(current_camera_config, 'batterylevel')[:-1])
|
||||||
|
if battery_level < 10:
|
||||||
|
print("Battery level is too low, shutter disabled.")
|
||||||
|
return False
|
||||||
|
file_path = camera.capture(gp.GP_CAPTURE_IMAGE)
|
||||||
|
print('Camera file path: {0}/{1}'.format(file_path.folder, file_path.name))
|
||||||
|
print(target)
|
||||||
|
target = find_file_ext(file_path.name, target)
|
||||||
|
print('Copying image to', target)
|
||||||
|
try:
|
||||||
|
camera_file = camera.file_get(
|
||||||
|
file_path.folder, file_path.name, gp.GP_FILE_TYPE_NORMAL)
|
||||||
|
except:
|
||||||
|
print("Camera error. Check Battery and try restarting the camera.")
|
||||||
|
return False
|
||||||
|
try:
|
||||||
|
camera_file.save(target)
|
||||||
|
except:
|
||||||
|
print('File access error.')
|
||||||
|
return False
|
||||||
|
camera.exit()
|
||||||
|
return True
|
||||||
|
|
||||||
|
def main():
|
||||||
|
apply_dslr_settings(camera_current_settings)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
logging.basicConfig(
|
||||||
|
format='%(levelname)s: %(name)s: %(message)s', level=logging.ERROR)
|
||||||
|
callback_obj = gp.check_result(gp.use_python_logging())
|
||||||
|
sys.exit(main())
|
|
@ -16,7 +16,8 @@ import numpy as np
|
||||||
import serialutils
|
import serialutils
|
||||||
|
|
||||||
# DSLR
|
# DSLR
|
||||||
import gphoto2 as gp
|
# ~ import gphoto2 as gp
|
||||||
|
import dslr_helper
|
||||||
|
|
||||||
# Run from SSH
|
# Run from SSH
|
||||||
if not os.getenv('DISPLAY'):
|
if not os.getenv('DISPLAY'):
|
||||||
|
@ -98,53 +99,18 @@ elif project_settings['cam_type'] == "picam":
|
||||||
'anti_flicker': dict(min=0, max=2, default=1, value=1),
|
'anti_flicker': dict(min=0, max=2, default=1, value=1),
|
||||||
}
|
}
|
||||||
elif project_settings['cam_type'] == "dslr":
|
elif project_settings['cam_type'] == "dslr":
|
||||||
camera_current_settings = {}
|
# Sane values for Nikon D40X
|
||||||
|
camera_current_settings = {
|
||||||
|
'capturemode' : 3, # use IR remote
|
||||||
|
'imagesize' : 2, # use size S (1936x1296)
|
||||||
|
'whitebalance' : 1, # Natural light
|
||||||
|
'capturetarget' : 0, # Internal memory
|
||||||
|
'nocfcardrelease' : 0, # Allow capture without sd card
|
||||||
|
'recordingmedia' : 1, # Write to RAM
|
||||||
|
}
|
||||||
else:
|
else:
|
||||||
camera_current_settings = {}
|
camera_current_settings = {}
|
||||||
|
|
||||||
|
|
||||||
def apply_gphoto_setting(config, setting, new_value):
|
|
||||||
cur_setting = gp.check_result(gp.gp_widget_get_child_by_name(config, setting))
|
|
||||||
# find corresponding choice
|
|
||||||
cur_setting_choice = gp.check_result(gp.gp_widget_get_choice(cur_setting, new_value))
|
|
||||||
# set config value
|
|
||||||
gp.check_result(gp.gp_widget_set_value(cur_setting, cur_setting_choice))
|
|
||||||
|
|
||||||
|
|
||||||
def apply_dslr_settings(camera, config):
|
|
||||||
# iterate over the settings dictionary
|
|
||||||
for setting in camera_settings:
|
|
||||||
# find the capture mode config item
|
|
||||||
# ~ cur_setting = gp.check_result(gp.gp_widget_get_child_by_name(config, setting))
|
|
||||||
# ~ # find corresponding choice
|
|
||||||
# ~ cur_setting_choice = gp.check_result(gp.gp_widget_get_choice(cur_setting, camera_settings[setting]))
|
|
||||||
# ~ # set config value
|
|
||||||
# ~ gp.check_result(gp.gp_widget_set_value(cur_setting, cur_setting_choice))
|
|
||||||
apply_gphoto_setting(config, setting, camera_settings[setting])
|
|
||||||
# validate config
|
|
||||||
gp.check_result(gp.gp_camera_set_config(camera, config))
|
|
||||||
|
|
||||||
|
|
||||||
def check_status_value( config, value, optimal_value=None):
|
|
||||||
cur_check = gp.check_result(gp.gp_widget_get_child_by_name(config, value))
|
|
||||||
cur_check_value = gp.check_result(gp.gp_widget_get_value(cur_check))
|
|
||||||
if optimal_value is not None:
|
|
||||||
cur_check_choice = gp.check_result(gp.gp_widget_get_choice(cur_check, optimal_value[value]))
|
|
||||||
return [cur_check_value, cur_check_choice]
|
|
||||||
else:
|
|
||||||
return cur_check_value
|
|
||||||
|
|
||||||
|
|
||||||
def check_status(camera, config):
|
|
||||||
for value in camera_status:
|
|
||||||
cur_check_value, cur_check_choice = check_status_value(config, value, camera_status)
|
|
||||||
if cur_check_value == cur_check_choice:
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
# Some values are not optimal
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def apply_cam_setting(cam_settings:dict, to_set:list=None):
|
def apply_cam_setting(cam_settings:dict, to_set:list=None):
|
||||||
# TODO: Refactor so that we can call with whatever camera type and setting, and have the work of determining how to apply it done here
|
# TODO: Refactor so that we can call with whatever camera type and setting, and have the work of determining how to apply it done here
|
||||||
# This version should probably be kept and renamed construct_v4l2_cmd()
|
# This version should probably be kept and renamed construct_v4l2_cmd()
|
||||||
|
@ -556,16 +522,8 @@ def main(args):
|
||||||
})
|
})
|
||||||
# ~ cam.stop()
|
# ~ cam.stop()
|
||||||
elif project_settings['cam_type'] == "dslr":
|
elif project_settings['cam_type'] == "dslr":
|
||||||
camera = gp.check_result(gp.gp_camera_new())
|
print(_("Applying DSLR settings..."))
|
||||||
try:
|
dslr_helper.apply_dslr_settings(camera_current_settings)
|
||||||
gp.check_result(gp.gp_camera_init(camera))
|
|
||||||
# get configuration tree
|
|
||||||
current_camera_config = gp.check_result(gp.gp_camera_get_config(camera))
|
|
||||||
apply_dslr_settings(camera, current_camera_config)
|
|
||||||
if check_status(camera, current_camera_config) is False:
|
|
||||||
print(_("Warning: Some settings are not set to the recommended value!"))
|
|
||||||
except:
|
|
||||||
camera = False
|
|
||||||
else:
|
else:
|
||||||
print(_("No camera type was defined in config.toml"))
|
print(_("No camera type was defined in config.toml"))
|
||||||
|
|
||||||
|
@ -576,6 +534,9 @@ def main(args):
|
||||||
camera_current_settings = apply_cam_setting(camera_current_settings)
|
camera_current_settings = apply_cam_setting(camera_current_settings)
|
||||||
time.sleep(.5)
|
time.sleep(.5)
|
||||||
|
|
||||||
|
if project_settings['cam_type'] == "dslr":
|
||||||
|
onionskin = False
|
||||||
|
|
||||||
loop_delta = 0
|
loop_delta = 0
|
||||||
while True:
|
while True:
|
||||||
start = timer()
|
start = timer()
|
||||||
|
@ -774,18 +735,14 @@ def main(args):
|
||||||
img_name = return_next_frame_number(get_last_frame(savepath))
|
img_name = return_next_frame_number(get_last_frame(savepath))
|
||||||
img_path = os.path.join(savepath, img_name)
|
img_path = os.path.join(savepath, img_name)
|
||||||
if project_settings['cam_type'] == 'dslr':
|
if project_settings['cam_type'] == 'dslr':
|
||||||
# Get file from DSLR camera
|
# Get file from DSLR
|
||||||
new_frame_path = camera.capture(gp.GP_CAPTURE_IMAGE)
|
capture_ok = dslr_helper.capture_and_download(img_path)
|
||||||
new_frame = camera.file_get(
|
|
||||||
new_frame_path.folder, new_frame_path.name, gp.GP_FILE_TYPE_NORMAL)
|
|
||||||
print(_("Saving {}{}").format(new_frame_path.folder, new_frame_path.name))
|
|
||||||
new_frame.save(img_path)
|
|
||||||
else:
|
else:
|
||||||
# Cam is either webcam, showmewebcam or picam
|
# Cam is either webcam, showmewebcam or picam
|
||||||
if project_settings['file_extension'] == 'jpg':
|
if project_settings['file_extension'] == 'jpg':
|
||||||
cv2.imwrite(img_path, og_frame, [int(cv2.IMWRITE_JPEG_QUALITY), project_settings['jpg_quality']])
|
capture_ok = cv2.imwrite(img_path, og_frame, [int(cv2.IMWRITE_JPEG_QUALITY), project_settings['jpg_quality']])
|
||||||
else:
|
else:
|
||||||
cv2.imwrite(img_path, og_frame)
|
capture_ok = cv2.imwrite(img_path, og_frame)
|
||||||
print(_("File {} written.").format(img_path))
|
print(_("File {} written.").format(img_path))
|
||||||
|
|
||||||
# Special case when we've no frame yet
|
# Special case when we've no frame yet
|
||||||
|
@ -793,7 +750,13 @@ def main(args):
|
||||||
img_list[index] = img_name
|
img_list[index] = img_name
|
||||||
else:
|
else:
|
||||||
index += 1
|
index += 1
|
||||||
frame = get_onionskin_frame(savepath, index)
|
# Display a message if capture was not successfull
|
||||||
|
if not capture_ok:
|
||||||
|
frame = generate_text_image(_("Error during capture."),
|
||||||
|
project_settings['screen_w'], project_settings['screen_h']
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
frame = get_onionskin_frame(savepath, index)
|
||||||
# Quit app
|
# Quit app
|
||||||
elif k%256 == 27:
|
elif k%256 == 27:
|
||||||
# ESC pressed
|
# ESC pressed
|
||||||
|
@ -830,8 +793,10 @@ def main(args):
|
||||||
ffmpeg_process.terminate()
|
ffmpeg_process.terminate()
|
||||||
if project_settings['cam_type'] == "showmewebcam":
|
if project_settings['cam_type'] == "showmewebcam":
|
||||||
cam.release()
|
cam.release()
|
||||||
else:
|
elif project_settings['cam_type'] == "picam":
|
||||||
cam.close()
|
cam.close()
|
||||||
|
elif project_settings['cam_type'] == "dslr":
|
||||||
|
pass
|
||||||
cv2.destroyAllWindows()
|
cv2.destroyAllWindows()
|
||||||
|
|
||||||
cv2.namedWindow("StopiCV", cv2.WINDOW_GUI_NORMAL)
|
cv2.namedWindow("StopiCV", cv2.WINDOW_GUI_NORMAL)
|
||||||
|
|
|
@ -3,3 +3,4 @@ numpy
|
||||||
pyserial
|
pyserial
|
||||||
pillow
|
pillow
|
||||||
opencv-python
|
opencv-python
|
||||||
|
gphoto2
|
||||||
|
|
Loading…
Reference in New Issue