In article <20030923160858147-0400@nntp.mgh.harvard.edu>,
Eric Raas <foo@bar.net> wrote:
> >
> > Are you using Cocoa for convenience or is your end goal to make a
> > standalone program? If it's convenience then you might consider
> > trying another viewing program such as GraphicConverter? It provides
> > plenty of options for upsampling the original. Matlab (and the image
> > processing toolbox) is another alternative.
> >
>
> Thanks - you are right in that the replication of the original image
> that is interleaved into the sinc interpolation is shifted - by 1/4
> pixel for 2x oversampling (I think our postings crossed).
>
> I am building a standalong application - overall I've found the current
> version of Cocoa to be good for image display (and it has worked very
> well for my current app in general). GraphicConverter is a great
> program - and I do a lot of my algorithm development and proof of
> concept in Matlab. My Cocoa program is actually a reimplementation of a
> Matlab program that just got too big to be managable in Matlab. I am
> also getting great performance using vectorized DSP stuff on the Mac (
> although in other posts I've complained about the documentation...)
>
> ER
I'm glad things are OK. (Note: I tend to think of replication as
causing the 1/2 pixel shift, not the other way around.)
BTW, those vector libraries were written in part by Mercury computer and
based on their SAL library.
Ken P.
--
Remove _me_ for e-mail address
Reply by Eric Raas●September 23, 20032003-09-23
>
> Are you using Cocoa for convenience or is your end goal to make a
> standalone program? If it's convenience then you might consider
> trying another viewing program such as GraphicConverter? It provides
> plenty of options for upsampling the original. Matlab (and the image
> processing toolbox) is another alternative.
>
Thanks - you are right in that the replication of the original image
that is interleaved into the sinc interpolation is shifted - by 1/4
pixel for 2x oversampling (I think our postings crossed).
I am building a standalong application - overall I've found the current
version of Cocoa to be good for image display (and it has worked very
well for my current app in general). GraphicConverter is a great
program - and I do a lot of my algorithm development and proof of
concept in Matlab. My Cocoa program is actually a reimplementation of a
Matlab program that just got too big to be managable in Matlab. I am
also getting great performance using vectorized DSP stuff on the Mac (
although in other posts I've complained about the documentation...)
ER
Reply by Eric Raas●September 23, 20032003-09-23
...
>
> I guess that if my image shifts, that means I am effectively convolving
> it with a shifted sinc function, which means I'm multiplying the 2D FFT
> data with a phase-modulated rect function (i.e. somehow disturbing the
> phase of the original data). I don't see how just zero-padding could do
> that though.
...
D'oh!! Just realized the reason for this shift is painfully obvious.
Sinc interpolation (say oversampling by a factor of two) will
interleave interpolated pixels between the 'true' pixels, which will
comprise an exact copy of the original image. If you superimpose the
interpolated image over the original image, the interpolated image
will have to be squashed to make it the same size. This squashing
(excuse my technical language) forces the 'true' pixels to move over
slightly to make room for the interpolated pixels. In the case of 2x
oversampling, the center of the 'true' pixel in the sinc-interpolated
image will be shifted by 1/4 of the spacing of the pixels in the
original image. This accounts for the slight sub-pixel shift that has
been driving me nuts... can probably fix this by applying a phase
modulation to the Fourier data.
Reply by Ken Prager●September 23, 20032003-09-23
In article <20030922225830754-0400@news.verizon.net>,
Eric Raas <foo@bar.net> wrote:
> >
> >> I have used sinc interpolation (by zero padding 2D FFT) to oversample
> >> an image along one axis. The results look good, but if I make the
> >> new and old images the same size and overlay them, the interpolated
> >> image seems to be shifted by about a pixel (maybe less) along the
> >> direction of interpolation.
> >
> > What are you using to make the old image the same size? Could the
> > error be there?
> >
>
> The original image is 64x64 and the new image is 128x64. I am viewing
> them onscreen using C libraries (Apple's Cocoa framework) which allow
> you to specify the desired display size (in screen pixels) of an image.
> I am drawing both the old and new images to a view with the same nominal
> size in screen pixels (the edges of the two images are in aligment - it
> is the content that seems to shift). The viewing size is somewhat
> larger than the original bitmap sizes, and the images are rendered using
> pixel replication (they look 'blocky').
>
> Of course the library must do other pixel transformations to render the
> small bitmaps on the screen as larger bitmaps - maybe the problem is
> related to this, although the shift looks too large to just be due to
> monitor resolution (it is on the order of the much larger pixels of the
> processed bitmaps - not the screen pixels).
>
> I guess that if my image shifts, that means I am effectively convolving
> it with a shifted sinc function, which means I'm multiplying the 2D FFT
> data with a phase-modulated rect function (i.e. somehow disturbing the
> phase of the original data). I don't see how just zero-padding could do
> that though.
>
> On a related note I have also noticed funny shifts/warping in images
> when I turn Apple's Quartz antialiasing on or off (it smooths the edges
> of blocky pixels in enlarged bitmaps - is really intended for text).
> Maybe I should try making my image view sizes an even power of two...
It sounds like your original image is being replicated. This would lead
to a one-pixel shift (in the image space, not viewing space).
I have only had a little experience with Cocoa's built-in functions for
image display but found them to be flaky. For one thing, the older
version, used with 10.1.x did not implement all of the functionality.
Bottom line is that I have seen Cocoa's IP routines offer less control
over the display process and I would not rely on them to upsample the
original image.
Are you using Cocoa for convenience or is your end goal to make a
standalone program? If it's convenience then you might consider trying
another viewing program such as GraphicConverter? It provides plenty of
options for upsampling the original. Matlab (and the image processing
toolbox) is another alternative.
HTH,
KP
--
Remove _me_ for e-mail address
Reply by Eric Raas●September 22, 20032003-09-22
>
>> I have used sinc interpolation (by zero padding 2D FFT) to oversample
>> an image along one axis. The results look good, but if I make the
>> new and old images the same size and overlay them, the interpolated
>> image seems to be shifted by about a pixel (maybe less) along the
>> direction of interpolation.
>
> What are you using to make the old image the same size? Could the
> error be there?
>
The original image is 64x64 and the new image is 128x64. I am viewing
them onscreen using C libraries (Apple's Cocoa framework) which allow
you to specify the desired display size (in screen pixels) of an image.
I am drawing both the old and new images to a view with the same nominal
size in screen pixels (the edges of the two images are in aligment - it
is the content that seems to shift). The viewing size is somewhat
larger than the original bitmap sizes, and the images are rendered using
pixel replication (they look 'blocky').
Of course the library must do other pixel transformations to render the
small bitmaps on the screen as larger bitmaps - maybe the problem is
related to this, although the shift looks too large to just be due to
monitor resolution (it is on the order of the much larger pixels of the
processed bitmaps - not the screen pixels).
I guess that if my image shifts, that means I am effectively convolving
it with a shifted sinc function, which means I'm multiplying the 2D FFT
data with a phase-modulated rect function (i.e. somehow disturbing the
phase of the original data). I don't see how just zero-padding could do
that though.
On a related note I have also noticed funny shifts/warping in images
when I turn Apple's Quartz antialiasing on or off (it smooths the edges
of blocky pixels in enlarged bitmaps - is really intended for text).
Maybe I should try making my image view sizes an even power of two...
Reply by Ken Prager●September 22, 20032003-09-22
In article <20030922134949292-0400@nntp.mgh.harvard.edu>,
Eric Raas <foo@bar.net> wrote:
> I have used sinc interpolation (by zero padding 2D FFT) to oversample an
> image along one axis. The results look good, but if I make the new and
> old images the same size and overlay them, the interpolated image seems
> to be shifted by about a pixel (maybe less) along the direction of
> interpolation.
What are you using to make the old image the same size? Could the error
be there?
KP
--
Remove _me_ for e-mail address
Reply by Eric Raas●September 22, 20032003-09-22
I have used sinc interpolation (by zero padding 2D FFT) to oversample an
image along one axis. The results look good, but if I make the new and
old images the same size and overlay them, the interpolated image seems
to be shifted by about a pixel (maybe less) along the direction of
interpolation.
The scheme I used was pretty simple (described here for interpolation of
rows):
1) take 2D FFT of original 64x64 image
2) zero pad 2D FFT array to create a 128x64 array (taking shifted
quadrants produced by FFT function into account)
3) compute inverse 2D FFT of the zero-padded array
I understand that a one-pixel image shift corresponds to a 2*pi phase
roll over the rows of the 2D FT matrix, but am not sure why this would
happen. Any ideas?
Code fragement (using Apple vDSP libraries) attached below:
// Compute 2D FFT of original image
fft2d_zip ( setup, &origImage, rowStride, columnStride, log2nc, log2nr,
FFT_FORWARD );
// Zero-pad the rows of the data here
COMPLEX_SPLIT padImage;
padImage.realp = (float*)calloc(n*2, sizeof(float));
padImage.imagp = (float*)calloc(n*2, sizeof(float)); // Is all zero
memcpy( padImage.realp, origImage.realp, ( n/2 * sizeof (float)));
memcpy( padImage.imagp, origImage.imagp, ( n/2 * sizeof (float)));
memcpy( &(padImage.realp[n + n/2]), &(origImage.realp[n/2]), ( n/2 *
sizeof ( float ) ) );
memcpy( &(padImage.imagp[n + n/2]), &(origImage.imagp[n/2]), ( n/2 *
sizeof ( float ) ) );
// Now compute inverse FFT
fft2d_zip ( setup, &padImage, rowStride, columnStride, log2nc,
log2nr+1, FFT_INVERSE );
// scale the result
float scale = 1.0 / (float)n; // get scale factor
vsmul( padImage.realp, 1, &scale, padImage.realp, 1, 2*n);
vsmul( padImage.imagp, 1, &scale, padImage.imagp, 1, 2*n);