Skip to content

Commit

Permalink
Update example, change stride behaviour if scale is not 1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
vfdev-5 committed Feb 12, 2018
1 parent c9bab5e commit c89abce
Show file tree
Hide file tree
Showing 5 changed files with 180 additions and 51 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ report/
__pycache__/
*.py[cod]
*$py.class
.pytest_cache

# C extensions
*.so
Expand Down
129 changes: 115 additions & 14 deletions examples/example_const_stride_tiling.ipynb

Large diffs are not rendered by default.

79 changes: 51 additions & 28 deletions tests/test_const_stride.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
import numpy as np


from tiling import ConstStrideTiles
from tiling import ConstStrideTiles, ceil_int


DEBUG_MODE = False


class TestConstStrideTiles(unittest.TestCase):
Expand Down Expand Up @@ -38,6 +41,12 @@ def test_wrong_args(self):
with self.assertRaises(AssertionError):
ConstStrideTiles((100, 120), (10, 10), stride=(10, -10))

def test_wrong_index(self):

with self.assertRaises(IndexError):
tiles = ConstStrideTiles((100, 120), (10, 10), stride=(5, 5))
tiles[10000]

def test_with_nodata(self):

def _test(im_size, ts, scale, stride, origin):
Expand All @@ -54,7 +63,7 @@ def _test(im_size, ts, scale, stride, origin):

debug_msg += "n={}\n".format(len(tiles))
self.assertGreater(len(tiles), 0, debug_msg)
self.assertLess(np.sqrt(len(tiles)), 1 + (im_size - origin) * 1.0 / stride, debug_msg)
self.assertLess(np.sqrt(len(tiles)), 1 + (im_size - origin) * 1.0 / tiles.stride[0], debug_msg)

extent0, out_size0 = tiles[0]
# Start at origin
Expand All @@ -71,9 +80,9 @@ def _test(im_size, ts, scale, stride, origin):
self.assertEqual(d, (extent[2], extent[3]), debug_msg)
# Check if constant stride
if extent[0] - prev_extent[0] > 0:
self.assertEqual(stride, extent[0] - prev_extent[0], debug_msg)
self.assertEqual(tiles.stride[0], extent[0] - prev_extent[0], debug_msg)
if extent[1] - prev_extent[1] > 0:
self.assertEqual(stride, extent[1] - prev_extent[1], debug_msg)
self.assertEqual(tiles.stride[1], extent[1] - prev_extent[1], debug_msg)
else:
self.assertEqual(0, extent[1] - prev_extent[1], debug_msg)

Expand All @@ -85,15 +94,25 @@ def _test(im_size, ts, scale, stride, origin):
debug_msg += "extent={}, out_size={}\n".format(extent, _)
self.assertLess(extent[0], im_size, debug_msg)
self.assertLess(extent[1], im_size, debug_msg)
self.assertGreaterEqual(extent[0] + max(extent[2], stride), im_size, debug_msg)
self.assertGreaterEqual(extent[1] + max(extent[3], stride), im_size, debug_msg)

