1717from skimage .feature import graycomatrix
1818
1919
20- def read_image (fname , colors = 256 ):
20+ def ordered_unique (seq ):
21+ return list (dict .fromkeys (seq ))
22+
23+
24+ def convert_imarray (imarray , colors = 256 ):
2125 """
22- Read an image and return an index array and colourtable.
26+ Convert an RGB image array to an index array and colourtable. The array
27+ will be quantized to the specified number of colours, and will be no larger
28+ than 512x512 pixels.
2329
2430 Args:
25- fname (str ): Path to image file, file handle, or a URL .
31+ imarray (np.ndarray ): The RGB or RGBA image array .
2632 colors (int): Number of colours to reduce to.
2733
2834 Returns:
2935 imarray (np.ndarray): Array of indices into the colourtable.
3036 unique_colors (np.ndarray): Colourtable.
3137 """
32- with fsspec .open (fname ) as f :
33- imp = Image .open (f )
34- imp = imp .quantize (colors = colors , dither = Image .NONE )
35- imp .thumbnail ((512 , 512 ))
38+ if np .min (imarray ) < 0 or np .max (imarray ) > 255 :
39+ raise ValueError ("Image array must be in the range [0, 255] or [0, 1]." )
40+ elif np .max (imarray ) <= 1.0 :
41+ imarray = imarray * 255
42+ imp = Image .fromarray (np .uint8 (imarray ))
43+ imp = imp .quantize (colors = colors , dither = Image .NONE )
44+ imp .thumbnail ((512 , 512 ))
3645 imarray = np .asarray (imp )
3746 palette = np .asarray (imp .getpalette ()).reshape (- 1 , 3 )
38- return imarray .astype (np .int16 ), palette [:colors ]/ 255
47+ unique = ordered_unique (tuple (i ) for i in palette [:colors ]/ 255 )
48+ return imarray , np .array (unique )
3949
4050
4151def construct_graph (imarray , colors = 256 , normed = True ):
@@ -219,7 +229,7 @@ def path_to_cmap(path, unique_colors, colors=256, reverse='auto', equilibrate=Fa
219229 return cmap
220230
221231
222- def guess_cmap ( fname ,
232+ def guess_cmap_from_array ( array ,
223233 source_colors = 256 ,
224234 target_colors = 256 ,
225235 min_weight = 0.025 ,
@@ -232,7 +242,7 @@ def guess_cmap(fname,
232242 Guess the colormap of an image.
233243
234244 Args:
235- fname (str ): Filename or URL of image to guess .
245+ array (np.ndarray ): The RGB or RGBA image array .
236246 source_colors (int): Number of colours to detect in the source image.
237247 target_colors (int): Number of colours to return in the colormap.
238248 min_weight (float): Minimum weight to keep. See `prune_graph`.
@@ -243,8 +253,45 @@ def guess_cmap(fname,
243253 the direction is essentially random.
244254
245255 """
246- imarray , uniq = read_image ( fname , colors = source_colors )
256+ imarray , uniq = convert_imarray ( array , colors = source_colors )
247257 G = construct_graph (imarray , colors = source_colors )
248258 G0 = prune_graph (G , uniq , min_weight = min_weight , max_dist = max_dist , max_neighbours = max_neighbours )
249259 path = longest_shortest_path (G0 )
250260 return path_to_cmap (path , uniq , colors = target_colors , reverse = reverse , equilibrate = equilibrate )
261+
262+
263+ def guess_cmap_from_image (fname ,
264+ source_colors = 256 ,
265+ target_colors = 256 ,
266+ min_weight = 0.025 ,
267+ max_dist = 0.25 ,
268+ max_neighbours = 20 ,
269+ reverse = 'auto' ,
270+ equilibrate = False
271+ ):
272+ """
273+ Guess the colormap of an image.
274+
275+ Args:
276+ fname (str): Filename or URL of image to guess.
277+ source_colors (int): Number of colours to detect in the source image.
278+ target_colors (int): Number of colours to return in the colormap.
279+ min_weight (float): Minimum weight to keep. See `prune_graph`.
280+ max_dist (float): Maximum distance to keep. See `prune_graph`.
281+ max_neighbours (int): Maximum number of neighbours to allow. See `prune_graph`.
282+ reverse (bool): Whether to reverse the colormap. If 'auto', the
283+ colormap will start with the end closest to dark blue. If False,
284+ the direction is essentially random.
285+
286+ """
287+ with fsspec .open (fname ) as f :
288+ img = Image .open (f )
289+ return guess_cmap_from_array (np .asarray (img ),
290+ source_colors = source_colors ,
291+ target_colors = target_colors ,
292+ min_weight = min_weight ,
293+ max_dist = max_dist ,
294+ max_neighbours = max_neighbours ,
295+ reverse = reverse ,
296+ equilibrate = equilibrate
297+ )
0 commit comments