[Insight-users] Reusing filters

somesh somesh.bbt at gmail.com
Wed Jun 12 14:37:08 EDT 2013


Hi,
This is a follow up on my last email to the group. I have attached a more
practical
example of how I am using the code.

In the attached code,
a) I read an image from file
b) Call my filter, which fills the pixels connected to a given position and
bounding box with a
given value. ( Its like paint bucket fill on most image editing programs,
but restricted to a given
bounding box)
c) Write the image to file.

My input image is TestInput.png, and desired output is DesiredOutput.png.

Inside my function FillImage() I mix ITK pipeline and iterators.
The code currently seg faults @ line 138:
inputImage->SetPixel(targetImageindex, targetForegroundPixel);
I do a check that the index is valid.
I have also pasted the code below for quick reference.

Thanks for reading.

-Somesh


// Code Starts
#include <itkImageFileReader.h>
#include <itkImageFileWriter.h>
#include <itkConnectedComponentImageFilter.h>
#include <itkImageRegionIteratorWithIndex.h>
#include <iomanip>
using namespace std;

// Read Image from File


template<typename TImage>
void
ReadImage(std::string filename, void* outImage)
{
    typedef TImage ImageType;
    typename ImageType::Pointer *image = (typename ImageType::Pointer
*)outImage;
    typedef itk::ImageFileReader< TImage > ReaderType;
    typename ReaderType::Pointer reader = ReaderType::New();
    reader->SetFileName(filename);
    reader->SetReleaseDataFlag(true);
    reader->Update();
    *image = reader->GetOutput();
}

// Write Image to File


template< typename TImage>
void
WriteImage(std::string filename, typename TImage::Pointer image)
{

    typedef itk::ImageFileWriter<TImage> WriterType;
    typename WriterType::Pointer writer = WriterType::New();
    writer->SetFileName(filename);
    writer->SetInput(image);
    writer->Update();
    // Do I need to disconnect if I want to reuse the filter
    image->DisconnectPipeline();

}

//------------------------------------------------------------------------------
//
//  FillLabel
/**
 *   Fill the region connected to the given "User specified position"
inside a
 *   "User specified bounding box" with the "target pixel value"
 *
 *   @param inputImage Pointer to input image file. Output will be written
inplace
 *
 *   @param clickedPointPosition User specified position
 *
 *   @param boundingRegion User specified bounding box
 *
 *   @param targetForegroundPixel Target pixel value
 *
 *  *
 *///---------------------------------------------------------------------------


template<typename TImage>
void
FillLabel(const typename TImage::Pointer inputImage,
          typename TImage::PointType clickedPointPosition,
          typename TImage::RegionType boundingRegion,
          typename TImage::PixelType targetForegroundPixel)
{

    typedef TImage ImageType;
    typedef typename ImageType::PixelType PixelType;

    // Apply connected component filter to the specified region of the
input image
    typedef itk::ConnectedComponentImageFilter <ImageType, ImageType >
            ConnectedComponentImageFilterType;
    typename ConnectedComponentImageFilterType::Pointer ccFilter
            = ConnectedComponentImageFilterType::New();
    ccFilter->SetInput(inputImage);
    ccFilter->GetOutput()->SetRequestedRegion(boundingRegion);
    ccFilter->Update();

    typename ImageType::Pointer ccImage = ccFilter->GetOutput();

    //Get Connected component Label at user specified position
    typename ImageType::IndexType index;
    ccImage->TransformPhysicalPointToIndex(clickedPointPosition, index);
    PixelType desiredPixel = ccImage->GetPixel(index);
    // Print the label
    cout << " Connected Component label at specified position is  "
            << (int) desiredPixel << endl;






    const unsigned int dimension = 2;
    itk::ContinuousIndex<double, dimension > targetIndex;
    typename ImageType::IndexType targetImageindex;
    // Get the size of the input image
    typename ImageType::SizeType inputImageSize =
inputImage->GetLargestPossibleRegion().GetSize();


    typename ImageType::PointType point;
    PixelType ccPixel;

    // Iterate through the User specified bounding box
    itk::ImageRegionIteratorWithIndex<ImageType> itCropped(ccImage,

 ccImage->GetRequestedRegion());

    itCropped.GoToBegin();
    while (!itCropped.IsAtEnd())
        {
            // Get pixel
            ccPixel = itCropped.Get();

            // If pixel is equal to the connected component pixel at user
specifed
            // position, replace pixel in input image with target pixel
            if (ccPixel == desiredPixel)
                {
                    // Get corresponding index of input image
                    index = itCropped.GetIndex();
                    ccImage->TransformIndexToPhysicalPoint(index, point);

inputImage->TransformPhysicalPointToContinuousIndex(point, targetIndex);



                    // Do a sanity check, check if index lies inside image
bounds
                    if ((targetIndex[0] >= inputImageSize[0]) ||
(targetIndex[1] >= inputImageSize[1])
                        || (targetIndex[0] < 0) || (targetIndex[1] < 0))
                        {
                            cout << " Invalid Index :: " << targetIndex[0]
<<
                                    " " << targetIndex[1] << endl;
                        }
                    else
                        {
                            targetImageindex[0] = targetIndex[0];
                            targetImageindex[1] = targetIndex[1];

                            // All good, set pixel in input image
                            inputImage->SetPixel(targetImageindex,
targetForegroundPixel);
                        }
                }

            ++itCropped;
        }
}


