[vtkusers] Linear interpolation as implemented by vtkImageReslice

David Gobbi david.gobbi at gmail.com
Wed Sep 19 10:42:19 EDT 2007


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