Merge pull request #18 from ppapadeas/asi-capture

Integrate ASI Cameras capture code in acquire.py
pull/19/head
Cees Bassa 2019-07-12 16:53:33 +02:00 committed by GitHub
commit 76d7867454
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 68 additions and 24 deletions

View File

@ -21,7 +21,7 @@ Features to be implemented.
#### High priority #### High priority
* ~~Use sunset/sunrise times for starting/stopping data acquisition.~~ * ~~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/). * Recognize unidentified satellite/meteor tracks using [3D Hough transform](http://www.ipol.im/pub/art/2017/208/).
#### Medium priority #### 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 <username> -c "capture_1.sh"`. * Create start up script in `/etc/init.d`. Call capture script as user with `su <username> -c "capture_1.sh"`.
## License ## License
&copy; 2018 Cees Bassa &copy; 2018-2019 Cees Bassa
Licensed under the [GPLv3](LICENSE). Licensed under the [GPLv3](LICENSE).

View File

@ -15,35 +15,73 @@ from stvid.utils import get_sunset_and_sunrise
import logging import logging
import configparser import configparser
import argparse import argparse
import zwoasi as asi
# Capture images # 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 # Array flag
first = True 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 # Loop until reaching end time
while float(time.time()) < tend: while float(time.time()) < tend:
# Get frames # Get frames
for i in range(nz): for i in range(nz):
# Get frame # Get frame
ret, frame = device.read() if type == 'asi':
frame = camera.capture_video_frame()
res = True
else:
res, frame = device.read()
# Skip lost frames # Skip lost frames
if ret is True: if res is True:
# Store time # Store time
t = float(time.time()) t = float(time.time())
# Convert image to grayscale if type != 'asi':
gray = np.asarray(cv2.cvtColor( # Convert image to grayscale
frame, cv2.COLOR_BGR2GRAY)).astype(np.uint8) gray = np.asarray(cv2.cvtColor(
frame, cv2.COLOR_BGR2GRAY)).astype(np.uint8)
# Store buffer # Store buffer
z = gray z = gray
else:
z = frame
# Display Frame # Display Frame
if live is True: if live is True:
cv2.imshow("Capture", gray) cv2.imshow("Capture", z)
cv2.waitKey(1) cv2.waitKey(1)
# Store results # Store results
@ -65,6 +103,11 @@ def capture(buf, z1, t1, z2, t2, device, nx, ny, nz, tend, live):
logging.info("Exiting capture") 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): def compress(buf, z1, t1, z2, t2, nx, ny, nz, tend, path):
# Flag to keep track of processed buffer # Flag to keep track of processed buffer
@ -191,6 +234,9 @@ if __name__ == '__main__':
# Get device id # Get device id
devid = cfg.getint('Camera', 'device_id') devid = cfg.getint('Camera', 'device_id')
# Get camera type
camera_type = cfg.get('Camera', 'camera_type')
# Current time # Current time
tnow = Time.now() tnow = Time.now()
@ -249,13 +295,6 @@ if __name__ == '__main__':
ny = cfg.getint('Camera', 'camera_y') ny = cfg.getint('Camera', 'camera_y')
nz = cfg.getint('Camera', 'camera_frames') nz = cfg.getint('Camera', 'camera_frames')
# Initialize device
device = cv2.VideoCapture(devid)
# Set properties
device.set(3, nx)
device.set(4, ny)
# Initialize arrays # Initialize arrays
z1base = multiprocessing.Array(ctypes.c_uint8, nx*ny*nz) z1base = multiprocessing.Array(ctypes.c_uint8, nx*ny*nz)
z1 = np.ctypeslib.as_array(z1base.get_obj()).reshape(nz, ny, nx) z1 = np.ctypeslib.as_array(z1base.get_obj()).reshape(nz, ny, nx)
@ -269,8 +308,8 @@ if __name__ == '__main__':
# Set processes # Set processes
pcapture = multiprocessing.Process(target=capture, pcapture = multiprocessing.Process(target=capture,
args=(buf, z1, t1, z2, t2, device, args=(buf, z1, t1, z2, t2,
nx, ny, nz, tend.unix, live)) nx, ny, nz, tend.unix, live, camera_type))
pcompress = multiprocessing.Process(target=compress, pcompress = multiprocessing.Process(target=compress,
args=(buf, z1, t1, z2, t2, nx, ny, args=(buf, z1, t1, z2, t2, nx, ny,
nz, tend.unix, path)) nz, tend.unix, path))
@ -290,4 +329,3 @@ if __name__ == '__main__':
# Release device # Release device
if live is True: if live is True:
cv2.destroyAllWindows() cv2.destroyAllWindows()
device.release()

View File

@ -37,10 +37,12 @@ if __name__ == '__main__':
print("Found " + file_for_astrometry + " for astrometric solving.") print("Found " + file_for_astrometry + " for astrometric solving.")
sex_config = cfg.get('Astrometry', 'sex_config') sex_config = cfg.get('Astrometry', 'sex_config')
low_app = cfg.get('Astrometry', 'low_app')
high_app = cfg.get('Astrometry', 'high_app')
# Format command # Format command
command = "solve-field -O -y -u app -L 37 -H 40 --use-sextractor " + \ command = "solve-field -O -y -u app -L %s -H %s --downsample 2 " % (low_app, high_app) + \
"--sextractor-config %s --downsample 2 --x-column X_IMAGE " % sex_config + \ "--use-sextractor --sextractor-config %s --x-column X_IMAGE " % sex_config + \
"--y-column Y_IMAGE --sort-column MAG_AUTO --sort-ascending " + \ "--y-column Y_IMAGE --sort-column MAG_AUTO --sort-ascending " + \
"%s" % file_for_astrometry "%s" % file_for_astrometry

View File

@ -20,10 +20,13 @@ alt_sunset = -6.0 # Solar altitude at sunset
alt_sunrise = -6.0 # Solar altitude at sunrise alt_sunrise = -6.0 # Solar altitude at sunrise
[Camera] [Camera]
camera_type = watec # or asi for ZWO ASI Cameras
device_id = 0 device_id = 0
camera_x = 720 # Camera horizontal pixel count camera_x = 720 # Camera horizontal pixel count
camera_y = 576 # Camera vertical 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] [Astrometry]
sex_config = /path/to/solve.sex sex_config = /path/to/solve.sex
low_app = 18 # Arcsec per pixel low scale
high_app = 20 # Arcsec per pixel high scale

View File

@ -12,3 +12,4 @@ pytz==2018.4
six==1.11.0 six==1.11.0
spacetrack==0.13.0 spacetrack==0.13.0
termcolor termcolor
zwoasi