pytroll / satpy

Python package for earth-observing satellite data processing
http://satpy.readthedocs.org/en/latest/
GNU General Public License v3.0
1.06k stars 293 forks source link

Question: Change image size when saving with satpy.save_dataset #683

Closed isobelrlawrence closed 5 years ago

isobelrlawrence commented 5 years ago

Hello,

I'm using Satpy to generate RGB composites from satellite imagery. I want to generate them fairly quickly and output small image files so I can scan through them quickly to check cloud cover.

Currently scene.save_dataset is outputting .png images which are ~70x70 inches and 40Mb, so way bigger than I need. I cant see how to change the image size (to say 10% of what it is currently) within this or another satpy function.

Please help! Here is my code:

from satpy.scene import Scene
from satpy import find_files_and_readers
from datetime import datetime

files = find_files_and_readers(sensor='olci', 
              start_time=datetime(2019, 3, 15, 4, 28),
              end_time=datetime(2019, 3, 15, 4, 30),
              base_dir="/Users/il/Downloads/",
              reader='olci_l1b')

scn = Scene(filenames=files)
scn.load(['true_color'])
scn.save_dataset('true_color', filename='true_color_gnc_tutorial'+'.png')

Many thanks

djhoese commented 5 years ago

This is similar to #368 and is something I've been concerned about. You have a couple options; some don't exist but would be the fastest most efficient way of doing it; others exist but produce the equivalent result. It also depends if you need geolocation information. Since you mentioned just skimming through the images, I'm guessing this isn't needed. I'll provide as much info as I can. First, the options that exist:

  1. You could resample to a smaller version of the input area. See https://pyresample.readthedocs.io/en/latest/geo_def.html#areadefinition for more information (just noticed the docs haven't rebuilt in a while, hopefully will have these updated shortly). By providing this smaller version of the source area (scn['true_color'].attrs['area']) to new_scn = scn.resample(smaller_area, cache_dir='/path/to/cache_dir/') you should be able to create smaller versions of the data relatively quickly. This is your only existing option if you need geolocation. By default this would do nearest neighbor resampling. You may want aggregation/averaging which is possible by specifying resampler='native' but requires the target area to be an even factor of the source area.
  2. You can slice the data: scn['small_true_color'] = scn['true_color'][:, ::4, ::4] This means take ever 4th pixel in the y and x dimensions. This will make the "area" attribute invalid. This is your best/fastest option if you don't care about geolocation.

Now for the ones that don't exist yet:

  1. Slicing of the Scene object is possible, but you can't stride the data (ex. ::4) yet. This is mainly a limitation of the AreaDefinition class in pyresample. It is something we want to add, but haven't had the time. Let me know if you'd be interested in looking in to it. This would allow you to do the same thing as 2 above but keep the geolocation intact.
  2. @mraspaud is currently working on an "aggregation" method which would make it easier to get a nicer image similar to 1 above. This feature is not ready yet.
isobelrlawrence commented 5 years ago

Thanks for your reply Djhoese, I sliced the data as you suggested. It's not ideal as the images look more pixelated but it will do!

The ability to resize whilst maintaining the DPI would be a good feature in the future!

Many thanks

djhoese commented 5 years ago

Aggregation as @mraspaud is working on would help provide some amount of high quality at lower number of pixels. Keep in mind that you can't have a full resolution image and have the final image use less pixels. Compression would allow the file to be smaller, but you still have to store all that data if you want it to be full/high resolution.