stphot/acquire.py

136 lines
4.2 KiB
Python
Executable File

#!/usr/bin/env python3
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
if __name__ == "__main__":
# Parse arguments
parser = argparse.ArgumentParser(
description="Capture images with an ASI CMOS camera")
parser.add_argument("-s", "--settings", help="JSON file with settings", default=None)
parser.add_argument("-p", "--path", help="Output path", default=None)
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)
# 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 = asi.get_num_cameras()
if ncam == 0:
print("No ZWO ASI cameras found")
sys.exit(1)
# Decode settings
texp_us = 1000 * int(settings["exposure"])
gain = int(settings["gain"])
# Initialize camera 0
camera = asi.Camera(0)
camera_info = camera.get_camera_property()
# 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_AUTO_MAX_EXP, texp_us_max // 1000)
camera.set_control_value(asi.ASI_GAIN, gain, auto=False)
#camera.set_control_value(asi.ASI_AUTO_MAX_GAIN, gain_max)
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"]))
# Start capture
camera.start_video_capture()
# 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
while True:
# Capture frame
t0 = time.time()
img = camera.capture_video_frame()
# Get settings
camera_settings = camera.get_control_values()
# Stability test
if texp_us == camera_settings["Exposure"] and gain == camera_settings["Gain"]:
stable = True
# 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), img, nfd, texp, gain, temp)
# 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
if stable:
cv2.imwrite(os.path.join(path, "%s.jpg" % nfd), rgb_img)
# Stop capture
camera.stop_video_capture()
# Close file
fstat.close()