@@ -1236,39 +1236,98 @@ def inverse(self, value):
12361236
12371237def rgb_to_hsv (arr ):
12381238 """
1239- convert rgb values in a numpy array to hsv values
1240- input and output arrays should have shape (M,N,3)
1239+ convert float rgb values (in the range [0, 1]), in a numpy array to hsv
1240+ values.
1241+
1242+ Parameters
1243+ ----------
1244+ arr : (..., 3) array-like
1245+ All values must be in the range [0, 1]
1246+
1247+ Returns
1248+ -------
1249+ hsv : (..., 3) ndarray
1250+ Colors converted to hsv values in range [0, 1]
12411251 """
1242- out = np .zeros (arr .shape , dtype = np .float )
1252+ # make sure it is an ndarray
1253+ arr = np .asarray (arr )
1254+
1255+ # check length of the last dimension, should be _some_ sort of rgb
1256+ if arr .shape [- 1 ] != 3 :
1257+ raise ValueError ("Last dimension of input array must be 3; "
1258+ "shape {shp} was found." .format (shp = arr .shape ))
1259+
1260+ in_ndim = arr .ndim
1261+ if arr .ndim == 1 :
1262+ arr = np .array (arr , ndmin = 2 )
1263+
1264+ # make sure we don't have an int image
1265+ if arr .dtype .kind in ('iu' ):
1266+ arr = arr .astype (np .float32 )
1267+
1268+ out = np .zeros_like (arr )
12431269 arr_max = arr .max (- 1 )
12441270 ipos = arr_max > 0
12451271 delta = arr .ptp (- 1 )
12461272 s = np .zeros_like (delta )
12471273 s [ipos ] = delta [ipos ] / arr_max [ipos ]
12481274 ipos = delta > 0
12491275 # red is max
1250- idx = (arr [:, : , 0 ] == arr_max ) & ipos
1276+ idx = (arr [... , 0 ] == arr_max ) & ipos
12511277 out [idx , 0 ] = (arr [idx , 1 ] - arr [idx , 2 ]) / delta [idx ]
12521278 # green is max
1253- idx = (arr [:, : , 1 ] == arr_max ) & ipos
1279+ idx = (arr [... , 1 ] == arr_max ) & ipos
12541280 out [idx , 0 ] = 2. + (arr [idx , 2 ] - arr [idx , 0 ]) / delta [idx ]
12551281 # blue is max
1256- idx = (arr [:, : , 2 ] == arr_max ) & ipos
1282+ idx = (arr [... , 2 ] == arr_max ) & ipos
12571283 out [idx , 0 ] = 4. + (arr [idx , 0 ] - arr [idx , 1 ]) / delta [idx ]
1258- out [:, :, 0 ] = (out [:, :, 0 ] / 6.0 ) % 1.0
1259- out [:, :, 1 ] = s
1260- out [:, :, 2 ] = arr_max
1284+
1285+ out [..., 0 ] = (out [..., 0 ] / 6.0 ) % 1.0
1286+ out [..., 1 ] = s
1287+ out [..., 2 ] = arr_max
1288+
1289+ if in_ndim == 1 :
1290+ out .shape = (3 ,)
1291+
12611292 return out
12621293
12631294
12641295def hsv_to_rgb (hsv ):
12651296 """
12661297 convert hsv values in a numpy array to rgb values
1267- both input and output arrays have shape (M,N,3)
1298+ all values assumed to be in range [0, 1]
1299+
1300+ Parameters
1301+ ----------
1302+ hsv : (..., 3) array-like
1303+ All values assumed to be in range [0, 1]
1304+
1305+ Returns
1306+ -------
1307+ rgb : (..., 3) ndarray
1308+ Colors converted to RGB values in range [0, 1]
12681309 """
1269- h = hsv [:, :, 0 ]
1270- s = hsv [:, :, 1 ]
1271- v = hsv [:, :, 2 ]
1310+ # make sure it is an ndarray
1311+ hsv = np .asarray (hsv )
1312+
1313+ # check length of the last dimension, should be _some_ sort of rgb
1314+ if hsv .shape [- 1 ] != 3 :
1315+ raise ValueError ("Last dimension of input array must be 3; "
1316+ "shape {shp} was found." .format (shp = hsv .shape ))
1317+
1318+ # if we got pased a 1D array, try to treat as
1319+ # a single color and reshape as needed
1320+ in_ndim = hsv .ndim
1321+ if in_ndim == 1 :
1322+ hsv = np .array (hsv , ndmin = 2 )
1323+
1324+ # make sure we don't have an int image
1325+ if hsv .dtype .kind in ('iu' ):
1326+ hsv = hsv .astype (np .float32 )
1327+
1328+ h = hsv [..., 0 ]
1329+ s = hsv [..., 1 ]
1330+ v = hsv [..., 2 ]
12721331
12731332 r = np .empty_like (h )
12741333 g = np .empty_like (h )
@@ -1316,9 +1375,13 @@ def hsv_to_rgb(hsv):
13161375 b [idx ] = v [idx ]
13171376
13181377 rgb = np .empty_like (hsv )
1319- rgb [:, :, 0 ] = r
1320- rgb [:, :, 1 ] = g
1321- rgb [:, :, 2 ] = b
1378+ rgb [..., 0 ] = r
1379+ rgb [..., 1 ] = g
1380+ rgb [..., 2 ] = b
1381+
1382+ if in_ndim == 1 :
1383+ rgb .shape = (3 , )
1384+
13221385 return rgb
13231386
13241387
0 commit comments