[Numpy-discussion] collecting the bluest pixels

Anne Archibald peridot.faceted at gmail.com
Tue Oct 7 15:30:44 EDT 2008


2008/10/7 paul taney <paultaney at yahoo.com>:
> Hi,
>
> I have this silly color filter that Stefan gave me:
>
>
> def vanderwalt(image, f):
>    """colorfilter, thanks to Stefan van der Walt"""
>    RED, GRN, BLU = 0, 1, 2
>    bluemask = (image[...,BLU] > f*image[...,GRN]) & \
>               (image[...,BLU] > f*image[...,RED])
>
>    return bluemask
>
>
> To collect the right number of the bluest pixels I am calling it from this arduous successive approximation routine.  It occured to me that someone on this list knows how to do this in a couple of lines...

Well, I can see several approaches. The most direct way to do what
you're asking is to use scipy.optimize.bisect to implement the
successive approximations. That'll be almost as slow as your current
approach, though. Instead, I'd first write a function that measures
the "blueness" of each pixel:

def blueness(image):
      A = np.empty(image.shape[:-1],dtype=np.float32)
      np.divide(image[...,BLU],image[...,RED],A) # use three-argument
divide to reduce the number of float temporaries
      B = np.empty(image.shape[:-1],dtype=np.float32)
      np.divide(image[...,BLU],image[...,GRN],B)
      return np.minimum(A,B)

Now, once you have the bluenesses, you can sort them and pull out the
blueness that gives you the percent you want:

bluenesses = np.sort(blueness(image),axis=None) # axis=None flattens the array
factor = bluenesses[int((1-wanted_fraction)*len(bluenesses))]

If you want a smarter blueness filter, you could look into using HSV:
you could then specify a distance in hue and a distance in saturation,
based on how relatively important you think they are.

Anne



More information about the NumPy-Discussion mailing list