Skip to content

Commit

Permalink
Refactor contrast stretching
Browse files Browse the repository at this point in the history
  • Loading branch information
mrpgraae committed Mar 14, 2018
1 parent 193db04 commit f107e9e
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 31 deletions.
23 changes: 23 additions & 0 deletions terracotta/encode_decode.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,26 @@ def array_to_img(arr, alpha_mask):
img = Image.fromarray(alpha_mask, mode='LA')

return img


def contrast_stretch(tile, val_range):
"""Scale an image to between 0 and 255.
Parameters
----------
val_range: (int, int)
min and max value of input tile
Returns
-------
out: numpy array
input tile scaled to 0 - 255.
"""

_, max_val = val_range
if max_val == 0:
tile[:] = 0
else:
tile *= 255 // max_val
tile = tile.astype(np.uint8)
return tile
30 changes: 3 additions & 27 deletions terracotta/tile.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ def _load_file_meta(files):
return meta

def tile(self, tile_x, tile_y, tile_z, ds_name,
timestep=None, tilesize=256, scale_contrast=False):
timestep=None, tilesize=256):
"""Load a requested tile from source.
Parameters
Expand Down Expand Up @@ -181,14 +181,13 @@ def tile(self, tile_x, tile_y, tile_z, ds_name,
raise TileOutOfBoundsError('Tile {}/{}/{} is outside image bounds'
.format(tile_z, tile_x, tile_y))

nodata = self.get_nodata(ds_name)
mercator_tile = mercantile.Tile(x=tile_x, y=tile_y, z=tile_z)
tile_bounds = mercantile.xy_bounds(mercator_tile)
tile = self._load_tile(fname, tile_bounds, tilesize)

nodata = self.get_nodata(ds_name)
alpha_mask = np.full((tilesize, tilesize), 255, np.uint8)
alpha_mask[tile == nodata] = 0
if scale_contrast:
tile = contrast_stretch(tile, self._datasets[ds_name]['meta']['range'])

return tile, alpha_mask

Expand Down Expand Up @@ -253,26 +252,3 @@ def tile_exists(bounds, tile_z, tile_x, tile_y):
and (tile_x >= mintile.x) \
and (tile_y <= maxtile.y + 1) \
and (tile_y >= mintile.y)


def contrast_stretch(tile, val_range):
"""Scale the image to between 0 and 255.
Parameters
----------
val_range: (int, int)
min and max value of input tile
Returns
-------
out: numpy array
input tile scaled to 0 - 255.
"""

_, max_val = val_range
if max_val == 0:
tile[:] = 0
else:
tile *= 255 // max_val
tile = tile.astype(np.uint8)
return tile
9 changes: 5 additions & 4 deletions terracotta/tile_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

import terracotta.tile as tile
from terracotta.tile import TileNotFoundError, TileOutOfBoundsError, DatasetNotFoundError
from terracotta.encode_decode import array_to_img
import terracotta.encode_decode as ed


DEFAULT_CACHE_SIZE = 1000000000 # 1GB
Expand All @@ -32,8 +32,7 @@ def get_tile(dataset, tile_z, tile_x, tile_y, timestep=None):
"""Respond to tile requests"""

try:
img, alpha_mask = tilestore.tile(tile_x, tile_y, tile_z, dataset, timestep,
scale_contrast=True)
img, alpha_mask = tilestore.tile(tile_x, tile_y, tile_z, dataset, timestep)
except TileNotFoundError:
if current_app.debug:
raise
Expand All @@ -43,7 +42,9 @@ def get_tile(dataset, tile_z, tile_x, tile_y, timestep=None):
img = np.full((256, 256), nodata, dtype=np.uint8)
alpha_mask = np.zeros((256, 256), dtype=np.uint8)

img = array_to_img(img, alpha_mask)
range = tilestore.get_meta(dataset)['range']
img = ed.contrast_stretch(img, range)
img = ed.array_to_img(img, alpha_mask)

sio = BytesIO()
img.save(sio, 'png', compress_level=0)
Expand Down

0 comments on commit f107e9e

Please sign in to comment.