Accessing multi-frame image in Magick++

Questions and postings pertaining to the development of ImageMagick, feature enhancements, and ImageMagick internals. ImageMagick source code and algorithms are discussed here. Usage questions which are too arcane for the normal user list should also be posted here.
blackhaz

Accessing multi-frame image in Magick++

Post 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
User avatar
magick
Site Admin
Posts: 11064
Joined: 2003-05-31T11:32:55-07:00

Re: Accessing multi-frame image in Magick++

Post 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.
blackhaz

Re: Accessing multi-frame image in Magick++

Post 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!
User avatar
magick
Site Admin
Posts: 11064
Joined: 2003-05-31T11:32:55-07:00

Re: Accessing multi-frame image in Magick++

Post 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.
blackhaz

Re: Accessing multi-frame image in Magick++

Post by blackhaz »

Thanks, Magick! Probably add an argument to forwardFourierTransform so one could be able to specify an STL container to hold the results?
User avatar
magick
Site Admin
Posts: 11064
Joined: 2003-05-31T11:32:55-07:00

Re: Accessing multi-frame image in Magick++

Post 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).
blackhaz

Re: Accessing multi-frame image in Magick++

Post 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?
User avatar
magick
Site Admin
Posts: 11064
Joined: 2003-05-31T11:32:55-07:00

Re: Accessing multi-frame image in Magick++

Post 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,
blackhaz

Re: Accessing multi-frame image in Magick++

Post 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.
User avatar
magick
Site Admin
Posts: 11064
Joined: 2003-05-31T11:32:55-07:00

Re: Accessing multi-frame image in Magick++

Post by magick »

Try forwardFourierTransformImage().
blackhaz

Re: Accessing multi-frame image in Magick++

Post 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)'
User avatar
magick
Site Admin
Posts: 11064
Joined: 2003-05-31T11:32:55-07:00

Re: Accessing multi-frame image in Magick++

Post by magick »

Looks like we have the template wrong. Look for a patch by end-of-day.
blackhaz

Re: Accessing multi-frame image in Magick++

Post by blackhaz »

Thanks, Magick. Probably you know this, already but documentation needs to be fixed as it refers to forwardFourierTransform and not forwardFourierTransformImage.
User avatar
magick
Site Admin
Posts: 11064
Joined: 2003-05-31T11:32:55-07:00

Re: Accessing multi-frame image in Magick++

Post by magick »

Already fixed-- we're waiting for it to be mirrored to the main web site in about an hour.
blackhaz

Re: Accessing multi-frame image in Magick++

Post 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.
Post Reply