[vtkusers] Linear interpolation as implemented by vtkImageReslice
David Gobbi
david.gobbi at gmail.com
Wed Sep 19 11:48:09 EDT 2007
Out of curiousity, I checked to see what the GIMP does when it expands an
image by 2.0. Turns out that it duplicates the topmost row and the leftmost
column of the image, i.e. it's new x values are [0, 0, 0.5, 1.0, 1.5, ...]
I tried ImageMagick, and it uses [0, 0.25, 0.75, 1.25, 1.75, ...] which avoids
duplication of the first row and column but which blurs sharp edges more
than the gimp does.
David
On 9/19/07, Luca Pamparana <luca.pamparana at gmail.com> wrote:
> You are fantastic. Thanks for the explanation. I will try and work out these
> values by hand using the explanation you gave me and hopefully make sense of
> the result!
>
> Thank you so much!
>
>
> Luca
>
> On 9/19/07, David Gobbi <david.gobbi at gmail.com> wrote:
> > Hi Luca,
> >
> > The equations for bilinear interpolation are easy. Let's say that you
> > want to interpolate a value at (x,y). First thing the algorithm does is
> > calculate (i,j) = (floor(x), floor(y)) to find the indices of a pixel in
> the
> > original image. Then it calculates fx = x-i and fy = y-j, and uses these
> to
> > compute interpolation weights for the four voxels surrounding (x,y),
> > so that it can give you v(x,y) which is the value of the new pixel:
> >
> > v(x,y) = (1-fx)(1-fy)*v(i,j) + (1-fx)(fy)*v(i,j+1) +
> > (fx)(1-fy)*v(i+1,j) + (fx)(fy)*v(i+1,j+1)
> >
> > The reason that your results are odd must be due to the way that (x,y)
> > is calculated. For the simple vtkImageReslice example that I gave in
> > my previous email, the x values at which the new pixel are interpolated
> are
> > x = [0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4]
> >
> > It's just my guess by looking at your numbers, that for you the x values
> are
> > x = [-0.25 , 0.25, 0.75, 1.25, 1.75, 2.25, 2.75, 3.25, 3.75, 4.25]
> >
> > I don't want to get too technical here, but both of the above sets of x
> values
> > are correct if you want to get a zoom factor of 2.0. Which of the two
> > behaviours
> > you want depends on how you want edges to be handled.
> >
> > The first behaviour (averaging the neighboring pixels) is what you want if
> > you are expanding a 5x5 image to create a 9x9 image. As for why you get
> > a 9x9 image when you do averaging like this, instead of a 10x10 image,
> > that should be obvious when you think about it.
> >
> > The second behaviour with all those 0.25's is what you use if you really
> need
> > to expand your 5x5 image into a 10x10 image. Again, let me be clear
> > on this: both of these behaviours are giving you a zoom factor of 2.0.
> > The difference lies in how you want the edges to be handled.
> >
> > So, now about edges. The edge of the image is defined as the position
> > of the center of the outermost pixels. Please note that I said the CENTER
> > of those pixels. That is how VTK defines the edge, and this is the best
> > definition in most circumstances, so please don't argue with that
> definition.
> > When vtkImageReslice needs to interpolate beyond the edge of an image,
> > (e.g. when x = -0.25) the rule that is applied is as follows
> > 1) if the distance from x to the edge is less than half of the output
> pixel
> > spacing, then x is clamped to the edge before interpolation occurs
> > 2) if the distance is greater than half of the output pixel spacing, then
> > the output pixel is set to the background color
> > 3) In vtk 4 and earlier, this "half pixel" rule doesn't apply, all
> out-of-bounds
> > pixels were set to the background value until vtk 5.0
> >
> > So let me quickly summarize: I think that your results are following
> > behaviour 2 as described above. Whether or not this is what you want,
> > well, that's up to you. As for why vtkImageReslice is giving you these
> > results, I can't tell you that unless you post your code.
> >
> > David
> >
> >
> >
> > On 9/19/07, Luca Pamparana <luca.pamparana at gmail.com> wrote:
> > > Hi David,
> > >
> > > Many many thanks for answering my question! I am really grateful.
> > >
> > > Yes, you are right I see that the number of pixels generated are
> correct.
> > > However, I am unable to figure out what the algorithms are doing to
> generate
> > > the values.
> > >
> > > For example, I created a small synthetic image (unsigned char) type with
> the
> > > following pattern. Origin is at lower left (image dimension 5 X 5):
> > >
> > > 2 3 4 5 0
> > > 3 4 5 0 1
> > > 4 5 0 1 2
> > > 5 0 1 2 3
> > > 0 1 2 3 4
> > >
> > > switched to linear interpolation with the image and on zooming by a
> factor
> > > of 2, I get the following pixel blocks:
> > >
> > > 2 2 3 3 4 4 5 4 1
> > > 0
> > > 3 3 3 4 4 4 3 2 1
> > > 1
> > > 3 3 4 4 5 4 1 0 1
> > > 1
> > > 4 4 4 4 3 2 1 1 1
> > > 2
> > > 4 4 5 4 1 0 1 1 2
> > > 2
> > > 5 4 3 2 1 1 1 2 2
> > > 3
> > > 5 4 1 0 1 1 2 2 3
> > > 3
> > > 3 2 1 1 1 2 2 3 3
> > > 4
> > > 0 0 1 1 2 2 3 3 4
> > > 4
> > > 0 0 1 1 2 2 3 3 4
> > > 4
> > >
> > > What I want to know is how this is calculated? Could you, by any chance,
> > > tell me the formula and the process as which pixels are considered when
> > > calculating the intermediate values and what happens with the edge
> pixels? I
> > > see the first two rows are exactly the same.
> > >
> > > Also, what about cubic interpolation? Is it something similar as well?
> > >
> > > I am attaching an image of the output, so you can see the pixel blocks.
> If
> > > you load it in GIMP than you can easily see each pixel and see the
> intensity
> > > value with the color picker tool...
> > >
> > > Again, I will be really grateful for all your help.
> > >
> > > Thanks,
> > >
> > > Luca
> > >
> > >
> > > On 9/19/07, David Gobbi < david.gobbi at gmail.com> wrote:
> > > > Hi Luca,
> > > >
> > > > To see how vtkImageReslice zooms an image by a factor of 2, you
> > > > should be doing something like this:
> > > >
> > > > vtkPNGReader *reader = vtkPNGReader::New();
> > > > reader->SetFileName("myfile.png");
> > > > reader->SetDataSpacing( 1.0, 1.0, 1.0); // tell VTK what pixel
> spacing to
> > > use
> > > >
> > > > vtkImageReslice *reslice = vtkImageReslice::New();
> > > > reslice->SetInput(reader->GetOutput());
> > > > reslice->SetOutputSpacing( 0.5, 0.5, 0.5); // resample with zoom
> factor of
> > > 2.0
> > > >
> > > > If you write the output of this reslice to a file, you will see
> > > > exactly what you expect, i.e. a new pixel inserted between all
> > > > the old pixels in both the vertical and horizontal directions. So if
> > > > the original image size was 100x100, the new image will be
> > > > 199x199 because 99 new pixels have been inserted in the
> > > > horizontal and vertical directions.
> > > >
> > > > Since this is not what you are seeing, then there might be something
> > > > wrong with the way you are appying the zoom factor. If you can send
> > > > a few lines of code that show how you are using vtkImageReslice, that
> > > > would help me to fully answer your question.
> > > >
> > > > Cheers,
> > > >
> > > > David
> > > >
> > > >
> > > > On 9/19/07, Luca Pamparana <luca.pamparana at gmail.com> wrote:
> > > > > Hi everyone,
> > > > >
> > > > > I had asked this question a few days back but did not receive any
> help.
> > > > > Asking it again hoping someone would answer my query!
> > > > >
> > > > > Just trying to understand the linear interpolation algorithm as
> > > implemented
> > > > > in the vtkImageReslice class. I tried looking at the source code but
> it
> > > is
> > > > >
> > > > > really complicated and I could not understand much :(
> > > > >
> > > > > Anyway, I am zooming my image by a factor of 2. The image is a
> synthetic
> > > > > image which has a thick edge going along its diagonal (the value is
> > > changing
> > > > > from 0 to 255) and I am trying to look at how the values are
> > > interpolated in
> > > > > that region.
> > > > >
> > > > >
> > > > > One thing I noticed is that there are 2 pixels being inserted in the
> > > > > horizontal direction. So, I get the values 255, 191, 64 and 0 (255
> and 0
> > > are
> > > > > the old values and the two new values are being generated by taking
> a
> > > > > weighted average). Is this correct? I thought that if I zoom by a
> factor
> > > of
> > > > >
> > > > > 2.0 than one pixel should be inserted between successive pixels. I
> am
> > > not
> > > > > sure what happens at the edge pixels though.
> > > > >
> > > > > Also, what happens in the vertical direction? I cannot really figure
> out
> > > how
> > > > > this works...
> > > > >
> > > > >
> > > > > So if I have pixel values as follows:
> > > > >
> > > > > 255 0 1 2
> > > > > 0 255 0 1
> > > > >
> > > > > How is the lienar interpolation being done on a zoom of 2.0?
> > > > >
> > > > > I would really appreciate it if someone can clarify these doubts for
> > > me....
> > > > > I have spend a lot of time trying to understand this but have not
> yet
> > > been
> > > > > able to comprehend this implementation.
> > > > >
> > > > >
> > > > > Thanks,
> > > > >
> > > > > Luca
> > > > >
> > > > > _______________________________________________
> > > > > This is the private VTK discussion list.
> > > > > Please keep messages on-topic. Check the FAQ at:
> > > > > http://www.vtk.org/Wiki/VTK_FAQ
> > > > > Follow this link to subscribe/unsubscribe:
> > > > > http://www.vtk.org/mailman/listinfo/vtkusers
> > > > >
> > > > >
> > > >
> > >
> > >
> > >
> >
>
>
More information about the vtkusers
mailing list