astropy / imageutils

Image processing utilities for Astropy (No longer maintained)
https://imageutils.readthedocs.org/
9 stars 17 forks source link

downsample does not accept dtype=int #43

Open barentsen opened 9 years ago

barentsen commented 9 years ago

It looks like downsample does not accept an array with dtype=int. Given that many images are stored as ints, it would be nice if it did?

In [1]: import numpy as np
In [2]: from imageutils import downsample
In [3]: img = np.array([[1, 2], [3, 4]])
In [4]: downsample(img, 2)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-4-fd13e25e043f> in <module>()
----> 1 downsample(img, 2)

/home/gb/bin/anaconda/lib/python2.7/site-packages/imageutils-0.0.dev110-py2.7-linux-x86_64.egg/imageutils/sampling.so in imageutils.sampling.downsample (imageutils/sampling.c:1298)()

ValueError: Buffer dtype mismatch, expected 'DTYPE_t' but got 'long'

Of course this works fine:

In [5]: downsample(img.astype(np.double), 2)
Out[5]: array([[ 10.]])
cdeil commented 9 years ago

imageutils has been merged into Astropy core in https://github.com/astropy/astropy/pull/3201 but apparently the downsample function wasn't ... as far as I can see it's currently not in Astropy core or photutils!?

@astrofrog @larrybradley Do we want to provide the downsample function? Do you think there's still a need for imageutils or should all functionality go into Astropy core or photutils directly from now on?

larrybradley commented 9 years ago

@barentsen downsample/upsample are Cython functions, which require strict data typing (here data must be a float64). I think allowing other types would require a python wrapper around the Cython function to recast the data type (or perhaps this could be done within the Cython code?).

@cdeil I think these functions weren't added to astropy because there is a way to do this (downsample/upsample) using numpy broadcasting tricks (although that method is a bit slower). I'll have to go back through the long comments on that PR to refresh my memory.

larrybradley commented 9 years ago

Here is a one-line equivalent of downsample:

data.reshape(data.shape[0] / factor, factor, data.shape[1] / factor, factor).sum(axis=(1, 3))

However, it will work only when the data shape is an exact multiple of factor. I think(?) the imageutils.downsample function would handle this (essentially by trimming the data).

barentsen commented 9 years ago

The numpy one-liner is perhaps somewhat obscure -- I didn't think of it. I'd say the act of binning data is common enough to deserve a user-friendly function in astropy?

larrybradley commented 9 years ago

I agree (the one-line equivalent of upsample is even more obscure). I'll submit an astropy PR with the numpy one-line versions of both downsample and upsample (and adding the automatic trimming, if necessary).

astrofrog commented 9 years ago

Here is a version that works including the trimming of the data:

def downsample(image, factor):
    nx_new = image.shape[1] // factor
    ny_new = image.shape[0] // factor
    nx_init = nx_new * factor
    ny_init = ny_new * factor
    return (image[:ny_init, :nx_init]
            .reshape((ny_new, factor, nx_new, factor))
            .mean(axis=3).mean(axis=1))
larrybradley commented 9 years ago

astropy PR is here: https://github.com/astropy/astropy/pull/3453