Skip to content

Commit 4ebfdbf

Browse files
authored
Merge pull request #18 from BerkeleyAutomation/remove-scipy-im-ops
Remove dependency on scipy.misc image ops.
2 parents bf1a5c8 + 85b52ca commit 4ebfdbf

1 file changed

Lines changed: 65 additions & 10 deletions

File tree

perception/image.py

Lines changed: 65 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
import numpy as np
1414
import PIL.Image as PImage
1515

16-
import scipy.misc as sm
1716
import scipy.signal as ssg
1817
import scipy.ndimage.filters as sf
1918
import scipy.ndimage.interpolation as sni
@@ -26,6 +25,7 @@
2625
import scipy.ndimage.filters as sf
2726
import scipy.spatial.distance as ssd
2827
import skimage.morphology as morph
28+
import skimage.transform as skt
2929
import scipy.ndimage.morphology as snm
3030

3131
from autolab_core import PointCloud, NormalCloud, PointNormalCloud, Box, Contour
@@ -35,6 +35,61 @@
3535
BINARY_IM_DEFAULT_THRESH = BINARY_IM_MAX_VAL / 2
3636

3737

38+
def imresize(image, size, interp="nearest"):
39+
"""Wrapper over `skimage.transform.resize` to mimic `scipy.misc.imresize`.
40+
41+
Since `scipy.misc.imresize` has been removed in version 1.3.*, instead use
42+
`skimage.transform.resize`. The "lanczos" and "cubic" interpolation methods
43+
are not supported by `skimage.transform.resize`, however there is now
44+
"biquadratic", "biquartic", and "biquintic".
45+
46+
Parameters
47+
----------
48+
image : :obj:`numpy.ndarray`
49+
The image to resize.
50+
51+
size : int, float, or tuple
52+
* int - Percentage of current size.
53+
* float - Fraction of current size.
54+
* tuple - Size of the output image.
55+
56+
interp : :obj:`str`, optional
57+
Interpolation to use for re-sizing ("neartest", "bilinear",
58+
"biquadratic", "bicubic", "biquartic", "biquintic"). Default is
59+
"nearest".
60+
61+
Returns
62+
-------
63+
:obj:`np.ndarray`
64+
The resized image.
65+
"""
66+
skt_interp_map = {"nearest": 0, "bilinear": 1, "biquadratic": 2,
67+
"bicubic": 3, "biquartic": 4, "biquintic": 5}
68+
if interp in ("lanczos", "cubic"):
69+
raise ValueError("\"lanczos\" and \"cubic\""
70+
" interpolation are no longer supported.")
71+
assert interp in skt_interp_map, ("Interpolation \"{}\" not"
72+
" supported.".format(interp))
73+
74+
if isinstance(size, (tuple, list)):
75+
output_shape = size
76+
elif isinstance(size, (float)):
77+
np_shape = np.asarray(image.shape).astype(np.float32)
78+
np_shape[0:2] *= size
79+
output_shape = tuple(np_shape.astype(int))
80+
elif isinstance(size, (int)):
81+
np_shape = np.asarray(image.shape).astype(np.float32)
82+
np_shape[0:2] *= size / 100.0
83+
output_shape = tuple(np_shape.astype(int))
84+
else:
85+
raise ValueError("Invalid type for size \"{}\".".format(type(size)))
86+
87+
return skt.resize(image,
88+
output_shape,
89+
order=skt_interp_map[interp],
90+
anti_aliasing=False,
91+
mode="constant")
92+
3893
class Image(object):
3994
"""Abstract wrapper class for images.
4095
"""
@@ -1074,7 +1129,7 @@ def resize(self, size, interp='bilinear'):
10741129
:obj:`ColorImage`
10751130
The resized image.
10761131
"""
1077-
resized_data = sm.imresize(self.data, size, interp=interp)
1132+
resized_data = imresize(self.data, size, interp=interp).astype(np.uint8)
10781133
return ColorImage(resized_data, self._frame)
10791134

10801135
def find_chessboard(self, sx=6, sy=9):
@@ -1572,7 +1627,7 @@ def resize(self, size, interp='bilinear'):
15721627
:obj:`DepthImage`
15731628
The resized image.
15741629
"""
1575-
resized_data = sm.imresize(self.data, size, interp=interp, mode='F')
1630+
resized_data = imresize(self.data, size, interp=interp).astype(np.float32)
15761631
return DepthImage(resized_data, self._frame)
15771632

15781633
def threshold(self, front_thresh=0.0, rear_thresh=100.0):
@@ -1954,7 +2009,7 @@ def resize(self, size, interp='bilinear'):
19542009
:obj:`IrImage`
19552010
The resized image.
19562011
"""
1957-
resized_data = sm.imresize(self._data, size, interp=interp)
2012+
resized_data = imresize(self._data, size, interp=interp).astype(np.uint16)
19582013
return IrImage(resized_data, self._frame)
19592014

19602015
@staticmethod
@@ -2060,7 +2115,7 @@ def resize(self, size, interp='bilinear'):
20602115
:obj:`GrayscaleImage`
20612116
The resized image.
20622117
"""
2063-
resized_data = sm.imresize(self.data, size, interp=interp)
2118+
resized_data = imresize(self.data, size, interp=interp).astype(np.uint8)
20642119
return GrayscaleImage(resized_data, self._frame)
20652120

20662121
def to_color(self):
@@ -2185,7 +2240,7 @@ def resize(self, size, interp='bilinear'):
21852240
:obj:`BinaryImage`
21862241
The resized image.
21872242
"""
2188-
resized_data = sm.imresize(self.data, size, interp=interp)
2243+
resized_data = imresize(self.data, size, interp=interp).astype(np.uint8)
21892244
return BinaryImage(resized_data, self._frame)
21902245

21912246
def mask_binary(self, binary_im):
@@ -3311,7 +3366,7 @@ def resize(self, size, interp='nearest'):
33113366
Interpolation to use for re-sizing ('nearest', 'lanczos', 'bilinear',
33123367
'bicubic', or 'cubic')
33133368
"""
3314-
resized_data = sm.imresize(self.data, size, interp=interp, mode='L')
3369+
resized_data = imresize(self.data, size, interp=interp).astype(np.uint8)
33153370
return SegmentationImage(resized_data, self._frame)
33163371

33173372
@staticmethod
@@ -3397,9 +3452,9 @@ def resize(self, size, interp='nearest'):
33973452
:obj:`PointCloudImage`
33983453
The resized image.
33993454
"""
3400-
resized_data_0 = sm.imresize(self._data[:,:,0], size, interp=interp, mode='F')
3401-
resized_data_1 = sm.imresize(self._data[:,:,1], size, interp=interp, mode='F')
3402-
resized_data_2 = sm.imresize(self._data[:,:,2], size, interp=interp, mode='F')
3455+
resized_data_0 = imresize(self._data[:,:,0], size, interp=interp).astype(np.float32)
3456+
resized_data_1 = imresize(self._data[:,:,1], size, interp=interp).astype(np.float32)
3457+
resized_data_2 = imresize(self._data[:,:,2], size, interp=interp).astype(np.float32)
34033458
resized_data = np.zeros([resized_data_0.shape[0],
34043459
resized_data_0.shape[1],
34053460
self.channels])

0 commit comments

Comments
 (0)