Convenience wrapper around `._image.resample` to resample *data* to *out_shape* (with a third dimension if *data* is RGBA) that takes care of allocating the output array and fetching the relevant properties from the Image object *image_obj*.
(
image_obj, data, out_shape, transform, *, resample=None, alpha=1)
| 160 | |
| 161 | |
| 162 | def _resample( |
| 163 | image_obj, data, out_shape, transform, *, resample=None, alpha=1): |
| 164 | """ |
| 165 | Convenience wrapper around `._image.resample` to resample *data* to |
| 166 | *out_shape* (with a third dimension if *data* is RGBA) that takes care of |
| 167 | allocating the output array and fetching the relevant properties from the |
| 168 | Image object *image_obj*. |
| 169 | """ |
| 170 | # AGG can only handle coordinates smaller than 24-bit signed integers, |
| 171 | # so raise errors if the input data is larger than _image.resample can |
| 172 | # handle. |
| 173 | msg = ('Data with more than {n} cannot be accurately displayed. ' |
| 174 | 'Downsampling to less than {n} before displaying. ' |
| 175 | 'To remove this warning, manually downsample your data.') |
| 176 | if data.shape[1] > 2**23: |
| 177 | warnings.warn(msg.format(n='2**23 columns')) |
| 178 | step = int(np.ceil(data.shape[1] / 2**23)) |
| 179 | data = data[:, ::step] |
| 180 | transform = Affine2D().scale(step, 1) + transform |
| 181 | if data.shape[0] > 2**24: |
| 182 | warnings.warn(msg.format(n='2**24 rows')) |
| 183 | step = int(np.ceil(data.shape[0] / 2**24)) |
| 184 | data = data[::step, :] |
| 185 | transform = Affine2D().scale(1, step) + transform |
| 186 | # decide if we need to apply anti-aliasing if the data is upsampled: |
| 187 | # compare the number of displayed pixels to the number of |
| 188 | # the data pixels. |
| 189 | interpolation = image_obj.get_interpolation() |
| 190 | if interpolation in ['antialiased', 'auto']: |
| 191 | # don't antialias if upsampling by an integer number or |
| 192 | # if zooming in more than a factor of 3 |
| 193 | pos = np.array([[0, 0], [data.shape[1], data.shape[0]]]) |
| 194 | disp = transform.transform(pos) |
| 195 | dispx = np.abs(np.diff(disp[:, 0])) |
| 196 | dispy = np.abs(np.diff(disp[:, 1])) |
| 197 | if ((dispx > 3 * data.shape[1] or |
| 198 | dispx == data.shape[1] or |
| 199 | dispx == 2 * data.shape[1]) and |
| 200 | (dispy > 3 * data.shape[0] or |
| 201 | dispy == data.shape[0] or |
| 202 | dispy == 2 * data.shape[0])): |
| 203 | interpolation = 'nearest' |
| 204 | else: |
| 205 | interpolation = 'hanning' |
| 206 | out = np.zeros(out_shape + data.shape[2:], data.dtype) # 2D->2D, 3D->3D. |
| 207 | if resample is None: |
| 208 | resample = image_obj.get_resample() |
| 209 | |
| 210 | # When an output pixel falls exactly on the edge between two input pixels, the Agg |
| 211 | # resampler will use the right input pixel as the nearest neighbor. We want the |
| 212 | # left input pixel to be chosen instead, so we flip the input data and the supplied |
| 213 | # transform. If origin != 'upper', the transform will already include a flip in the |
| 214 | # vertical direction. |
| 215 | if interpolation == 'nearest': |
| 216 | transform = Affine2D().translate(-data.shape[1], 0).scale(-1, 1) + transform |
| 217 | data = np.flip(data, axis=1) |
| 218 | if image_obj.origin == 'upper': |
| 219 | transform = Affine2D().translate(0, -data.shape[0]).scale(1, -1) + transform |
no test coverage detected
searching dependent graphs…