Skip to content

Instantly share code, notes, and snippets.

@jabooth
Created July 10, 2014 13:45
Show Gist options
  • Save jabooth/4d809b780a3b70d5146c to your computer and use it in GitHub Desktop.
Save jabooth/4d809b780a3b70d5146c to your computer and use it in GitHub Desktop.
extract_local_patches_fast lineprofile breaking bad image
Timer unit: 1e-06 s
File: /Users/jab08/pythondev/menpo/menpo/fitmultilevel/functions.py
Function: extract_local_patches_fast at line 67
Total time: 0.001947 s
Line # Hits Time Per Hit % Time Line Contents
==============================================================
67 def extract_local_patches_fast(image, centres, patch_shape, out=None):
68 r"""
69 Extract square patches from an image about centres.
70
71 Parameters
72 ----------
73 image : :map:`Image`
74 The image to extract patches from
75
76 centres : :map:`PointCloud`
77 The centres around which the patches should be extracted
78
79 patch_shape : `tuple` of `ints`
80 The size of the patch in each dimension
81
82 out : `ndarray` of shape: ``n_centres, + patch_shape + n_channels,``,
83 optional
84 The output array to be assigned to. If `None`, a new numpy array
85 will be created.
86
87 Returns
88 -------
89 patches : `ndarray` of shape: ``n_centres, + patch_shape + n_channels,``
90 The patches as a single numpy array.
91 """
92 1 2 2.0 0.1 if out is not None:
93 patches = out
94 else:
95 1 2 2.0 0.1 patches = np.empty(
96 1 12 12.0 0.6 (centres.n_points,) + patch_shape + (image.n_channels,))
97 # 0 out the patches array
98 1 121 121.0 6.2 patches[...] = 0
99 1 12 12.0 0.6 image_size = np.array(image.shape, dtype=np.int)
100 1 7 7.0 0.4 patch_shape = np.array(patch_shape, dtype=np.int)
101 1 20 20.0 1.0 centres = np.require(centres.points, dtype=np.int)
102 1 25 25.0 1.3 half_patch_shape = np.require(np.floor(patch_shape / 2), dtype=np.int)
103 # deal with odd patch shapes
104 # - add_to_patch[axis] = 0 if patch_shape[axis] is odd
105 # - add_to_patch[axis] = 1 if patch_shape[axis] is even
106 1 4 4.0 0.2 add_to_patch = np.mod(patch_shape, 2)
107 # 1. compute the extents
108 1 13 13.0 0.7 c_min = centres - half_patch_shape
109 1 8 8.0 0.4 c_max = centres + half_patch_shape + add_to_patch
110 1 6 6.0 0.3 out_min_min = c_min < 0
111 1 5 5.0 0.3 out_min_max = c_min > image_size
112 1 4 4.0 0.2 out_max_min = c_max < 0
113 1 3 3.0 0.2 out_max_max = c_max > image_size
114
115 # 1. Build the extraction slices
116 1 3 3.0 0.2 ext_s_min = c_min.copy()
117 1 2 2.0 0.1 ext_s_max = c_max.copy()
118 # Clamp the min to 0
119 1 3 3.0 0.2 ext_s_min[out_min_min] = 0
120 1 2 2.0 0.1 ext_s_max[out_max_min] = 0
121 # Clamp the max to image bounds across each dimension
122 3 8 2.7 0.4 for i in xrange(image.n_dims):
123 2 28 14.0 1.4 ext_s_max[out_max_max[:, i], i] = image_size[i] - 1
124 2 18 9.0 0.9 ext_s_min[out_min_max[:, i], i] = image_size[i] - 1
125
126 # 2. Build the insertion slices
127 1 3 3.0 0.2 ins_s_min = ext_s_min - c_min
128 1 16 16.0 0.8 ins_s_max = np.maximum(ext_s_max - c_max + patch_shape, (0, 0))
129
130 1 1 1.0 0.1 for i, (e_a, e_b, i_a, i_b) in enumerate(zip(ext_s_min, ext_s_max,
131 69 189 2.7 9.7 ins_s_min, ins_s_max)):
132 # build a list of insertion slices and extraction slices
133 204 339 1.7 17.4 i_slices = [slice(a, b) for a, b in zip(i_a, i_b)]
134 204 303 1.5 15.6 e_slices = [slice(a, b) for a, b in zip(e_a, e_b)]
135 # get a view onto the patch we are on
136 68 160 2.4 8.2 patch = patches[i, ...]
137 # apply the slices to map
138 68 627 9.2 32.2 patch[i_slices] = image.pixels[e_slices]
139
140 1 1 1.0 0.1 return patches
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment