[Insight-users] Using regions to control iterators...

Jared Hoover jsh238 at gmail.com
Fri May 12 14:14:36 EDT 2006


Luis and Jim,

I will try to describe what I'm trying to do more clearly.  I want to create
a colored output image that is identical to pixel spacing and size as the
input image.  An index and size specified at the command prompt will provide
a region in which the colors of the input image will be averaged and
outputed as one value in the exact same corresponding region in the output
image.  It will produce an output image that looks like the input image
except for the 'color smearing' in region of interest.

I tried setting the index to [0,0] and non-zero values at the command prompt
but the *.exe still crashes so I don't think it would be a problem with the
ImageFileWriter.  Below is the whole file..

Jared

#include "itkImage.h"
#include "itkImageRegionConstIterator.h"
#include "itkImageRegionIterator.h"
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"

int main( int argc, char *argv[] ) {

    // Verify the number of parameters on the command line.
    if ( argc < 7 )    {
        std::cerr << "Missing parameters. " << std::endl;
        std::cerr << "Usage: " << std::endl;
        std::cerr << argv[0]
        << " inputImageFile outputImageFile originX originY lengthX lengthY"
        << std::endl;
        return -1;
    }

    // Color Pixel Type
    typedef itk::RGBPixel<unsigned char> PixelType;
    // ND Type
    const unsigned int Dimension = 2;
    // Image Type
    typedef itk::Image< PixelType, Dimension > ImageType;
    // Image File Reader Type
    typedef itk::ImageFileReader< ImageType > ReaderType;
    // Image File Writer Type
    typedef itk::ImageFileWriter< ImageType > WriterType;
    // Image Region Constant Iterator Type
    typedef itk::ImageRegionConstIterator<ImageType>
                                ConstIteratorType;
    // Image Region Iterator Type
    typedef itk::ImageRegionIterator<ImageType>
                                IteratorType;

    ////////////////////////////////////////////////////////////////
    /* try updating the reader */
    //
    ReaderType::Pointer reader = ReaderType::New();
    reader->SetFileName(argv[1]);
    try {
        reader->Update();
    }
    catch(itk::ExceptionObject &err) {
        std::cerr << "ExceptionObject caught!" << std::endl;
        std::cerr << err << std::endl;
        return -1;
    }
    ImageType::ConstPointer sourceImage = reader->GetOutput();


    //////////////////////////////////////////////////////////
    /* create the writer                                    */
    //
    WriterType::Pointer writer = WriterType::New();
    writer->SetFileName(argv[2]);


    //////////////////////////////////////////////////////////
    /* create the region in source to read from                */
    //
    ImageType::RegionType sourceInputRegion;
    ImageType::RegionType::IndexType sourceRegionStartIndex;
    ImageType::RegionType::SizeType sourceRegionStartSize;

    sourceRegionStartIndex[0] = ::atoi(argv[3]);
    sourceRegionStartIndex[1] = ::atoi(argv[4]);

    sourceRegionStartSize[0] = ::atoi(argv[5]);
    sourceRegionStartSize[1] = ::atoi(argv[6]);

    sourceInputRegion.SetSize(sourceRegionStartSize);
    sourceInputRegion.SetIndex(sourceRegionStartIndex);


    //////////////////////////////////////////////////////////
    /* create the region to output into the output image    */
    //
    ImageType::RegionType outputRegion;

    outputRegion.SetSize(sourceRegionStartSize);
    outputRegion.SetIndex(sourceRegionStartIndex);


    //////////////////////////////////////////////////////////
    /* Allocate an output image and set valid values to
    /    some of the basic image information during the
    /    copying process.  The starting index of the output
    /    region is now filled with zero values and the
    /    cooridinates of the physical origin are computed
    /    as a shift from the origin of the input image.
    //                                                        */
    ImageType::Pointer outputImage = ImageType::New();
    const ImageType::SpacingType& spacing =
                            reader->GetOutput()->GetSpacing();
    const ImageType::PointType& inputOrigin =
                            reader->GetOutput()->GetOrigin();
    double outputOrigin[Dimension];

    for(unsigned int i=0; i<Dimension; i++) {
        outputOrigin[i] =
inputOrigin[i]+spacing[i]*sourceRegionStartIndex[i];
    }
    outputImage->SetSpacing(spacing);            // Same pixel spacing as
input image
    outputImage->SetOrigin(outputOrigin);        // Same origin as input
image

outputImage->SetLargestPossibleRegion(sourceImage->GetLargestPossibleRegion());
    outputImage->SetBufferedRegion(outputRegion);
    outputImage->SetRequestedRegion(outputRegion);
    //outputImage->SetRegions(outputRegion);
    outputImage->Allocate();

    //////////////////////////////////////////////////////////
    /* Image Region Constant Iterator                        */
    //
    ConstIteratorType inputIt(reader->GetOutput(),sourceInputRegion);
    IteratorType outputIt(outputImage,outputImage->GetBufferedRegion());

    int i = 0;
    PixelType averageTemp, average;
    for( inputIt.GoToBegin(); !inputIt.IsAtEnd() ;
        ++inputIt) {
            if(i!=0){
                averageTemp = inputIt.Get();
                average.SetRed(int((average.GetRed
()+averageTemp.GetRed())/2.0));
                average.SetGreen(int((average.GetGreen
()+averageTemp.GetGreen())/2.0));
                average.SetBlue(int((average.GetBlue
()+averageTemp.GetBlue())/2.0));
            }
            else {
                averageTemp = inputIt.Get();
                average.SetRed(int(averageTemp.GetRed()));
                average.SetGreen(int(averageTemp.GetGreen()));
                average.SetBlue(int(averageTemp.GetBlue()));
                i++;
            }
        }


    for( outputIt.GoToBegin() ; !outputIt.IsAtEnd() ;
        ++outputIt) {
            outputIt.Set(average);
    }


    //////////////////////////////////////////////////////////
    /* Setting attributes to writer    and writing data        */
    //
    writer->SetInput(outputImage);
    try {
        writer->Update();
    }
    catch(itk::ExceptionObject &err) {
        std::cerr << "ExceptionObject caught!" << std::endl;
        std::cerr << err << std::endl;
        return -1;
    }

    return 0;
}


On 5/12/06, Miller, James V (GE, Research) <millerjv at crd.ge.com> wrote:
>
>  At first glance, the only issue I see is your calculation of the origin.
> In ITK, the origin corresponds to the physical coordinate (mm or ft, etc.)
> of the pixel at index [0, 0, ...].  Since your output region starts at a
> non-zero index, you should not need to move the origin.  So just copy the
> origin and spacing from the input image to the output image.
>
> Can you describe the "problem" in more detail?  How does the output image
> look?
>
> There could be a problem with the ImageFileWriter when the BufferedRegion
> does not start at index [0,0,...].  You could place a
> RegionOfInterestImageFilter before the ImageFileWriter (or an
> ChangeInformationImageFilter) to adjust the image so that the BufferedRegion
> starts at [0,0,...]
>
> Here are the definitions of regions:
>
> RequestedRegion: How much of the image to process.
> BufferedRegion: How much of the image is in memory.
> LargestPossibleRegion: How big could the image be.
>
> Filters are told to process a RequestedRegion.  When a filter runs, the
> RequestedRegion must be a subset of the BufferedRegion. The
> LargestPossibleRegion is typically used to tell whether a pixel is a true
> boundary condition or just a voxel at the edge of BufferedRegion.
>
> Jim
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://public.kitware.com/pipermail/insight-users/attachments/20060512/46fdb503/attachment.html


More information about the Insight-users mailing list