60 lines
2.0 KiB
Python
60 lines
2.0 KiB
Python
"""rankorder.py - convert an image of any type to an image of ints whose
|
|
pixels have an identical rank order compared to the original image
|
|
|
|
Originally part of CellProfiler, code licensed under both GPL and BSD licenses.
|
|
Website: http://www.cellprofiler.org
|
|
Copyright (c) 2003-2009 Massachusetts Institute of Technology
|
|
Copyright (c) 2009-2011 Broad Institute
|
|
All rights reserved.
|
|
Original author: Lee Kamentstky
|
|
"""
|
|
import numpy as np
|
|
|
|
|
|
def rank_order(image):
|
|
"""Return an image of the same shape where each pixel is the
|
|
index of the pixel value in the ascending order of the unique
|
|
values of ``image``, aka the rank-order value.
|
|
|
|
Parameters
|
|
----------
|
|
image : ndarray
|
|
|
|
Returns
|
|
-------
|
|
labels : ndarray of type np.uint32, of shape image.shape
|
|
New array where each pixel has the rank-order value of the
|
|
corresponding pixel in ``image``. Pixel values are between 0 and
|
|
n - 1, where n is the number of distinct unique values in
|
|
``image``.
|
|
original_values : 1-D ndarray
|
|
Unique original values of ``image``
|
|
|
|
Examples
|
|
--------
|
|
>>> a = np.array([[1, 4, 5], [4, 4, 1], [5, 1, 1]])
|
|
>>> a
|
|
array([[1, 4, 5],
|
|
[4, 4, 1],
|
|
[5, 1, 1]])
|
|
>>> rank_order(a)
|
|
(array([[0, 1, 2],
|
|
[1, 1, 0],
|
|
[2, 0, 0]], dtype=uint32), array([1, 4, 5]))
|
|
>>> b = np.array([-1., 2.5, 3.1, 2.5])
|
|
>>> rank_order(b)
|
|
(array([0, 1, 2, 1], dtype=uint32), array([-1. , 2.5, 3.1]))
|
|
"""
|
|
flat_image = image.ravel()
|
|
sort_order = flat_image.argsort().astype(np.uint32)
|
|
flat_image = flat_image[sort_order]
|
|
sort_rank = np.zeros_like(sort_order)
|
|
is_different = flat_image[:-1] != flat_image[1:]
|
|
np.cumsum(is_different, out=sort_rank[1:])
|
|
original_values = np.zeros((sort_rank[-1] + 1,), image.dtype)
|
|
original_values[0] = flat_image[0]
|
|
original_values[1:] = flat_image[1:][is_different]
|
|
int_image = np.zeros_like(sort_order)
|
|
int_image[sort_order] = sort_rank
|
|
return (int_image.reshape(image.shape), original_values)
|