1+ # -*- coding: utf-8 -*-
2+ """
3+ Created on Sun Aug 25 18:19:14 2019
4+
5+ @author: Glenn C. Newell
6+ """
7+ import warnings
8+ warnings .filterwarnings (action = "ignore" )
9+ from astroquery .astrometry_net import AstrometryNet
10+ import astropy .wcs as wcs
11+ import re
12+ import math
13+ from PIL import Image , ImageOps
14+ import os
15+ import sys
16+
17+
18+
19+ def flip_image (image_path , saved_location ):
20+ """
21+ Flip or mirror the image
22+
23+ @param image_path: The path to the image to edit
24+ @param saved_location: Path to save the cropped image
25+ """
26+ image_obj = Image .open (image_path )
27+ rotated_image = image_obj .transpose (Image .FLIP_LEFT_RIGHT )
28+ rotated_image .save (saved_location )
29+ rotated_image .show ()
30+
31+ ast = AstrometryNet ()
32+ ast .api_key = 'XXXXXXXXXXXXXXXX'
33+
34+ imagename = sys .argv [1 ]
35+ #image.show()
36+ #imagename = "D:/Google Drive/Stellarium DSO image addition/buble_full_P-1.jpg"
37+ file , ext = os .path .splitext (imagename )
38+ image = Image .open (imagename )
39+ print ('Unstretching image by raising blackpoint (for Plate Solving)' )
40+ greyscale = image .copy ().convert ('L' )
41+
42+ stars = ImageOps .colorize (greyscale , black = "black" , white = "white" , blackpoint = 200 , whitepoint = 255 )
43+ #stars.show()
44+ print ('Saving:' , file + '_stars.jpg' )
45+ stars .save (file + '_stars.jpg' )
46+ print ('Uploading:' , file + '_stars.jpg' )
47+
48+ #wcs_header = ast.solve_from_image('D:\Google Drive\Stellarium DSO image addition\buble_full_P-1.jpg', force_image_upload=True)
49+
50+ try_again = True
51+ submission_id = None
52+
53+ while try_again :
54+ try :
55+ if not submission_id :
56+ #"C:\Users\gnewell\Google Drive\Stellarium DSO image addition\buble_full_P-1.jpg"
57+ #"D:/Google Drive/Stellarium DSO image addition/buble_full_P-1.jpg"
58+ wcs_header = ast .solve_from_image (file + '_stars.jpg' , force_image_upload = True , parity = 2 , scale_units = 'degwidth' , scale_type = 'ul' ,
59+ scale_lower = 0.1 , scale_upper = 12.0 , solve_timeout = 620 , downsample_factor = 2 , submission_id = submission_id )
60+ else :
61+ wcs_header = ast .monitor_submission (submission_id ,
62+ solve_timeout = 600 )
63+ except TimeoutError as e :
64+ submission_id = e .args [1 ]
65+ else :
66+ # got a result, so terminate
67+ try_again = False
68+
69+ if wcs_header :
70+ # Code to execute when solve succeeds
71+ #print(wcs_header)
72+ #w = wcs_header
73+ w = wcs .WCS (wcs_header )
74+ #hdu = hdulist[0]
75+ #hdr = hdulist[0].header
76+ #hdulist.close()
77+
78+ #print(repr(wcs_header))
79+
80+ print ('\n Image Width x Height:' ,wcs_header ['IMAGEW' ],'x' , wcs_header ['IMAGEH' ])
81+ for comment in wcs_header ['comment' ]:
82+ #print(comment)
83+ if re .match ('^scale:' ,comment ):
84+ print (comment )
85+ l = []
86+ for t in comment .split ():
87+ try :
88+ l .append (float (t ))
89+ except ValueError :
90+ pass
91+ scale = l [- 1 ]
92+ #print(scale)
93+
94+ cd11 = wcs_header ['CD1_1' ]
95+ cd12 = wcs_header ['CD1_2' ]
96+ cd21 = wcs_header ['CD2_1' ]
97+ cd22 = wcs_header ['CD2_2' ]
98+ if cd11 * cd22 - cd12 * cd21 > 0 :
99+ parity = 1
100+ else :
101+ parity = - 1
102+
103+ print ('Image Parity: ' ,parity )
104+ orientation = math .degrees (math .atan2 (cd21 - cd12 , cd11 + cd22 ))
105+ print ('Image Orientation: {0:.1f}' .format (180 + orientation ),'East of North' )
106+
107+ #print('Press Enter to exit')
108+ #input()
109+
110+ else :
111+ print ('Failure to solve input image' )
112+ # Code to execute when solve fails
113+ raise SystemExit
114+ imgresized = image .copy ()
115+ rescale = 1.0
116+ if scale < 1.0 :
117+ rescale = 0.5
118+ if scale < 0.5 :
119+ rescale = 0.25
120+ size = int (rescale * int (wcs_header ['IMAGEW' ])), int (rescale * int (wcs_header ['IMAGEH' ]))
121+ imgresized = image .resize (size )
122+
123+ imgflipped = imgresized .copy ()
124+ if parity == - 1 :
125+ print ('Flipping image to correct Parity' )
126+ imgflipped .transpose (Image .FLIP_LEFT_RIGHT )
127+ #image2.show()
128+ ccw = 180.01 - orientation
129+ print ('Rotating image' ,ccw , 'ccw so North is Up' )
130+ imgrotated = imgflipped .rotate (ccw , expand = 1 )
131+ #imgrotated.show()
132+ width , height = imgrotated .size
133+ print ('New size: ' ,width , height )
134+ if width >= height :
135+ ledgewidth = True
136+ ledgeheight = False
137+ else :
138+ ledgewidth = False
139+ ledgeheight = True
140+ scaledone = False
141+ print ('Scaling long edge to 512, 1024, or 2048' )
142+ if ledgewidth == True :
143+ if width > 2048 :
144+ rescale2 = 2048 / width
145+ size = int (rescale2 * width ), int (rescale2 * height )
146+ imgreresized = imgrotated .resize (size )
147+ scaledone = True
148+ if (scaledone == False ) and (width > 1024 ):
149+ rescale2 = 1024 / width
150+ size = int (rescale2 * width ), int (rescale2 * height )
151+ imgreresized = imgrotated .resize (size )
152+ scaledone = True
153+ if scaledone == False :
154+ rescale2 = 512 / width
155+ size = int (rescale2 * width ), int (rescale2 * height )
156+ imgreresized = imgrotated .resize (size )
157+ scaledone = True
158+ if ledgeheight == True :
159+ if height > 2048 :
160+ rescale2 = 2048 / height
161+ size = int (rescale2 * width ), int (rescale2 * height )
162+ imgreresized = imgrotated .resize (size )
163+ scaledone = True
164+ if scaledone == False and height > 1024 :
165+ rescale2 = 1024 / height
166+ size = int (rescale2 * width ), int (rescale2 * height )
167+ imgreresized = imgrotated .resize (size )
168+ scaledone = True
169+ if scaledone == False :
170+ rescale2 = 512 / height
171+ size = int (rescale2 * width ), int (rescale2 * height )
172+ imgreresized = imgrotated .resize (size )
173+ scaledone = True
174+ #imgreresized.show()
175+ width , height = imgreresized .size
176+ print ('New size: ' ,width , height )
177+ print ('Padding short edge to 512, 1024, or 2048' )
178+ paddone = False
179+ delta_w = 0
180+ delta_h = 0
181+ if ledgewidth == True :
182+ if height > 1024 :
183+ delta_h = 2048 - height
184+ paddone = True
185+ if paddone == False and height > 512 :
186+ delta_h = 1024 - height
187+ paddone = True
188+ if paddone == False :
189+ delta_h = 512 - height
190+ if ledgeheight == True :
191+ if width > 1024 :
192+ delta_w = 2048 - width
193+ paddone = True
194+ if paddone == False and width > 512 :
195+ delta_w = 1024 - width
196+ paddone = True
197+ if paddone == False :
198+ delta_w = 512 - width
199+ padding = (delta_w // 2 , delta_h // 2 , delta_w - (delta_w // 2 ), delta_h - (delta_h // 2 ))
200+ finalimage = ImageOps .expand (imgreresized , padding )
201+ width , height = finalimage .size
202+ print ('Final size: ' ,width , height )
203+ #finalimage.show()
204+ print ('Saving final image:' , file + '_for_Stellarium.png' )
205+ finalimage .save (file + '_for_Stellarium.png' )
206+ print ('Unstretching image by raising blackpoint (for Plate Solving)' )
207+ greyscale = finalimage .copy ().convert ('L' )
208+
209+ stars = ImageOps .colorize (greyscale , black = "black" , white = "white" , blackpoint = 200 , whitepoint = 255 )
210+ #stars.show()
211+ print ('Saving:' , file + '_for_Stellarium_stars.jpg' )
212+ stars .save (file + '_for_Stellarium_stars.jpg' )
213+ try_again = True
214+ submission_id = None
215+ newscale = scale / rescale / rescale2
216+
217+ newll = newscale * width / 3600 / 1.2
218+ newul = newscale * width / 3600 * 1.2
219+ print ('Scale est:' ,newscale ,'arcsecperpix (for Plate Solving) Lower Limit:' , newll , 'Upper Limit:' , newul , 'degwidth' )
220+ print ('Uploading:' , file + '_for_Stellarium_stars.jpg' )
221+ while try_again :
222+ try :
223+ if not submission_id :
224+ #wcs_header2 = ast.solve_from_image(file + '_for_Stellarium_stars.jpg', force_image_upload=True, parity=0, scale_units='arcsecperpix', scale_type='ev',
225+ # solve_timeout=620, scale_est=newscale, scale_err=20, downsample_factor=2, submission_id=submission_id)
226+ wcs_header2 = ast .solve_from_image (file + '_for_Stellarium_stars.jpg' , force_image_upload = True , parity = 1 , scale_units = 'degwidth' , scale_type = 'ul' ,
227+ solve_timeout = 620 , scale_lower = newll , scale_upper = newul , downsample_factor = 2 , submission_id = submission_id )
228+ else :
229+ wcs_header2 = ast .monitor_submission (submission_id ,
230+ solve_timeout = 600 )
231+ except TimeoutError as e :
232+ submission_id = e .args [1 ]
233+ else :
234+ # got a result, so terminate
235+ try_again = False
236+
237+ if wcs_header2 :
238+ w2 = wcs .WCS (wcs_header2 )
239+ # Code to execute when solve succeeds
240+ wx1 , wy1 = w2 .all_pix2world (0. , 0. , 0 )
241+ #print('0,0: {0} {1}'.format(wx1, wy1))
242+
243+ wx2 , wy2 = w2 .all_pix2world (wcs_header2 ['IMAGEW' ]- 1 ,0 , 0 )
244+ #print(wcs_header2['IMAGEW']-1,0,': {0} {1}'.format(wx2, wy2))
245+
246+
247+ wx3 , wy3 = w2 .all_pix2world (wcs_header2 ['IMAGEW' ]- 1 , wcs_header2 ['IMAGEH' ]- 1 , 0 )
248+ #print(wcs_header2['IMAGEW']-1, wcs_header2['IMAGEH']-1,': {0} {1}'.format(wx3, wy3))
249+
250+ wx4 , wy4 = w2 .all_pix2world (0. , wcs_header2 ['IMAGEH' ]- 1 , 0 )
251+ #print(0, wcs_header2['IMAGEH']-1,': {0} {1}'.format(wx4, wy4))
252+ i_n = '\" ' + os .path .basename (file + '_for_Stellarium.png' ) + '\" ,'
253+ print ('\n Saving Entry for Stellarium textures.json in:' ,file + '_for_Stellarium.json' )
254+ if os .path .exists (file + '_for_Stellarium.json' ):
255+ os .remove (file + '_for_Stellarium.json' )
256+ json = open (file + '_for_Stellarium.json' , "a" )
257+ print ('\t {\n \t \t \" imageCredits\" : {\" Short\" : \" Mine\" , \" infoUrl\" : \" \" },\n \t \t \" imageUrl\" :' ,i_n , file = json )
258+ print ('\t \t \" worldCoords" : [[[{0:.4f}, {1:.4f}], [{2:.4f}, {3:.4f}], [{4:.4f}, {5:.4f}], [{6:.4f}, {7:.4f}]]],' .format (wx4 , wy4 , wx3 , wy3 , wx2 , wy2 , wx1 , wy1 ), file = json )
259+ print ('\t \t \" textureCoords\" : [[[0,0], [1,0], [1,1], [0,1]]],\n \t \t \" minResolution\" : 0.2,\n \t \t \" maxBrightness\" : 12.0\n \t },' , file = json )
260+ json .close ()
261+ else :
262+ print ('Failure to solve final image' )
263+ # Code to execute when solve fails
264+
0 commit comments