[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