int
main(int argc, char* argv[])
{
    // Define Image Type as 2D image
    typedef itk::Image<unsigned char, 2 > ImageType;

    // Read Image
    ImageType::Pointer inputImage = NULL;
    void* pImg = &inputImage;
    ReadImage<ImageType > ("TestInput.png", pImg);
    inputImage->SetRequestedRegion(inputImage->GetLargestPossibleRegion());
    inputImage->Update();


    ImageType::PointType point;
    point[0] = 418;
    point[1] = 215;


    ImageType::SizeType size;
    size[0] = 75;
    size[1] = 75;

    ImageType::IndexType index;
    index[0] = 375;
    index[1] = 175;

    ImageType::RegionType boundingRegion;
    boundingRegion.SetSize(size);
    boundingRegion.SetIndex(index);

    ImageType::PixelType pixel;
    pixel = 100;


    FillLabel<ImageType > (inputImage,
                           point,
                           boundingRegion,
                           pixel);

    // Call write image filter
    WriteImage<ImageType > ("TestOutput.png", inputImage);
    //    // Call write image filter again
    //    WriteImage<ImageType > ("TestOutputCopy.png", inputImage);

    return EXIT_SUCCESS;
}

// Code ends




On Tue, Jun 11, 2013 at 3:57 PM, somesh <somesh.bbt at gmail.com> wrote:

> Hi Group,
> I have a very basic doubt regarding re-using filter. I have an application
> where:
>
> a) I read an image from file
>
> b) Connect it to vtk for displaying (using itkImageToVTKImageFilter.h , I
> use VTKImageViewer2
> for displaying the image)
>
> c) Call various filter on the input itk image and the display is updated
> automatically.
> These filters can be called multiple times. All the filters are wrapped in
> a library.
>
> For example, the input image can be a segmentation, which I connect to vtk
> for displaying. And I can apply filters like dilation/connected components
> etc
> on the itk segmentation image and display is updated.
>
> See attached TestITKFilters.cxx. That's a very basic version of what I am
> doing in
> the application. ReadImage/WriteImage/PasteImage are the "filters".
>
> Here are my doubts:
> a) Should I call DisconnectPipeline at lines 32/57/58 if I want to use the
> filters
>    multiple times.
>
> b) If I call DisconnectPipeline on input image inside the function, does
> it also disconnect
>  itkImageToVTKImageFilter pipeline ?
>
> c) In the attached code, if I call WriteImage multiple times ( e.g.
> uncomment line 87,
> the program segfaults with the error:
>
> *terminate called after throwing an instance of
> 'itk::ImageFileWriterException'*
> *  what():  /usr/local/include/ITK-4.3/itkImageFileWriter.hxx:403:*
> *Did not get requested region!*
> *Requested:*
> *ImageRegion (0xbfb788b0)*
> *  Dimension: 2*
> *  Index: [0, 0]*
> *  Size: [640, 400]*
> *Actual:*
> *ImageRegion (0xbfb788c4)*
> *  Dimension: 2*
> *  Index: [0, 0]*
> *  Size: [0, 0]*
>
> I tried adding
> inputImage->SetRequestedRegion(inputImage->GetLargestPossibleRegion());,
> but it has no effect.
>
>
>
> Thanks,
> Somesh
>
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.itk.org/pipermail/insight-users/attachments/20130612/7f210528/attachment.htm>
-------------- next part --------------
# This is the root ITK CMakeLists file.
CMAKE_MINIMUM_REQUIRED(VERSION 2.4)
IF(COMMAND CMAKE_POLICY)
  CMAKE_POLICY(SET CMP0003 NEW)
ENDIF(COMMAND CMAKE_POLICY)

# This project is designed to be built outside the Insight source tree.
PROJECT(TestITKFilters)

# Find ITK.
FIND_PACKAGE(ITK REQUIRED)
INCLUDE(${ITK_USE_FILE})

ADD_EXECUTABLE(TestITKFilters TestITKFilters.cxx )

TARGET_LINK_LIBRARIES(TestITKFilters  ${ITK_LIBRARIES})
-------------- next part --------------
A non-text attachment was scrubbed...
Name: DesiredOutput.png
Type: image/png
Size: 4481 bytes
Desc: not available
URL: <http://www.itk.org/pipermail/insight-users/attachments/20130612/7f210528/attachment.png>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: TestInput.png
Type: image/png
Size: 4483 bytes
Desc: not available
URL: <http://www.itk.org/pipermail/insight-users/attachments/20130612/7f210528/attachment-0001.png>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: TestITKFilters.cxx
Type: application/octet-stream
Size: 6127 bytes
Desc: not available
URL: <http://www.itk.org/pipermail/insight-users/attachments/20130612/7f210528/attachment.obj>


More information about the Insight-users mailing list