#!/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 . 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()