231 lines
7.7 KiB
Python
Executable File
231 lines
7.7 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
# gacquire - gphoto3 interface to stphot.
|
|
#
|
|
# 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 program is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program 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 General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
import logging
|
|
import locale
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
|
|
import gphoto2 as gp
|
|
|
|
import argparse
|
|
import os
|
|
import sys
|
|
import json
|
|
import time
|
|
import cv2
|
|
import zwoasi as asi
|
|
import numpy as np
|
|
from stphot.io import write_fits_file
|
|
|
|
def gcapture():
|
|
locale.setlocale(locale.LC_ALL, '')
|
|
logging.basicConfig(
|
|
format='%(levelname)s: %(name)s: %(message)s', level=logging.WARNING)
|
|
callback_obj = gp.check_result(gp.use_python_logging())
|
|
camera = gp.Camera()
|
|
camera.init()
|
|
print('Capturing image')
|
|
file_path = camera.capture(gp.GP_CAPTURE_IMAGE)
|
|
print('Camera file path: {0}/{1}'.format(file_path.folder, file_path.name))
|
|
target = os.path.join('/tmp', file_path.name)
|
|
print('Copying image to', target)
|
|
camera_file = camera.file_get(
|
|
file_path.folder, file_path.name, gp.GP_FILE_TYPE_NORMAL)
|
|
camera_file.save(target)
|
|
camera.exit()
|
|
return 0
|
|
|
|
if __name__ == "__main__":
|
|
# Parse arguments
|
|
parser = argparse.ArgumentParser(
|
|
description="Capture images with a DSLR gphoto2 camera")
|
|
parser.add_argument("-s", "--settings", help="JSON file with settings", default="settings.json")
|
|
parser.add_argument("-p", "--path", help="Output path", default=None)
|
|
# parser.add_argument("-t", "--exptime", help="Exposure time [seconds]", type=float, default=None)
|
|
# parser.add_argument("-g", "--gain", help="Gain", type=int, default=None)
|
|
# parser.add_argument("-b", "--bin", help="Binning factor", type=int, default=None)
|
|
parser.add_argument("-n", "--number", help="Number of images to acquire", type=int, default=None)
|
|
# parser.add_argument("-F", "--format", help="Data format [RAW8, RAW16, RGB24]", default=None)
|
|
parser.add_argument("-l", "--live", action="store_true", help="Display live image while capturing")
|
|
parser.add_argument("-w", "--wait", help="Wait time between exposures [seconds]", type=float, default=0)
|
|
parser.add_argument("-d", "--dslr", help="DSLR with gphoto2", type=bool, default=False)
|
|
args = parser.parse_args()
|
|
|
|
# Check arguments
|
|
if args.settings == None or args.path == None:
|
|
parser.print_help()
|
|
sys.exit()
|
|
|
|
# Read settings
|
|
try:
|
|
with open(args.settings, "r") as fp:
|
|
settings = json.load(fp)
|
|
except Exception as e:
|
|
print(e)
|
|
sys.exit(1)
|
|
|
|
# Override settings
|
|
# if args.exptime is not None:
|
|
# settings["exposure"] = f"{int(float(args.exptime) * 1000)}"
|
|
# if args.gain is not None:
|
|
# settings["gain"] = f"{args.gain}"
|
|
# if args.bin is not None:
|
|
# settings["bin"] = f"{args.bin}"
|
|
# if args.format is not None:
|
|
# if args.format == "RAW8":
|
|
# settings["type"] = f"{asi.ASI_IMG_RAW8}"
|
|
# elif args.format == "RAW16":
|
|
# settings["type"] = f"{asi.ASI_IMG_RAW16}"
|
|
# elif args.format == "RGB24":
|
|
# settings["type"] = f"{asi.ASI_IMG_RGB24}"
|
|
|
|
# Number of images
|
|
if args.number is not None:
|
|
nimg = args.number
|
|
else:
|
|
nimg = 6
|
|
|
|
|
|
# Check path
|
|
path = os.path.abspath(args.path)
|
|
if not os.path.exists(path):
|
|
os.makedirs(path)
|
|
|
|
# Intialize SDK library
|
|
# try:
|
|
# asi.init(os.getenv("ZWO_ASI_LIB"))
|
|
# except Exception as e:
|
|
# print(e)
|
|
# sys.exit(1)
|
|
|
|
# Find cameras
|
|
ncam = len(gp.Camera.autodetect())
|
|
if ncam == 0:
|
|
print("No gphoto2 cameras found")
|
|
sys.exit(1)
|
|
|
|
# Decode settings
|
|
# texp_us = 1000 * int(settings["exposure"])
|
|
# gain = int(settings["gain"])
|
|
|
|
# Initialize camera 0
|
|
camera = gp.Camera()
|
|
camera.init()
|
|
#camera_info = camera.get_camera_property()
|
|
camera_info = camera.get_summary()
|
|
print(camera_info)
|
|
|
|
# Set control values
|
|
# camera.set_control_value(asi.ASI_BANDWIDTHOVERLOAD, int(settings["usb"]))
|
|
# camera.set_control_value(asi.ASI_EXPOSURE, texp_us, auto=False)
|
|
# camera.set_control_value(asi.ASI_GAIN, gain, auto=False)
|
|
# camera.set_control_value(asi.ASI_WB_B, int(settings["wbb"]))
|
|
# camera.set_control_value(asi.ASI_WB_R, int(settings["wbr"]))
|
|
# camera.set_control_value(asi.ASI_GAMMA, int(settings["gamma"]))
|
|
# camera.set_control_value(asi.ASI_BRIGHTNESS, int(settings["brightness"]))
|
|
# camera.set_control_value(asi.ASI_FLIP, int(settings["flip"]))
|
|
# camera.set_control_value(asi.ASI_AUTO_MAX_BRIGHTNESS, 80)
|
|
# camera.disable_dark_subtract()
|
|
# camera.set_roi(bins=int(settings["bin"]))
|
|
|
|
# Force any single exposure to be halted
|
|
#try:
|
|
# camera.stop_video_capture()
|
|
# camera.stop_exposure()
|
|
#except (KeyboardInterrupt, SystemExit):
|
|
# raise
|
|
#except:
|
|
# pass
|
|
|
|
# Set image format
|
|
# if int(settings["type"]) == asi.ASI_IMG_RAW8:
|
|
# camera.set_image_type(asi.ASI_IMG_RAW8)
|
|
# elif int(settings["type"]) == asi.ASI_IMG_RGB24:
|
|
# camera.set_image_type(asi.ASI_IMG_RGB24)
|
|
# elif int(settings["type"]) == asi.ASI_IMG_RAW16:
|
|
# camera.set_image_type(asi.ASI_IMG_RAW16)
|
|
# else:
|
|
# camera.set_image_type(asi.ASI_IMG_RAW8)
|
|
|
|
# Forever loop
|
|
for i in range(nimg):
|
|
print(f"Capturing image {i} of {nimg}")
|
|
# Capture frame
|
|
t0 = time.time()
|
|
# XXX
|
|
img = camera.capture(gp.GP_CAPTURE_IMAGE)
|
|
exit()
|
|
|
|
# Display Frame
|
|
if args.live is True:
|
|
cv2.imshow("Capture", img)
|
|
cv2.waitKey(1)
|
|
|
|
# Get settings
|
|
camera_settings = camera.get_control_values()
|
|
|
|
# Extract settings
|
|
# texp_us = camera_settings["Exposure"]
|
|
# texp = float(texp_us) / 1000000
|
|
# gain = camera_settings["Gain"]
|
|
# temp = float(camera_settings["Temperature"]) / 10
|
|
|
|
# Format start time
|
|
nfd = "%s.%03d" % (time.strftime("%Y-%m-%dT%T",
|
|
time.gmtime(t0)), int((t0 - np.floor(t0)) * 1000))
|
|
|
|
# print(nfd, texp, gain, temp)
|
|
|
|
# Store FITS file
|
|
# write_fits_file(os.path.join(path, "%s.fits" % nfd), np.flipud(img), nfd, texp, gain, temp)
|
|
write_fits_file(os.path.join(path, "%s.fits" % nfd), np.flipud(img), nfd)
|
|
|
|
#print(settings["type"], asi.ASI_IMG_RAW8, asi.ASI_IMG_RGB24, asi.ASI_IMG_RAW16)
|
|
|
|
# Get RGB image
|
|
if int(settings["type"]) == asi.ASI_IMG_RAW8:
|
|
ny, nx = img.shape
|
|
rgb_img = cv2.cvtColor(img, cv2.COLOR_BAYER_BG2BGR)
|
|
elif int(settings["type"]) == asi.ASI_IMG_RGB24:
|
|
ny, nx, nc = img.shape
|
|
rgb_img = img
|
|
elif int(settings["type"]) == asi.ASI_IMG_RAW16:
|
|
ny, nx = img.shape
|
|
img_8bit = np.clip((img/256).astype("uint8"), 0, 255)
|
|
rgb_img = cv2.cvtColor(img_8bit, cv2.COLOR_BAYER_BG2BGR)
|
|
|
|
# Store image
|
|
cv2.imwrite(os.path.join(path, "%s.jpg" % nfd), rgb_img)
|
|
|
|
# Wait
|
|
if args.wait > 0:
|
|
time.sleep(args.wait)
|
|
|
|
# Stop capture
|
|
camera.stop_video_capture()
|
|
|
|
# Release device
|
|
if args.live is True:
|
|
cv2.destroyAllWindows()
|
|
|