diff --git a/README.md b/README.md index b478e02..75aeff8 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ Features to be implemented. #### High priority * ~~Use sunset/sunrise times for starting/stopping data acquisition.~~ -* Manual and automatic astrometric calibration. +* ~~Automatic astrometric calibration.~~ * Recognize unidentified satellite/meteor tracks using [3D Hough transform](http://www.ipol.im/pub/art/2017/208/). #### Medium priority @@ -43,6 +43,6 @@ Features to be implemented. * Create start up script in `/etc/init.d`. Call capture script as user with `su -c "capture_1.sh"`. ## License -© 2018 Cees Bassa +© 2018-2019 Cees Bassa Licensed under the [GPLv3](LICENSE). diff --git a/acquire.py b/acquire.py index 8fdc73e..1571b94 100755 --- a/acquire.py +++ b/acquire.py @@ -15,35 +15,73 @@ from stvid.utils import get_sunset_and_sunrise import logging import configparser import argparse +import zwoasi as asi # Capture images -def capture(buf, z1, t1, z2, t2, device, nx, ny, nz, tend, live): +def capture(buf, z1, t1, z2, t2, nx, ny, nz, tend, live, type): # Array flag first = True + # Initialize device + if camera_type == 'asi': + asi.init(os.getenv("ZWO_ASI_LIB")) + + camera = asi.Camera(0) + camera_info = camera.get_camera_property() + logging.info('ASI Camera info: %s' % camera_info) + + camera.set_control_value(asi.ASI_BANDWIDTHOVERLOAD, + camera.get_controls()['BandWidth']['MinValue']) + camera.disable_dark_subtract() + + camera.set_control_value(asi.ASI_GAIN, 300) + camera.set_control_value(asi.ASI_EXPOSURE, 100000) + camera.set_control_value(asi.ASI_WB_B, 99) + camera.set_control_value(asi.ASI_WB_R, 75) + camera.set_control_value(asi.ASI_GAMMA, 50) + camera.set_control_value(asi.ASI_BRIGHTNESS, 50) + camera.set_control_value(asi.ASI_FLIP, 0) + camera.set_roi(bins=2) + camera.start_video_capture() + camera.set_image_type(asi.ASI_IMG_Y8) + + else: + device = cv2.VideoCapture(devid) + + # Set properties + device.set(3, nx) + device.set(4, ny) + # Loop until reaching end time while float(time.time()) < tend: # Get frames for i in range(nz): # Get frame - ret, frame = device.read() + if type == 'asi': + frame = camera.capture_video_frame() + res = True + else: + res, frame = device.read() # Skip lost frames - if ret is True: + if res is True: # Store time t = float(time.time()) - # Convert image to grayscale - gray = np.asarray(cv2.cvtColor( - frame, cv2.COLOR_BGR2GRAY)).astype(np.uint8) + if type != 'asi': + # Convert image to grayscale + gray = np.asarray(cv2.cvtColor( + frame, cv2.COLOR_BGR2GRAY)).astype(np.uint8) - # Store buffer - z = gray + # Store buffer + z = gray + else: + z = frame # Display Frame if live is True: - cv2.imshow("Capture", gray) + cv2.imshow("Capture", z) cv2.waitKey(1) # Store results @@ -65,6 +103,11 @@ def capture(buf, z1, t1, z2, t2, device, nx, ny, nz, tend, live): logging.info("Exiting capture") + if type == 'asi': + camera.stop_video_capture() + else: + device.release() + def compress(buf, z1, t1, z2, t2, nx, ny, nz, tend, path): # Flag to keep track of processed buffer @@ -191,6 +234,9 @@ if __name__ == '__main__': # Get device id devid = cfg.getint('Camera', 'device_id') + # Get camera type + camera_type = cfg.get('Camera', 'camera_type') + # Current time tnow = Time.now() @@ -249,13 +295,6 @@ if __name__ == '__main__': ny = cfg.getint('Camera', 'camera_y') nz = cfg.getint('Camera', 'camera_frames') - # Initialize device - device = cv2.VideoCapture(devid) - - # Set properties - device.set(3, nx) - device.set(4, ny) - # Initialize arrays z1base = multiprocessing.Array(ctypes.c_uint8, nx*ny*nz) z1 = np.ctypeslib.as_array(z1base.get_obj()).reshape(nz, ny, nx) @@ -269,8 +308,8 @@ if __name__ == '__main__': # Set processes pcapture = multiprocessing.Process(target=capture, - args=(buf, z1, t1, z2, t2, device, - nx, ny, nz, tend.unix, live)) + args=(buf, z1, t1, z2, t2, + nx, ny, nz, tend.unix, live, camera_type)) pcompress = multiprocessing.Process(target=compress, args=(buf, z1, t1, z2, t2, nx, ny, nz, tend.unix, path)) @@ -290,4 +329,3 @@ if __name__ == '__main__': # Release device if live is True: cv2.destroyAllWindows() - device.release() diff --git a/calibrate.py b/calibrate.py index 6b09245..3f0b511 100755 --- a/calibrate.py +++ b/calibrate.py @@ -37,10 +37,12 @@ if __name__ == '__main__': print("Found " + file_for_astrometry + " for astrometric solving.") sex_config = cfg.get('Astrometry', 'sex_config') + low_app = cfg.get('Astrometry', 'low_app') + high_app = cfg.get('Astrometry', 'high_app') # Format command - command = "solve-field -O -y -u app -L 37 -H 40 --use-sextractor " + \ - "--sextractor-config %s --downsample 2 --x-column X_IMAGE " % sex_config + \ + command = "solve-field -O -y -u app -L %s -H %s --downsample 2 " % (low_app, high_app) + \ + "--use-sextractor --sextractor-config %s --x-column X_IMAGE " % sex_config + \ "--y-column Y_IMAGE --sort-column MAG_AUTO --sort-ascending " + \ "%s" % file_for_astrometry diff --git a/configuration.ini-dist b/configuration.ini-dist index 67f8a95..6b6acf8 100644 --- a/configuration.ini-dist +++ b/configuration.ini-dist @@ -20,10 +20,13 @@ alt_sunset = -6.0 # Solar altitude at sunset alt_sunrise = -6.0 # Solar altitude at sunrise [Camera] +camera_type = watec # or asi for ZWO ASI Cameras device_id = 0 camera_x = 720 # Camera horizontal pixel count camera_y = 576 # Camera vertical pixel count -camera_frames = 250 # Camera frames for each image (25fps*10sec=250) +camera_frames = 250 # Camera frames for each image (e.g 25fps*10sec=250) [Astrometry] sex_config = /path/to/solve.sex +low_app = 18 # Arcsec per pixel low scale +high_app = 20 # Arcsec per pixel high scale diff --git a/requirements.txt b/requirements.txt index 67ef075..bdad575 100644 --- a/requirements.txt +++ b/requirements.txt @@ -12,3 +12,4 @@ pytz==2018.4 six==1.11.0 spacetrack==0.13.0 termcolor +zwoasi