Example #1
0
def histogram(source, selem=None, sink=None, mask=None, max_bin=None):
    """Normalized sliding window histogram

    Arguments
    ---------
    source : array
      Input array.
    selem : array
      Structure element. If None, use a cube of size 3.
    sink : array
      Output array. If None, a new array is allocated.
    mask : array
      Optional mask, if None, the complete source is used.
      Pixels on the mask are zero in the output.
    max_bin : int or None
      Maximal number of bins.

    Returns
    -------
    sink : array
      Array of the source shape pluse on extra dimension for the histogram
      at each pixel.
    """

    if max_bin is None:
        max_bin = io.max_value(source.dtype)
    if max_bin >= 2**16:
        raise ValueError(
            'The histograms are to large for this code to be efficient!')
    parameter_index = [max_bin]

    return _apply_code(code.histogram,
                       code.histogram_masked,
                       max_bin=max_bin,
                       sink_shape_per_pixel=(max_bin, ),
                       sink_dtype=float,
                       source=source,
                       selem=selem,
                       sink=sink,
                       mask=mask,
                       parameter_index=parameter_index)
Example #2
0
def _apply_code(function,
                function_mask,
                source,
                selem=None,
                sink=None,
                sink_dtype=None,
                sink_shape_per_pixel=None,
                mask=None,
                max_bin=None,
                parameter_index=None,
                parameter_float=None):
    """Helper to apply code."""
    selem = _initialize_selem(selem, source.ndim)

    if source.ndim > 3:
        raise ValueError('Source dimension %d not supported!' % source.ndim)
    if source.ndim != 3:
        source = np.asarray(source)
        shape_remove = [d for d in range(source.ndim, 3)]
        source = source.view()
        source.shape = source.shape + (1, ) * (3 - source.ndim)
        if mask is not None:
            mask = np.asarray(mask)
            mask = mask.view()
            mask.shape = mask.shape + (1, ) * (3 - mask.ndim)
        selem = selem.view()
        selem.shape = selem.shape + (1, ) * (3 - selem.ndim)
    else:
        shape_remove = []

    if source.dtype not in (np.uint8, np.uint16, np.int, np.int16, np.int32,
                            np.int64, np.uint32, np.uint64, np.bool):
        raise ValueError(
            'The rank filter requires a source of integer type, found %r!' %
            source.dtype)

    if mask is not None:
        if mask.dtype == bool:
            mask = mask.view('uint8')
        if mask.shape != source.shape:
            raise ValueError(
                'Source shape %r and mask shape %r do not match!' %
                (source.shape, mask.shape))

    if source is sink:
        raise ValueError("Cannot perform rank filter in place!")

    if sink_shape_per_pixel is None:
        shape_per_pixel = (1, )
        shape_remove += [3]
    else:
        shape_per_pixel = sink_shape_per_pixel

    if sink is None:
        if sink_dtype is None:
            sink_dtype = source.dtype
        sink = np.zeros(source.shape + shape_per_pixel, dtype=sink_dtype)
    else:
        if shape_per_pixel != (1, ):
            if sink.shape != source.shape + shape_per_pixel:
                raise ValueError(
                    'The sink of shape %r does not have expected shape %r!' %
                    (sink.shape, source.shape + shape_per_pixel))
        if sink.shape != source.shape + shape_per_pixel:
            sink = sink.reshape(source.shape + shape_per_pixel)

    if sink.dtype == bool:
        s = sink.view('uint8')
    else:
        s = sink

    if max_bin is None:
        max_bin = io.max_value(source.dtype)
    if max_bin >= 2**16:
        raise ValueError(
            'The histograms are to large for this code to be efficient!')

    bitdepth = int(np.log2(max_bin))
    if bitdepth > 12:
        warnings.warn(
            "Bitdepth of %d may result in bad rank filter performance." %
            bitdepth)

    if parameter_index is None:
        parameter_index = np.zeros(0, dtype=int)
    parameter_index = np.asarray([parameter_index], dtype=int).flatten()

    if parameter_float is None:
        parameter_float = np.zeros(0, dtype=float)
    parameter_float = np.asarray([parameter_float], dtype=float).flatten()

    #print(source.__class__, source.dtype, s.__class__, s.dtype, selem.dtype, mask.dtype, max_bin)

    if mask is None:
        function(source=source,
                 selem=selem,
                 sink=s,
                 max_bin=max_bin,
                 p=parameter_index,
                 q=parameter_float)
    else:
        function_mask(source=source,
                      selem=selem,
                      mask=mask,
                      sink=s,
                      max_bin=max_bin,
                      p=parameter_index,
                      q=parameter_float)

    if len(shape_remove) > 0:
        shape = tuple(s for d, s in enumerate(sink.shape)
                      if d not in shape_remove)
        sink = sink.reshape(shape)

    return sink