<div dir="ltr">Hi,<div>This is a follow up on my last email to the group. I have attached a more practical </div><div>example of how I am using the code.</div><div><br></div><div>In the attached code, </div><div>a) I read an image from file</div>
<div>b) Call my filter, which fills the pixels connected to a given position and bounding box with a</div><div>given value. ( Its like paint bucket fill on most image editing programs, but restricted to a given </div><div style>
bounding box)</div><div>c) Write the image to file.</div><div><br></div><div>My input image is TestInput.png, and desired output is DesiredOutput.png.</div><div><br></div><div>Inside my function FillImage() I mix ITK pipeline and iterators.</div>
<div>The code currently seg faults @ line 138:</div><div>inputImage->SetPixel(targetImageindex, targetForegroundPixel);</div><div>I do a check that the index is valid. <br></div><div>I have also pasted the code below for quick reference.<br>
</div><div style><br></div><div style>Thanks for reading.<br></div><div style><br></div><div style>-Somesh<br></div><div style><br></div><div style><br></div><div style>// Code Starts</div><div style><div><font face="courier new, monospace" size="1">#include <itkImageFileReader.h> </font></div>
<div><font face="courier new, monospace" size="1">#include <itkImageFileWriter.h> </font></div><div><font face="courier new, monospace" size="1">#include <itkConnectedComponentImageFilter.h></font></div><div><font face="courier new, monospace" size="1">#include <itkImageRegionIteratorWithIndex.h></font></div>
<div><font face="courier new, monospace" size="1">#include <iomanip></font></div><div><font face="courier new, monospace" size="1">using namespace std;</font></div><div><font face="courier new, monospace" size="1"><br>
</font></div><div><font face="courier new, monospace" size="1">// Read Image from File</font></div><div><font face="courier new, monospace" size="1"><br></font></div><div><font face="courier new, monospace" size="1"><br></font></div>
<div><font face="courier new, monospace" size="1">template<typename TImage></font></div><div><font face="courier new, monospace" size="1">void</font></div><div><font face="courier new, monospace" size="1">ReadImage(std::string filename, void* outImage)</font></div>
<div><font face="courier new, monospace" size="1">{</font></div><div><font face="courier new, monospace" size="1"> typedef TImage ImageType;</font></div><div><font face="courier new, monospace" size="1"> typename ImageType::Pointer *image = (typename ImageType::Pointer *)outImage;</font></div>
<div><font face="courier new, monospace" size="1"> typedef itk::ImageFileReader< TImage > ReaderType;</font></div><div><font face="courier new, monospace" size="1"> typename ReaderType::Pointer reader = ReaderType::New();</font></div>
<div><font face="courier new, monospace" size="1"> reader->SetFileName(filename);</font></div><div><font face="courier new, monospace" size="1"> reader->SetReleaseDataFlag(true);</font></div><div><font face="courier new, monospace" size="1"> reader->Update();</font></div>
<div><font face="courier new, monospace" size="1"> *image = reader->GetOutput();</font></div><div><font face="courier new, monospace" size="1">}</font></div><div><font face="courier new, monospace" size="1"><br></font></div>
<div><font face="courier new, monospace" size="1">// Write Image to File</font></div><div><font face="courier new, monospace" size="1"><br></font></div><div><font face="courier new, monospace" size="1"><br></font></div><div>
<font face="courier new, monospace" size="1">template< typename TImage></font></div><div><font face="courier new, monospace" size="1">void</font></div><div><font face="courier new, monospace" size="1">WriteImage(std::string filename, typename TImage::Pointer image)</font></div>
<div><font face="courier new, monospace" size="1">{</font></div><div><font face="courier new, monospace" size="1"><br></font></div><div><font face="courier new, monospace" size="1"> typedef itk::ImageFileWriter<TImage> WriterType;</font></div>
<div><font face="courier new, monospace" size="1"> typename WriterType::Pointer writer = WriterType::New();</font></div><div><font face="courier new, monospace" size="1"> writer->SetFileName(filename);</font></div>
<div><font face="courier new, monospace" size="1"> writer->SetInput(image);</font></div><div><font face="courier new, monospace" size="1"> writer->Update();</font></div><div><font face="courier new, monospace" size="1"> // Do I need to disconnect if I want to reuse the filter</font></div>
<div><font face="courier new, monospace" size="1"> image->DisconnectPipeline();</font></div><div><font face="courier new, monospace" size="1"><br></font></div><div><font face="courier new, monospace" size="1">}</font></div>
<div><font face="courier new, monospace" size="1"><br></font></div><div><font face="courier new, monospace" size="1">//------------------------------------------------------------------------------</font></div><div><font face="courier new, monospace" size="1">//</font></div>
<div><font face="courier new, monospace" size="1">// FillLabel</font></div><div><font face="courier new, monospace" size="1">/**</font></div><div><font face="courier new, monospace" size="1"> * Fill the region connected to the given "User specified position" inside a </font></div>
<div><font face="courier new, monospace" size="1"> * "User specified bounding box" with the "target pixel value"</font></div><div><font face="courier new, monospace" size="1"> *</font></div><div><font face="courier new, monospace" size="1"> * @param inputImage Pointer to input image file. Output will be written inplace</font></div>
<div><font face="courier new, monospace" size="1"> *</font></div><div><font face="courier new, monospace" size="1"> * @param clickedPointPosition User specified position</font></div><div><font face="courier new, monospace" size="1"> * </font></div>
<div><font face="courier new, monospace" size="1"> * @param boundingRegion User specified bounding box</font></div><div><font face="courier new, monospace" size="1"> * </font></div><div><font face="courier new, monospace" size="1"> * @param targetForegroundPixel Target pixel value</font></div>
<div><font face="courier new, monospace" size="1"> * </font></div><div><font face="courier new, monospace" size="1"> * *</font></div><div><font face="courier new, monospace" size="1"> *///---------------------------------------------------------------------------</font></div>
<div><font face="courier new, monospace" size="1"><br></font></div><div><font face="courier new, monospace" size="1"><br></font></div><div><font face="courier new, monospace" size="1">template<typename TImage></font></div>
<div><font face="courier new, monospace" size="1">void</font></div><div><font face="courier new, monospace" size="1">FillLabel(const typename TImage::Pointer inputImage,</font></div><div><font face="courier new, monospace" size="1"> typename TImage::PointType clickedPointPosition,</font></div>
<div><font face="courier new, monospace" size="1"> typename TImage::RegionType boundingRegion,</font></div><div><font face="courier new, monospace" size="1"> typename TImage::PixelType targetForegroundPixel)</font></div>
<div><font face="courier new, monospace" size="1">{</font></div><div><font face="courier new, monospace" size="1"><br></font></div><div><font face="courier new, monospace" size="1"> typedef TImage ImageType;</font></div>
<div><font face="courier new, monospace" size="1"> typedef typename ImageType::PixelType PixelType;</font></div><div><font face="courier new, monospace" size="1"><br></font></div><div><font face="courier new, monospace" size="1"> // Apply connected component filter to the specified region of the input image</font></div>
<div><font face="courier new, monospace" size="1"> typedef itk::ConnectedComponentImageFilter <ImageType, ImageType ></font></div><div><font face="courier new, monospace" size="1"> ConnectedComponentImageFilterType;</font></div>
<div><font face="courier new, monospace" size="1"> typename ConnectedComponentImageFilterType::Pointer ccFilter</font></div><div><font face="courier new, monospace" size="1"> = ConnectedComponentImageFilterType::New();</font></div>
<div><font face="courier new, monospace" size="1"> ccFilter->SetInput(inputImage);</font></div><div><font face="courier new, monospace" size="1"> ccFilter->GetOutput()->SetRequestedRegion(boundingRegion);</font></div>
<div><font face="courier new, monospace" size="1"> ccFilter->Update();</font></div><div><font face="courier new, monospace" size="1"><br></font></div><div><font face="courier new, monospace" size="1"> typename ImageType::Pointer ccImage = ccFilter->GetOutput();</font></div>
<div><font face="courier new, monospace" size="1"><br></font></div><div><font face="courier new, monospace" size="1"> //Get Connected component Label at user specified position</font></div><div><font face="courier new, monospace" size="1"> typename ImageType::IndexType index;</font></div>
<div><font face="courier new, monospace" size="1"> ccImage->TransformPhysicalPointToIndex(clickedPointPosition, index);</font></div><div><font face="courier new, monospace" size="1"> PixelType desiredPixel = ccImage->GetPixel(index);</font></div>
<div><font face="courier new, monospace" size="1"> // Print the label</font></div><div><font face="courier new, monospace" size="1"> cout << " Connected Component label at specified position is "</font></div>
<div><font face="courier new, monospace" size="1"> << (int) desiredPixel << endl;</font></div><div><font face="courier new, monospace" size="1"> </font></div><div><font face="courier new, monospace" size="1"> </font></div>
<div><font face="courier new, monospace" size="1"><br></font></div><div><font face="courier new, monospace" size="1"><br></font></div><div><font face="courier new, monospace" size="1"><br></font></div><div><font face="courier new, monospace" size="1"><br>
</font></div><div><font face="courier new, monospace" size="1"> const unsigned int dimension = 2;</font></div><div><font face="courier new, monospace" size="1"> itk::ContinuousIndex<double, dimension > targetIndex;</font></div>
<div><font face="courier new, monospace" size="1"> typename ImageType::IndexType targetImageindex;</font></div><div><font face="courier new, monospace" size="1"> // Get the size of the input image</font></div><div><font face="courier new, monospace" size="1"> typename ImageType::SizeType inputImageSize = inputImage->GetLargestPossibleRegion().GetSize();</font></div>
<div><font face="courier new, monospace" size="1"><br></font></div><div><font face="courier new, monospace" size="1"><br></font></div><div><font face="courier new, monospace" size="1"> typename ImageType::PointType point;</font></div>
<div><font face="courier new, monospace" size="1"> PixelType ccPixel;</font></div><div><font face="courier new, monospace" size="1"><br></font></div><div><font face="courier new, monospace" size="1"> // Iterate through the User specified bounding box</font></div>
<div><font face="courier new, monospace" size="1"> itk::ImageRegionIteratorWithIndex<ImageType> itCropped(ccImage,</font></div><div><font face="courier new, monospace" size="1"> ccImage->GetRequestedRegion());</font></div>
<div><font face="courier new, monospace" size="1"><br></font></div><div><font face="courier new, monospace" size="1"> itCropped.GoToBegin();</font></div><div><font face="courier new, monospace" size="1"> while (!itCropped.IsAtEnd())</font></div>
<div><font face="courier new, monospace" size="1"> {</font></div><div><font face="courier new, monospace" size="1"> // Get pixel</font></div><div><font face="courier new, monospace" size="1"> ccPixel = itCropped.Get();</font></div>
<div><font face="courier new, monospace" size="1"><br></font></div><div><font face="courier new, monospace" size="1"> // If pixel is equal to the connected component pixel at user specifed</font></div><div><font face="courier new, monospace" size="1"> // position, replace pixel in input image with target pixel</font></div>
<div><font face="courier new, monospace" size="1"> if (ccPixel == desiredPixel)</font></div><div><font face="courier new, monospace" size="1"> {</font></div><div><font face="courier new, monospace" size="1"> // Get corresponding index of input image</font></div>
<div><font face="courier new, monospace" size="1"> index = itCropped.GetIndex();</font></div><div><font face="courier new, monospace" size="1"> ccImage->TransformIndexToPhysicalPoint(index, point);</font></div>
<div><font face="courier new, monospace" size="1"> inputImage->TransformPhysicalPointToContinuousIndex(point, targetIndex);</font></div><div><font face="courier new, monospace" size="1"><br></font></div>
<div><font face="courier new, monospace" size="1"><br></font></div><div><font face="courier new, monospace" size="1"><br></font></div><div><font face="courier new, monospace" size="1"> // Do a sanity check, check if index lies inside image bounds</font></div>
<div><font face="courier new, monospace" size="1"> if ((targetIndex[0] >= inputImageSize[0]) || (targetIndex[1] >= inputImageSize[1])</font></div><div><font face="courier new, monospace" size="1"> || (targetIndex[0] < 0) || (targetIndex[1] < 0))</font></div>
<div><font face="courier new, monospace" size="1"> {</font></div><div><font face="courier new, monospace" size="1"> cout << " Invalid Index :: " << targetIndex[0] <<</font></div>
<div><font face="courier new, monospace" size="1"> " " << targetIndex[1] << endl;</font></div><div><font face="courier new, monospace" size="1"> }</font></div>
<div><font face="courier new, monospace" size="1"> else</font></div><div><font face="courier new, monospace" size="1"> {</font></div><div><font face="courier new, monospace" size="1"> targetImageindex[0] = targetIndex[0];</font></div>
<div><font face="courier new, monospace" size="1"> targetImageindex[1] = targetIndex[1];</font></div><div><font face="courier new, monospace" size="1"><br></font></div><div><font face="courier new, monospace" size="1"> // All good, set pixel in input image</font></div>
<div><font face="courier new, monospace" size="1"> inputImage->SetPixel(targetImageindex, targetForegroundPixel);</font></div><div><font face="courier new, monospace" size="1"> }</font></div>
<div><font face="courier new, monospace" size="1"> }</font></div><div><font face="courier new, monospace" size="1"><br></font></div><div><font face="courier new, monospace" size="1"> ++itCropped;</font></div>
<div><font face="courier new, monospace" size="1"> }</font></div><div><font face="courier new, monospace" size="1">}</font></div><div><font face="courier new, monospace" size="1"><br></font></div><div><font face="courier new, monospace" size="1"><br>
</font></div><div><font face="courier new, monospace" size="1">int</font></div><div><font face="courier new, monospace" size="1">main(int argc, char* argv[])</font></div><div><font face="courier new, monospace" size="1">{</font></div>
<div><font face="courier new, monospace" size="1"> // Define Image Type as 2D image</font></div><div><font face="courier new, monospace" size="1"> typedef itk::Image<unsigned char, 2 > ImageType;</font></div><div>
<font face="courier new, monospace" size="1"><br></font></div><div><font face="courier new, monospace" size="1"> // Read Image</font></div><div><font face="courier new, monospace" size="1"> ImageType::Pointer inputImage = NULL;</font></div>
<div><font face="courier new, monospace" size="1"> void* pImg = &inputImage;</font></div><div><font face="courier new, monospace" size="1"> ReadImage<ImageType > ("TestInput.png", pImg);</font></div>
<div><font face="courier new, monospace" size="1"> inputImage->SetRequestedRegion(inputImage->GetLargestPossibleRegion());</font></div><div><font face="courier new, monospace" size="1"> inputImage->Update();</font></div>
<div><font face="courier new, monospace" size="1"><br></font></div><div><font face="courier new, monospace" size="1"><br></font></div><div><font face="courier new, monospace" size="1"> ImageType::PointType point;</font></div>
<div><font face="courier new, monospace" size="1"> point[0] = 418;</font></div><div><font face="courier new, monospace" size="1"> point[1] = 215;</font></div><div><font face="courier new, monospace" size="1"><br></font></div>
<div><font face="courier new, monospace" size="1"><br></font></div><div><font face="courier new, monospace" size="1"> ImageType::SizeType size;</font></div><div><font face="courier new, monospace" size="1"> size[0] = 75;</font></div>
<div><font face="courier new, monospace" size="1"> size[1] = 75;</font></div><div><font face="courier new, monospace" size="1"><br></font></div><div><font face="courier new, monospace" size="1"> ImageType::IndexType index;</font></div>
<div><font face="courier new, monospace" size="1"> index[0] = 375;</font></div><div><font face="courier new, monospace" size="1"> index[1] = 175;</font></div><div><font face="courier new, monospace" size="1"><br></font></div>
<div><font face="courier new, monospace" size="1"> ImageType::RegionType boundingRegion;</font></div><div><font face="courier new, monospace" size="1"> boundingRegion.SetSize(size);</font></div><div><font face="courier new, monospace" size="1"> boundingRegion.SetIndex(index);</font></div>
<div><font face="courier new, monospace" size="1"><br></font></div><div><font face="courier new, monospace" size="1"> ImageType::PixelType pixel;</font></div><div><font face="courier new, monospace" size="1"> pixel = 100;</font></div>
<div><font face="courier new, monospace" size="1"><br></font></div><div><font face="courier new, monospace" size="1"><br></font></div><div><font face="courier new, monospace" size="1"> FillLabel<ImageType > (inputImage,</font></div>
<div><font face="courier new, monospace" size="1"> point,</font></div><div><font face="courier new, monospace" size="1"> boundingRegion,</font></div><div><font face="courier new, monospace" size="1"> pixel);</font></div>
<div><font face="courier new, monospace" size="1"><br></font></div><div><font face="courier new, monospace" size="1"> // Call write image filter</font></div><div><font face="courier new, monospace" size="1"> WriteImage<ImageType > ("TestOutput.png", inputImage);</font></div>
<div><font face="courier new, monospace" size="1"> // // Call write image filter again</font></div><div><font face="courier new, monospace" size="1"> // WriteImage<ImageType > ("TestOutputCopy.png", inputImage);</font></div>
<div><font face="courier new, monospace" size="1"><br></font></div><div><font face="courier new, monospace" size="1"> return EXIT_SUCCESS;</font></div><div><font face="courier new, monospace" size="1">}</font></div><div>
<br></div><div style>// Code ends</div></div><div><br></div><div><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Jun 11, 2013 at 3:57 PM, somesh <span dir="ltr"><<a href="mailto:somesh.bbt@gmail.com" target="_blank">somesh.bbt@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr">Hi Group,<div>I have a very basic doubt regarding re-using filter. I have an application where:</div>
<div><br></div><div>a) I read an image from file</div><div><br></div><div>b) Connect it to vtk for displaying (using <span style>itkImageToVTKImageFilter.h , I use VTKImageViewer2</span></div>
<div><span style>for displaying the image)</span></div><div><span style><br></span></div><div>c) Call various filter on the input itk image and the display is updated automatically.</div>
<div>These filters can be called multiple times. All the filters are wrapped in a library.</div><div><br></div><div>For example, the input image can be a segmentation, which I connect to vtk</div><div>for displaying. And I can apply filters like dilation/connected components etc</div>
<div>on the itk segmentation image and display is updated.</div><div><br></div><div>See attached TestITKFilters.cxx. That's a very basic version of what I am doing in</div><div>the application. ReadImage/WriteImage/PasteImage are the "filters".</div>
<div><br></div><div>Here are my doubts:</div><div>a) Should I call DisconnectPipeline at lines 32/57/58 if I want to use the filters </div><div> multiple times.</div><div><br></div><div>
b) If I call DisconnectPipeline on input image inside the function, does it also disconnect </div><div> <span style>itkImageToVTKImageFilter pipeline ?</span><br></div><div><span style><br>
</span></div><div><span style>c) In the attached code, if I call WriteImage multiple times ( e.g. uncomment line 87,</span></div><div><span style>the program segfaults with the error:</span></div>
<div><span style><br></span></div><div><div><font color="#000000"><i>terminate called after throwing an instance of 'itk::ImageFileWriterException'</i></font></div><div><font color="#000000"><i> what(): /usr/local/include/ITK-4.3/itkImageFileWriter.hxx:403:</i></font></div>
<div><font color="#000000"><i>Did not get requested region!</i></font></div><div><font color="#000000"><i>Requested:</i></font></div><div><font color="#000000"><i>ImageRegion (0xbfb788b0)</i></font></div><div><font color="#000000"><i> Dimension: 2</i></font></div>
<div><font color="#000000"><i> Index: [0, 0]</i></font></div><div><font color="#000000"><i> Size: [640, 400]</i></font></div><div><font color="#000000"><i>Actual:</i></font></div><div><font color="#000000"><i>ImageRegion (0xbfb788c4)</i></font></div>
<div><font color="#000000"><i> Dimension: 2</i></font></div><div><font color="#000000"><i> Index: [0, 0]</i></font></div><div><font color="#000000"><i> Size: [0, 0]</i></font></div><div style><br></div>
</div><div><span style>I tried adding </span><font color="#000000">inputImage->SetRequestedRegion(inputImage->GetLargestPossibleRegion());,</font></div><div><font color="#000000">but it has no effect.</font></div>
<div><br></div><div><br></div><div><br></div><div>Thanks,</div><div>Somesh</div><div><br></div><div><br></div><div><div>
<br></div>
</div></div>
</blockquote></div><br></div></div></div>