-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpatches.py
executable file
·54 lines (43 loc) · 1.63 KB
/
patches.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#!/usr/bin/python
import collections
import itertools
import numpy
from utilities import crop
class Patches(collections.Iterable, collections.Sized):
"""
Represents an image and allows iteration over patches.
Patches may be manipulated and then sent to the stack method to put them
together into an image.
"""
def __init__(self, image, patch_shape):
# ammount of vertical / horizontal splits
self.__vsplits = int(image.shape[0] / patch_shape[0])
self.__hsplits = int(image.shape[1] / patch_shape[1])
# crop to the optimal shape
optimal_shape = (patch_shape[0] * self.__vsplits,
patch_shape[1] * self.__hsplits)
image = crop(image, optimal_shape)
self.__image = image
self.__patch_shape = patch_shape
def split(self):
"""
Split into patches.
"""
vsplitted = numpy.vsplit(self.__image, self.__vsplits)
hsplitted = (numpy.hsplit(vsplit, self.__hsplits) for vsplit in vsplitted)
return itertools.chain(*hsplitted)
def stack(self, patches):
"""
Puts together the patches to match the shape of the original image.
Assumes patches are created from this Patches. Undoes what self.split
does to an image.
"""
# stack together horizontally
vsplits = (numpy.hstack(itertools.islice(patches, self.__hsplits))
for _ in xrange(self.__vsplits))
# stack vertically
return numpy.vstack(vsplits)
def __iter__(self):
return self.split()
def __len__(self):
return self.__vsplits * self.__hsplits