Page 1 of 2

Accessing multi-frame image in Magick++

Posted: 2010-09-12T15:30:37-07:00
by blackhaz
Hello!

Assume we have the following chunk of code:

Image tmpI
tmpI.forwardFourierTransform(false); /* true returns magnitude/phase pair, otherwise real/imaginary pair */

After this, the object tmpI should have a pair of images. How do I access individual frames? As far as I can understand, an object of class Image can have only one image in it. I once saw a reference to subimage or subframe (forgot the name) on the IM forum, but it is not working and didn't work for the topicstarter.

The way I currently do it is a workaround:

tmpI.adjoin(true);
tmpI.write("somefile"); /* Saving this pair of images to some file */
tmpI.read("somefile[0]"); /* Reading image back from file */

This is because read method allows you to set [0] or [1] which is the frame number you want to get. So I save to TIFF, MPC or whatever format supports multi-frame images, and then read using [0] for the real part and [1] for imaginary part.

This is obviously a lame workaround as it involves saving and reading from/to hard drive. I tried MPR (an MPC file in memory) and it works must faster than hard disk, however still, that involves moving lots of data (sometimes up to 200 MB if we are saving a huge filter in MPC format) to one chunk of memory and moving it once again to another chunk of memory.

Thank you so much in advance!

Max

Re: Accessing multi-frame image in Magick++

Posted: 2010-09-12T15:43:45-07:00
by magick
Magick++ provides a set of Standard Template Libary (STL ) algorithms for operating across ranges of image frames in a container. It also provides a set of STL unary function objects to apply an operation on image frames in a container via an algorithm which uses unary function objects. A good example of a standard algorithm which is useful for processing containers of image frames is the STL for_each algorithm which invokes a unary function object on a range of container elements. See http://www.imagemagick.org/Magick++/STL.html.

Re: Accessing multi-frame image in Magick++

Posted: 2010-09-12T17:22:50-07:00
by blackhaz
Dear Magick,

Would it be too much to ask for a code example with Fourier transforms? I am aware of STL, however I have one input image. Even if I put it in the STL list, I can't apply forwardFourierTransform to the list itself. If I apply forwardFourierTransform to the list using for_each, then I don't have a pair of images as a result in the list.

I am a bit confused on how shall I use the list here, as with forwardFourierTransform I have one image as input and a pair of images as output. The input image is a single Image class object.

Thanks!

Re: Accessing multi-frame image in Magick++

Posted: 2010-09-12T17:29:04-07:00
by magick
We may need to move forwardFourierTransform to an STL container. We'll need to investigate. Give us a few days and we'll get back to you.

Re: Accessing multi-frame image in Magick++

Posted: 2010-09-13T04:55:17-07:00
by blackhaz
Thanks, Magick! Probably add an argument to forwardFourierTransform so one could be able to specify an STL container to hold the results?

Re: Accessing multi-frame image in Magick++

Posted: 2010-09-14T12:00:46-07:00
by magick
Grab ImageMagick 6.6.4-2 Beta in a couple of hours. The forwardFourierTransform() method signature changed to support an STL container. The first parameter is the container, the second is the image, and an optional third parameter is whether you want the magnitude / phase or real / imaginary image pair (bool).

Re: Accessing multi-frame image in Magick++

Posted: 2010-09-14T12:52:36-07:00
by blackhaz
Hurray!! Thanks a million!

By the way, why do we need a second parameter as the image? Shouldn't this function be invoked as Image.forwardFourierTransform(container,switch), i.e. it will grab (this) as the input Image?

Re: Accessing multi-frame image in Magick++

Posted: 2010-09-14T16:24:17-07:00
by magick
Containers are only available as part of the STL. We can grab the image from an InputIterator but its just as easy to pass an Image&. Take a look at Magick++/lib/Magick++/STL.h and let us know if you come up with a way to use 'this' rather than passing the image. Post your changes here so we can review them. Thanks,

Re: Accessing multi-frame image in Magick++

Posted: 2010-09-15T06:53:53-07:00
by blackhaz
Will do! But my coding skills are on a beginner's level.

By the way, I grabbed and built Version: ImageMagick 6.6.4-2 2010-09-15, however:
../DStation/dstation.cpp:502: error: 'forwardFourierTransform' was not declared in this scope

What may be the cause? I can't find this function in the headers as well, and the old one is gone.

Re: Accessing multi-frame image in Magick++

Posted: 2010-09-15T07:07:37-07:00
by magick
Try forwardFourierTransformImage().

Re: Accessing multi-frame image in Magick++

Posted: 2010-09-15T07:21:50-07:00
by blackhaz
Found it, however there is a problem with pointers?

./DStation/dstation.cpp: In member function 'void DStation::deconvolve()':
../DStation/dstation.cpp:502: error: no matching function for call to 'forwardFourierTransformImage(std::list<Magick::Image, std::allocator<Magick::Image> >*, Magick::Image&, bool)'

Calling as:
forwardFourierTransformImage(&FFTContainer,inputImage,false);

Tried &inputImage, however got:
../DStation/dstation.cpp:502: error: no matching function for call to 'forwardFourierTransformImage(std::list<Magick::Image, std::allocator<Magick::Image> >*, Magick::Image*, bool)'

Re: Accessing multi-frame image in Magick++

Posted: 2010-09-15T07:24:59-07:00
by magick
Looks like we have the template wrong. Look for a patch by end-of-day.

Re: Accessing multi-frame image in Magick++

Posted: 2010-09-15T07:28:41-07:00
by blackhaz
Thanks, Magick. Probably you know this, already but documentation needs to be fixed as it refers to forwardFourierTransform and not forwardFourierTransformImage.

Re: Accessing multi-frame image in Magick++

Posted: 2010-09-15T07:35:04-07:00
by magick
Already fixed-- we're waiting for it to be mirrored to the main web site in about an hour.

Re: Accessing multi-frame image in Magick++

Posted: 2010-09-15T07:45:52-07:00
by blackhaz
By the way, I looked at how this is now implemented in STL part and I think it would be logical to move the function back to the Image.cpp, something like this below. Invoked as:
inputImage.forwardFourierTransform(&FFTContainer,magnitudeFlag);

Code: Select all

template <class InputIterator, class Container >
void Magick::Image::forwardFourierTransform ( Container *fourierImages_, const bool magnitude_ )
{
  ExceptionInfo exceptionInfo;
  GetExceptionInfo( &exceptionInfo );
  MagickCore::Image* images = ForwardFourierTransformImage ( image(),
    magnitude_ == true ? MagickTrue : MagickFalse, &exceptionInfo );
// Ensure container is empty
    fourierImages_->clear();

    // Move images to container
    insertImages( fourierImages_, images );

  throwException( exceptionInfo );
  (void) DestroyExceptionInfo( &exceptionInfo );
}
The only problem is that Container is not defined at Image.h and I am not sure if you want to include all this STL stuff at that level.