def panSharpen(image, data, band): from mpop.imageo.geo_image import GeoImage pan_data = data[band].data pan = GeoImage((pan_data), data.area, data.time_slot, crange=(0,100) , mode="L") pan.enhance(gamma=2.0) sharp_image = image sharp_image.replace_luminance(pan.channels[0]) return sharp_image
def s2_truecolor(self): self.check_channels('B02','B03','B04') ch1 = self['B04'].data ch2 = self['B03'].data ch3 = self['B02'].data img = GeoImage((ch1, ch2, ch3), self.area, self.time_slot, fill_value=None, mode="RGB") img.enhance(stretch="linear") #img.enhance(stretch="histogram") img.enhance(gamma=2.0) return img
def daynight_background(self, cos_scaled=True, use_HRV=False, smooth=False, stretch=False, colorscale='greys', fixed_minmax=False, white_clouds=True): import numpy as np # threshold sza sza1 = 80. # calculate longitude/latitude and solar zenith angle from pyorbital.astronomy import sun_zenith_angle lonlats = self["IR_108"].area.get_lonlats() sza = sun_zenith_angle(self.time_slot, lonlats[0], lonlats[1]) if not smooth: mask = np.array(sza > sza1) else: mask = np.zeros(ir108.shape) mask[np.where(sza > sza1)] = 1 # select, if you want HRV or VIS006 if use_HRV: vis = self["HRV"].data # fill remaining area with VIS006 vis[vis.mask == True] = self["VIS006"].data[vis.mask == True] else: vis = self["VIS006"].data # sceen out data at night/day part of the disk ir108 = self["IR_108"].data * mask # ... and apply cos scaling to mitigate effect of solar zenith angle if not cos_scaled: vis = vis * (1 - mask) else: vis = vis * (1 - mask) / (np.cos(np.radians(sza)) + 0.05) # normilize vis reflectivity and ir brightness temperature # to comparable range between 0 and 1 if fixed_minmax: # minimum and maximum for ir108 ir1 = 190. ir2 = 290. # minimum and maximum for HRV (or VIS006) scale vis1 = 0. if not cos_scaled: vis2 = 75. #for pure vis/hrv else: vis2 = 110. #for scaling with cos(sza) else: # linear stretch from p1 percentile to p2 percentile #import matplotlib.pyplot as plt #plt.hist(ir108[np.where(ir108 > 100)], bins='auto') #plt.title("Histogram with 'auto' bins") #plt.show() #print " min/max(1) IR:", ir108.min(), ir108.max() #print " min/max(1) VIS:", vis.min(), vis.max() # percentile limits p1 = 5 p2 = 95 # ind_ir108 = np.where(ir108 > 100) if len(ind_ir108) > 5: ir1 = np.percentile(ir108[ind_ir108], p1) ir2 = np.percentile(ir108[ind_ir108], p2) else: ir1 = 190. ir2 = 290. ind_vis = np.where(vis > 0) if len(ind_vis) > 5: vis1 = np.percentile(vis[np.where(vis > 0)], p1) vis2 = np.percentile(vis[np.where(vis > 0)], p2) else: vis1 = 5. if not cos_scaled: vis2 = 75. else: vis2 = 110. #print " min/max(2) IR:", ir1, ir2 #print " min/max(2) VIS:", vis1, vis2 # scale the vis and ir channel to the range [0,1] # multiply with mask to keep the zeros for day/night area ir108 = (ir108 - ir1) / (ir2 - ir1) * mask vis = (vis - vis1) / (vis2 - vis1) * (1 - mask) #print " min/max scaled ir: ", ir108.min(), ir108.max() #print " min/max scaled vis:", vis.min(), vis.max() # invert ir108 ir108 = (1 - ir108) * mask img = GeoImage(vis + ir108, self.area, self.time_slot, fill_value=(0, 0, 0), mode="L") print(colorscale, white_clouds) if colorscale == 'rainbow': from trollimage.colormap import rainbow cm = deepcopy(rainbow) elif colorscale == 'greys': from trollimage.colormap import greys cm = deepcopy(greys) if white_clouds: #cm.reverse() # UH (my change in trollimage/colormap.py): color table is not any more changed, but changed one is returned. cm = cm.reverse() cm.set_range(0, 1) img.colorize(cm) if stretch: print("... use streching ", stretch) img.enhance(stretch=stretch) return img
#germ_scene.image[0.6].show() germ_area = germ_scene[10.8].area_def # Resample fls input elevation_ger = elevation.resample(germ_area) cot_ger = cot_fd.resample(germ_area) reff_ger = reff_fd.resample(germ_area) cwp_ger = cwp_fd.resample(germ_area) ele_img = GeoImage(elevation_ger.image_data, germ_area, time, fill_value=0, mode="L") ele_img.enhance(stretch="crude") cwp_img = GeoImage(cwp_ger.image_data, germ_area, time, fill_value=0, mode="L") cwp_img.enhance(stretch="crude") reff_img = GeoImage(reff_ger.image_data, germ_area, time, fill_value=0, mode="L") reff_img.enhance(stretch="crude") cot_img = GeoImage(cot_ger.image_data, germ_area, time,
def create_PIL_image(rgb, data, in_msg): if in_msg.verbose: print("*** make image for: ", rgb) # get the data array that you want to plot if rgb in products.MSG: prop = data[rgb].data plot_type = 'channel_image' elif rgb in products.MSG_color: prop = data[rgb.replace("c", "")].data plot_type = 'trollimage' elif rgb in products.CTTH: prop = data[rgb].data prop.mask = (prop == 0) if rgb == 'CTH': prop /= 1000. # 1000. == m -> km plot_type = 'trollimage' elif rgb in products.CT: prop = data[rgb].data plot_type = 'palette' if rgb == 'CT_QUALITY': plot_type = 'trollimage' elif rgb in products.CMa or rgb in products.SPhR: prop = data[rgb].data if hasattr(data[rgb], 'palette') and in_msg.nwcsaf_calibrate == False: plot_type = 'palette' else: plot_type = 'trollimage' elif rgb in products.HSAF: prop = data[rgb].data plot_type = 'trollimage' else: # includes products.RGBs_buildin prop = ma.asarray([-999., -999.]) plot_type = 'user_defined' #from numpy import log10 #prop=log10(prop) # search minimum and maximum # (default) min_data = prop.min() max_data = prop.max() # replace default with fixed min/max if specified if in_msg.fixed_minmax: if rgb in list(in_msg.rad_min.keys()): min_data = in_msg.rad_min[rgb] else: if rgb not in products.RGBs_buildin: print( "*** Warning, no specified minimum for plotting in get_input_msg.py or input file" ) if rgb in list(in_msg.rad_max.keys()): max_data = in_msg.rad_max[rgb] else: if rgb not in products.RGBs_buildin: print( "*** Warning, no specified maximum for plotting in get_input_msg.py or input file" ) if in_msg.verbose and rgb not in products.RGBs_buildin: print('... set value range from min_data (', min_data, ') to max_data (', max_data, ')') # specifies if a colorbar does make sense at all in_msg.colormap = {} # make the image if plot_type == 'channel_image': if in_msg.verbose: print( " use data.image.channel_image for black and white pictures" ) img = data.image.channel_image(rgb) in_msg.colormap[rgb] = None elif plot_type == 'trollimage': if in_msg.verbose: print( " use trollimage.image.image for colorized pictures (min=" + str(min_data) + ", max=" + str(max_data) + ")") img = trollimage(prop, mode="L", fill_value=in_msg.fill_value) rainbow.set_range(min_data, max_data) img.colorize(rainbow) rainbow_r.set_range( min_data, max_data ) # attention set_range does modify the colormap, but does not have a return values ! in_msg.colormap[rgb] = rainbow.reverse() # print "in_msg.colormap[rgb]", rgb, in_msg.colormap[rgb] elif plot_type == 'palette': min_data = 0. max_data = float(len(data[rgb].palette) - 1) if in_msg.verbose: print(" use GeoImage and colorize with a palette (min=" + str(min_data) + ", max=" + str(max_data) + ")") img = GeoImage(prop, data.area, data.time_slot, mode="P", palette=data[rgb].palette, fill_value=in_msg.fill_value) colormap = convert_palette2colormap(data[rgb].palette) colormap.set_range(min_data, max_data) # no return value! in_msg.colormap[rgb] = colormap elif plot_type == 'user_defined': obj_image = get_image(data, rgb) if in_msg.verbose: print(" use image function defined by my_msg_module.py") img = obj_image() in_msg.colormap[rgb] = None #if rgb == 'ndvi': # in_msg.colormap[rgb] = rdylgn_r else: print("*** Error in create_PIL_image (" + inspect.getfile(inspect.currentframe()) + ")") print(" unknown plot_type ", plot_type) quit() if in_msg.HRV_enhancement: if in_msg.verbose: print("enhance the image with the HRV channel") luminance = GeoImage((data["HRV"].data), data.area, data.time_slot, crange=(0, 100), mode="L") luminance.enhance(gamma=2.0) img.replace_luminance(luminance.channels[0]) rgb = 'HR' + rgb ## alternative: for geoimages is possible to add coasts and borders, but not for trollimage #if hasattr(img, 'add_overlay'): # if in_msg.verbose: # print " add coastlines to image by add_averlay" # img.add_overlay(color=(0, 0, 0), width=0.5, resolution=None) # convert image to PIL image if hasattr(img, 'pil_image'): if in_msg.verbose: print(" convert to PIL_image by pil_image function") PIL_image = img.pil_image() else: if in_msg.verbose: print(" convert to PIL_image by saving and reading") tmp_file = outputDir + satS + '_' + dateS + '_' + timeS + '__' + area + '_' + rgb.replace( "_", "-") + '_tmp.png' # in_msg. img.save(tmp_file) PIL_image = Image.open(tmp_file) subprocess.call("rm " + tmp_file, shell=True) return PIL_image
def fls_day(self, elevation, cot, reff, lwp=None, cth=None, validate=False, plot=False, plotdir='/tmp', single=False): """This method defines a composite for fog and low stratus detection and forecasting at daytime. The fog algorithm is optimized for the Meteosat Second Generation - SERVIRI instrument. Args: | elevation (:obj:`ndarray`): Ditital elevation model as array. | cot (:obj:`ndarray`): Cloud optical thickness(depth) as array. | reff (:obj:`ndarray`): Cloud particle effective radius as array. | lwp (:obj:`ndarray`): Liquid water path as array. | cth (:obj:`ndarray`): Cloud top height as array, optional. | validate (:obj:`bool`): Additional cloud mask output, optional. | plot (:obj:`bool`): Save filter and algorithm results as png images. | plotdir (:obj:`str`): Path to plotting directory as string. | single (:obj:`bool`): Compute lowcloud model single pixelwise. Default is False. Returns: Infrared image with colorized fog areas and the calculated fog mask. """ logger.debug("Creating fog composite for {} instrument scene {}" .format(self.fullname, self.time_slot)) self.check_channels(0.635, 0.81, 1.64, 3.92, 8.7, 10.8, 12.0) # Get central lon/lat coordinates for the image area = self[10.8].area lon, lat = area.get_lonlats() flsinput = {'vis006': self[0.635].data, 'vis008': self[0.81].data, 'ir108': self[10.8].data, 'nir016': self[1.64].data, 'ir039': self[3.92].data, 'ir120': self[12.0].data, 'ir087': self[8.7].data, 'lat': lat, 'lon': lon, 'time': self.time_slot, 'elev': elevation, 'cot': cot, 'reff': reff, 'lwp': lwp, 'cth': cth, 'plot': plot, 'save': plot, 'dir': plotdir, 'single': single, 'resize': '1'} # Compute fog mask flsalgo = DayFogLowStratusAlgorithm(**flsinput) fls, mask = flsalgo.run() # Create geoimage object from algorithm result flsimg = GeoImage(fls, area, self.time_slot, fill_value=0, mode="L") flsimg.enhance(stretch="crude") maskimg = GeoImage(~mask, area, self.time_slot, fill_value=0, mode="L") maskimg.enhance(stretch="crude") if validate: # Get cloud mask image vmaskimg = GeoImage(flsalgo.vcloudmask, area, self.time_slot, fill_value=0, mode="L") vmaskimg.enhance(stretch="crude") # Get cloud base height image cbhimg = GeoImage(flsalgo.cbh, area, self.time_slot, fill_value=9999, mode="L") # Get fog base height image fbhimg = GeoImage(flsalgo.fbh, area, self.time_slot, fill_value=9999, mode="L") # Get low cloud top height image lcthimg = GeoImage(flsalgo.lcth, area, self.time_slot, fill_value=9999, mode="L") return [flsimg, maskimg, vmaskimg, cbhimg, fbhimg, lcthimg] else: return flsimg, maskimg