Neat!

The easiest way to share this with others would be to submit a pull request to 
Images using Pkg.submit("Images"). There are a couple of things that could be 
done pretty easily to generalize this, and we could punt on anything hard---
better to have an implementation that works for many types. We could discuss 
them if you decide to move forward.

Best,
--Tim

On Sunday, August 03, 2014 04:34:18 PM Andrei wrote:
> For those looking for the same thing, below is my simple implementation. It
> uses bilinear interpolation and works with 2D arrays of Real-s and
> Integer-s (tested on Uint8 matrices mostly). Usage example:
> 
>  using Images
>  using ImageView
>  im = imread("...")
>  dat = convert(Array, im)   # say, dat is a Matrix of size (256, 256)
>  new_dat = imresize(dat, 128, 128)
>  view(new_dat)
> 
> Resizing from (256, 256) to (128, 128) takes ~1.5ms on my machine, while
> resizing same (256, 256) image to (512, 512) takes as long as ~60ms. So
> it's definitely not high-performance implementation, but it does its work
> and handles most frequent use cases.
> 
> ---------------------------
> 
> # interpolate point at (x, y) from 4 nearby pixel values
> function interp_bilinear{T <: Union(Real, Integer)}(dat::Array{T, 2},
>                                                     x::Float64, y::Float64,
>                                                     x1, x2, y1, y2)
>     q11 = dat[y1, x1]
>     q12 = dat[y2, x1]
>     q21 = dat[y1, x2]
>     q22 = dat[y2, x2]
>     if x1 != x2
>         r1 = (x2 - x) / (x2 - x1) * q11 + (x - x1) / (x2 - x1) * q21
>         r2 = (x2 - x) / (x2 - x1) * q12 + (x - x1) / (x2 - x1) * q22
>     else
>         # special case of x1 == x2, no interpolation needed
>         r1 = q11
>         r2 = q12
>     end
>     if y1 != y2
>         r = (y - y1) / (y2 - y1) * r1 + (y2 - y) / (y2 - y1) * r2
>     else
>         # special case of y1 == y2, no interpolation needed
>         r = r1
>     end
>     if typeof(r) <: Real
>         r = round(r)
>     end
>     r = convert(T, r)
>     return r
> end
> 
> 
> function imresize{T <: Union(Real, Integer)}(dat::Array{T, 2},
>                                              new_size::(Int, Int))
>     new_dat = similar(dat, new_size)
>     h, w = size(dat)
>     new_h, new_w = new_size
>     for new_j=1:new_w, new_i=1:new_h
>         # coordinates in original image
>         x = new_j * w / new_w
>         y = new_i * h / new_h
>         # coordinates of 4 points to interpolate from
>         x1, x2 = max(1, floor(x)), min(w, ceil(x))
>         y1, y2 = max(1, floor(y)), min(h, ceil(y))
>         new_dat[new_i, new_j] = interp_bilinear(dat, x, y, x1, x2, y1, y2)
>     end
>     return new_dat
> end
> 
> 
> function imresize{T <: Union(Real, Integer)}(dat::Array{T, 2},
>                                              new_size...)
>     return imresize(dat, new_size)
> end
> 
> ---------------
> 
> 
> 
> On Wed, Jul 30, 2014 at 1:14 AM, Andrei Zh <[email protected]>
> 
> wrote:
> > ...and Ron, Kevin, Lucas, etc ...
> > 
> > 
> > Surely, I'm just referring to someone I see on the mailing list very often
> > 
> > :)
> > 
> > Yeah, it's a pretty obvious omission, but to be truthful it's never come
> > 
> >> up
> >> for me so I've never implemented it. I will get to it eventually, but in
> >> the
> >> meantime if you need it soon it might be worth considering putting
> >> something
> >> together yourself. If you use Grid to do it (+ smoothing with imfilter or
> >> imfilter_gaussian if you're downsizing and don't want aliasing), it
> >> shouldn't
> >> be more than 20 lines or so. But there are other approaches, see
> >> http://stackoverflow.com/questions/384991/what-is-the-> >> 
> >> best-image-downscaling-algorithm-quality-wise
> >> which might involve more effort but also yield higher quality/speed.
> > 
> > I'm not so concerned about high quality, so I think I will dive into your
> > code and maybe come up with a general solution.

Reply via email to