for scale in [0.7, 0.89, 0.99, 1.0, 1.78, 2.12]:
for im_size in range(100, 120):
for ext in range(32, int(im_size * scale) - 1, 3):
for stride in range(ext // 2, ext + 10, 3):
for origin in range(-5, 5):
_test(im_size, ext, scale, stride, origin)
self.assertGreaterEqual(extent[0] + max(extent[2], tiles.stride[0]), im_size, debug_msg)
self.assertGreaterEqual(extent[1] + max(extent[3], tiles.stride[1]), im_size, debug_msg)

if not DEBUG_MODE:
for scale in [0.7, 0.89, 0.99, 1.0, 1.78, 2.12]:
for im_size in range(100, 120):
for ext in range(32, int(im_size * scale) - 1, 3):
for stride in range(int(ext * scale) // 2, int(ext * scale) + 10, 5):
for origin in range(-5, 5):
_test(im_size, ext, scale, stride, origin)

def test_as_iterator(self):
tiles = ConstStrideTiles((100, 120), (10, 10), stride=(5, 5))
counter = 0
for extent, out_size in tiles:
_extent, _out_size = tiles[counter]
self.assertEqual(extent, _extent)
self.assertEqual(out_size, _out_size)
counter += 1

def test_without_nodata(self):

Expand All @@ -111,7 +130,7 @@ def _test(im_size, ts, scale, stride, origin):

debug_msg += "n={}\n".format(len(tiles))
self.assertGreater(len(tiles), 0, debug_msg)
self.assertLess(np.sqrt(len(tiles)), 1 + (im_size - origin) * 1.0 / stride, debug_msg)
self.assertLess(np.sqrt(len(tiles)), 1 + (im_size - origin) * 1.0 / tiles.stride[0], debug_msg)

extent0, out_size0 = tiles[0]
# Start at origin but should be positive
Expand Down Expand Up @@ -145,7 +164,7 @@ def _test(im_size, ts, scale, stride, origin):
if prev_extent[2] == tiles.tile_extent[0]:
# Check if constant stride
if extent[0] - prev_extent[0] > 0:
self.assertEqual(stride, extent[0] - prev_extent[0],
self.assertEqual(tiles.stride[0], extent[0] - prev_extent[0],
debug_msg + var_debug_msg)

# Check if output size is the same
Expand All @@ -154,16 +173,16 @@ def _test(im_size, ts, scale, stride, origin):
if extent[0] - prev_extent[0] > 0:
if prev_extent[0] == 0 and extent[0] + extent[2] < im_size:
# Check stride between the ends of tiles
self.assertEqual(stride, extent[0] + extent[2] - prev_extent[0] - prev_extent[2],
self.assertEqual(tiles.stride[1], extent[0] + extent[2] - prev_extent[0] - prev_extent[2],
debug_msg + var_debug_msg)
elif prev_extent[0] > 0 and extent[0] + extent[2] == im_size:
# Check stride between the starts of tiles
self.assertEqual(stride, extent[0] - prev_extent[0],
self.assertEqual(tiles.stride[0], extent[0] - prev_extent[0],
debug_msg + var_debug_msg)

if prev_extent[3] == tiles.tile_extent[1]:
if extent[1] - prev_extent[1] > 0:
self.assertEqual(stride, extent[1] - prev_extent[1],
self.assertEqual(tiles.stride[1], extent[1] - prev_extent[1],
debug_msg + var_debug_msg)
else:
self.assertEqual(0, extent[1] - prev_extent[1], debug_msg + var_debug_msg)
Expand All @@ -172,33 +191,37 @@ def _test(im_size, ts, scale, stride, origin):
if extent[1] - prev_extent[1] > 0:
if prev_extent[1] == 0 and extent[1] + extent[3] < im_size:
# Check stride between the ends of tiles
self.assertEqual(stride, extent[1] + extent[3] - prev_extent[1] - prev_extent[3],
self.assertEqual(tiles.stride[1], extent[1] + extent[3] - prev_extent[1] - prev_extent[3],
debug_msg + var_debug_msg)
elif prev_extent[1] > 0 and extent[1] + extent[3] == im_size:
self.assertEqual(stride, extent[1] - prev_extent[1],
self.assertEqual(tiles.stride[1], extent[1] - prev_extent[1],
debug_msg + var_debug_msg)

# Check the last tile ends at the boundary or out side and starts inside
extent, _ = tiles[-1]
debug_msg += "extent={}, out_size={}\n".format(extent, _)
self.assertLess(extent[0], im_size, debug_msg)
self.assertLess(extent[1], im_size, debug_msg)
if stride < tiles.tile_extent[0]:
if tiles.stride[0] < tiles.tile_extent[0]:
self.assertEqual(extent[0] + extent[2], im_size, debug_msg)
else:
self.assertLessEqual(extent[0] + extent[2], im_size, debug_msg)

if stride < tiles.tile_extent[1]:
if tiles.stride[1] < tiles.tile_extent[1]:
self.assertEqual(extent[1] + extent[3], im_size, debug_msg)
else:
self.assertLessEqual(extent[1] + extent[3], im_size, debug_msg)

for scale in [0.7, 0.89, 0.99, 1.0, 1.78, 2.12]:
for im_size in range(100, 120):
for ext in range(32, int(im_size * scale) - 1, 3):
for stride in range(ext // 2, ext + 10, 3):
for origin in range(-5, 5):
_test(im_size, ext, scale, stride, origin)
if not DEBUG_MODE:
for scale in [0.7, 0.89, 0.99, 1.0, 1.78, 2.12]:
for im_size in range(100, 120):
for ext in range(32, int(im_size * scale) - 1, 3):
for stride in range(int(ext * scale) // 2, int(ext * scale) + 10, 5):
for origin in range(-5, 5):
_test(im_size, ext, scale, stride, origin)

def test_int_ceil(self):
self.assertEqual(2, ceil_int(1.789))


if __name__ == "__main__":
Expand Down
8 changes: 7 additions & 1 deletion tiling/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
from __future__ import absolute_import
from abc import ABCMeta, abstractmethod

import numpy as np


__version__ = '0.1'


Expand Down Expand Up @@ -38,7 +41,10 @@ def __init__(self, image_size, tile_size=(128, 128), scale=1.0):
self.image_size = image_size
self.tile_size = tile_size
self.scale = float(scale)
self.tile_extent = [d / self.scale for d in self.tile_size]
# Apply floor to tile extent (tile size / scale)
# Output size is then ceil(extent * scale), extent is <= tile_extent
# ceil(extent * scale) < ceil(tile_extent * scale) = ceil(floor(tile_extent / scale) * scale)<= tile_size
self.tile_extent = [int(np.floor(d / self.scale)) for d in self.tile_size]
self._index = 0
self._max_index = 0

Expand Down
14 changes: 6 additions & 8 deletions tiling/const_stride.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,9 @@ def __init__(self, image_size, tile_size, stride=(1, 1), scale=1.0, origin=(0, 0
Initialize tiles
:param image_size: (list or tuple of int) input image size in pixels (width, height)
:param tile_size: (list or tuple of int) output tile size in pixels (width, height)
:param stride: (list or tuple of int) horisontal and vertical strides in pixels.
Values need to be positive larger than 1 pixel.
:param stride: (list or tuple of int) horizontal and vertical strides in pixels.
Values need to be positive larger than 1 pixel. Stride value is impacted with scale and corresponds to a
sliding over scaled image.
:param scale: (float) Scaling applied to the input image parameters before extracting tile's extent
:param origin: (list or tuple of int) point in pixels in the original image from where to start the tiling.
Values can be positive or negative
Expand All @@ -84,13 +85,10 @@ def __init__(self, image_size, tile_size, stride=(1, 1), scale=1.0, origin=(0, 0
"Argument stride should be a tuple/list (sx, sy)"
if isinstance(stride, int):
stride = (stride, stride)
# Apply scale on the stride
stride = [int(np.floor(s / self.scale)) for s in stride]
for v in stride:
assert v > 0, "Stride values should be larger than 1 pixel"

# Apply floor to tile extent (tile size / scale)
# Output size is then ceil(extent * scale), extent is <= tile_extent
# ceil(extent * scale) < ceil(tile_extent * scale) = ceil(floor(tile_extent / scale) * scale)<= tile_size
self.tile_extent = [int(np.floor(e)) for e in self.tile_extent]
assert v > 0, "Scaled stride values `floor(stride / scale)` should be larger than 1 pixel"

self.stride = stride
self.origin = origin
Expand Down

0 comments on commit c89abce

Please sign in to comment.