Hi Louis,<div><br></div><div>Thanks very much for spotting the failure point. I realized that it was due to the missing VRadius. I appreciate your comments on the coding improvement.</div><div><br></div><div>I got the original code from online. I would be very happy to share it with the insight community if I were the original author. Here is the link to the code just in case you want to contact them:</div>
<div><br></div><div><a href="http://www.perlproductions.at/index.php?choice=referenz&lang=en&id=15">http://www.perlproductions.at/index.php?choice=referenz&lang=en&id=15</a></div><div><br></div><div>Thanks,</div>
<div><br></div><div>Ming<br><br><div class="gmail_quote">On Fri, Dec 11, 2009 at 5:19 PM, Luis Ibanez <span dir="ltr"><<a href="mailto:luis.ibanez@kitware.com">luis.ibanez@kitware.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
Hi Ming,<br>
<br>
Thanks for posting your code.<br>
<br>
<br>
The error is that you are not calling<br>
the method that sets the VRadius value.<br>
<br>
<br>
That's why you get the error message:<br>
<div class="im"><br>
<br>
"Member variable VRadius<br>
not properly initialized."<br>
<br>
<br>
</div>You simply need to add:<br>
<br>
filter->SetVRadius( 1 );<br>
<br>
before you make the call to Update();<br>
<br>
...<br>
<br>
Of course,<br>
you may want to try values of "VRadius"<br>
different from 1.<br>
<br>
<br>
BTW: doing<br>
<br>
"using namespace std;"<br>
<br>
is a really bad practice.<br>
<br>
Opening a namespace defeats the purpose<br>
of having namespaces at all.<br>
<br>
<br>
Please get used to typing:<br>
<br>
std::string<br>
std::cout<br>
std::cerr<br>
std::endl<br>
<br>
and so on....<br>
<br>
<br>
<br>
Also, please note that the implementation of<br>
templated classes shouldn't be put in .cpp files.<br>
We usually put this in .txx files.<br>
<br>
Please find attached the three files fixed<br>
along with a CMakeLists.txt file.<br>
<br>
<br>
BTW: your code was missing several<br>
essential lines of code, such as includes<br>
for ImageFileReader, ImageFileWriter and<br>
the ShepLogan filter itself.<br>
<br>
<br>
We strongly encourage you to share this<br>
filter with the ITK community by submitting<br>
it to the Insight Journal :-)<br>
<br>
<a href="http://www.insight-journal.org/" target="_blank">http://www.insight-journal.org/</a><br>
<br>
<br>
<br>
Regards,<br>
<br>
Luis<br>
<br>
<br>
-------------------------------<br>
<div><div></div><div class="h5">On Tue, Dec 8, 2009 at 6:19 PM, Ming Chao <<a href="mailto:mingchao2005@gmail.com">mingchao2005@gmail.com</a>> wrote:<br>
> Hi,<br>
> I got a code of SheppLoganFilter and used it to filter a raw sinogram image<br>
> (I am not sure if this is a correct use though). However, I got the<br>
> following error:<br>
> writing image image/test2.png caused a problem.<br>
> itk::ExceptionObject (0122FEC4)<br>
> Location: "void __thiscall itk::MultiThreader::SingleMethodExecute(void)"<br>
> File: \ITK\InsightToolkit-3.8.0\Code\Common\itkMultiThreader.cxx<br>
> Line: 429<br>
> Description: itk::ERROR: MultiThreader(01870068): Exception occurred during<br>
> Sing<br>
> leMethodExecute<br>
> c:\my rsch work\image reconstruction\code\SheppLoganFilter.cpp:27:<br>
> itk::ERROR: SheppLoganFilter(0177DD28): Member variable VRadius not properly<br>
> ini<br>
> tialized.<br>
><br>
> The codes I used are attached in the following. Any<br>
> comments/suggestions/help would be greatly appreciated.<br>
><br>
> The main function:<br>
> #include "itkImage.h"<br>
> using namespace std;<br>
> int main(int argc, char* argv[])<br>
> {<br>
> string filename("image/test.png");<br>
> string filename2("image/test2.png");<br>
> typedef unsigned char uchar;<br>
> typedef uchar PixelType;<br>
> const int Dimension = 2;<br>
> typedef itk::Image< PixelType, 2 > ImageType;<br>
><br>
> //reading image from disk<br>
> typedef itk::ImageFileReader< ImageType > ReaderType;<br>
> ReaderType::Pointer reader = ReaderType::New();<br>
> reader->SetFileName(filename);<br>
> reader->Update();<br>
> ImageType::Pointer input_image = ImageType::New();<br>
> input_image = reader->GetOutput();<br>
> typedef SheppLoganFilter<ImageType, ImageType> FilterType;<br>
> FilterType::Pointer filter = FilterType::New();<br>
> filter->SetInput(input_image);<br>
> typedef itk::ImageFileWriter< ImageType > WriterType;<br>
> WriterType::Pointer writer = WriterType::New();<br>
> writer->SetInput(filter->GetOutput());<br>
> writer->SetFileName(filename2);<br>
> try {<br>
> writer->Update();<br>
> }<br>
> catch( itk::ExceptionObject exp )<br>
> {<br>
> cerr << "writing image " << filename2 << " caused a problem." << endl;<br>
> cerr << exp << endl;<br>
> return 1;<br>
> }<br>
> }<br>
> The SheppLoganFilter.h:<br>
><br>
> #ifndef __SheppLoganFilter_h<br>
> #define __SheppLoganFilter_h<br>
> #include <vector><br>
><br>
> //ITK includes<br>
> #include "itkImageToImageFilter.h"<br>
> #include "itkImageRegionIterator.h"<br>
> #include "itkConstNeighborhoodIterator.h"<br>
> #include "itkOffset.h"<br>
> /*!<br>
> * \class SheppLoganFilter<br>
> * \brief Applies a shepp logan filter to an image and returns the filtered<br>
> image.<br>
> */<br>
> template < typename TInputImage, typename TOutputImage ><br>
> class SheppLoganFilter : public itk::ImageToImageFilter< TInputImage,<br>
> TOutputImage ><br>
> {<br>
> public:<br>
> /*! Standard class typedefs. */<br>
> typedef SheppLoganFilter Self;<br>
> typedef itk::ImageToImageFilter< TInputImage, TOutputImage > Superclass;<br>
> typedef itk::SmartPointer< Self > Pointer;<br>
> typedef itk::SmartPointer< const Self > ConstPointer;<br>
> /*! Method for creation through object factory */<br>
> itkNewMacro(Self);<br>
> /*! Run-time type information (and related methods) */<br>
> itkTypeMacro(SheppLoganFilter, ImageToImageFilter);<br>
> //Convenience typedefs<br>
> typedef TInputImage ImageType;<br>
> typedef TOutputImage OImageType;<br>
> typedef typename ImageType::RegionType RegionType;<br>
> typedef itk::ConstNeighborhoodIterator< ImageType ><br>
> NeighborhoodIteratorType;<br>
> typedef itk::ImageRegionIterator< OImageType> IteratorType;<br>
> typedef typename ImageType::ConstPointer ImageConstPointer;<br>
> typedef typename OImageType::Pointer ImagePointer;<br>
> /*! Extract dimension from input and output image. */<br>
> itkStaticConstMacro(ImageDimension, unsigned int,<br>
> TInputImage::ImageDimension);<br>
> itkSetMacro(VRadius, int);<br>
> itkGetConstReferenceMacro(VRadius, int);<br>
> protected:<br>
> SheppLoganFilter();<br>
> virtual ~SheppLoganFilter() {}<br>
> /*! Standard "PrintSelf" method */<br>
> void PrintSelf(std::ostream& os, itk::Indent indent) const;<br>
> /*!<br>
> * SheppLoganFilter can be implemented as a<br>
> * multithreaded filter. Therefore, this implementation provides<br>
> * a ThreadedGenerateData() routine which is called for each<br>
> * processing thread. The output image data is allocated<br>
> * automatically by the superclass prior to calling<br>
> * ThreadedGenerateData(). ThreadedGenerateData can only<br>
> * write to the portion of the output image specified by the<br>
> * parameter "outputRegionForThread".<br>
> *<br>
> * \sa ImageToImageFilter::ThreadedGenerateData(),<br>
> * ImageToImageFilter::GenerateData()<br>
> */<br>
> void ThreadedGenerateData(const RegionType& regionForThread,<br>
><br>
> int threadId );<br>
> private:<br>
> SheppLoganFilter(const Self&) {}; //purposely not implemented<br>
> void operator=(const Self&); //purposely not implemented<br>
> /*! vertical radius of shepp logan filter */<br>
> int m_VRadius;<br>
> };<br>
><br>
> #ifndef ITK_MANUAL_INSTANTIATION<br>
> #include "SheppLoganFilter.cpp"<br>
> #endif<br>
> #endif<br>
> And the SheppLoganFilter.cpp:<br>
> #ifndef _SheppLoganFilter_txx<br>
> #define _SheppLoganFilter_txx<br>
> #include "SheppLoganFilter.h"<br>
> #ifndef PI<br>
> #define PI 3.141592653<br>
> #endif<br>
> template < typename TInputImage, typename TOutputImage ><br>
> SheppLoganFilter< TInputImage, TOutputImage >::SheppLoganFilter()<br>
> {<br>
> m_VRadius = 0;<br>
> }<br>
> template < typename TInputImage, typename TOutputImage ><br>
> void SheppLoganFilter< TInputImage, TOutputImage ><br>
> ::ThreadedGenerateData(const RegionType&<br>
> regionForThread, int threadId )<br>
> {<br>
> if(m_VRadius <= 0)<br>
> itkExceptionMacro(<< "Member variable VRadius not properly initialized.");<br>
> //pointers to output and input image<br>
> ImageConstPointer inputImage = this->GetInput();<br>
> ImagePointer outputImage = this->GetOutput();<br>
> RegionType inputRegion = inputImage->GetLargestPossibleRegion();<br>
> RegionType outputRegion = outputImage->GetLargestPossibleRegion();<br>
> IteratorType out(outputImage, outputRegion);<br>
> NeighborhoodIteratorType::RadiusType radius;<br>
> radius.Fill(0);<br>
> radius[1] = m_VRadius;<br>
> int vDim = m_VRadius*2+1;<br>
> NeighborhoodIteratorType it(radius, inputImage, inputRegion);<br>
> //pointer to Shepp-Logan filter weights<br>
> float *sl = new float[vDim];<br>
> //vector with the OffsetTypes for the neighborhood iterator<br>
> std::vector< NeighborhoodIteratorType::OffsetType > offset;<br>
> int actIndex;<br>
> for(int i = -m_VRadius; i <= m_VRadius; ++i)<br>
> {<br>
> actIndex = i + m_VRadius;<br>
> *(sl+actIndex) = -2.0/(PI*PI*(4*i*i-1));<br>
> NeighborhoodIteratorType::OffsetType tmpO = {{0,i}};<br>
> offset.push_back(tmpO);<br>
> }<br>
> std::vector< int > tmpImg;<br>
> for (it.GoToBegin(), out.GoToBegin(); !it.IsAtEnd(); ++it, ++out)<br>
> {<br>
> float sum = 0;<br>
> for(int i = 0; i < m_VRadius*2+1; ++i)<br>
> {<br>
> sum += *(sl+i) * it.GetPixel(offset[i]);<br>
> }<br>
> tmpImg.push_back(sum);<br>
> }<br>
> int i = 0;<br>
> for (it.GoToBegin(), out.GoToBegin(); !it.IsAtEnd(); ++it, ++out)<br>
> {<br>
> out.Set(tmpImg[i++]);<br>
> }<br>
> }<br>
><br>
> template < typename TInputImage, typename TOutputImage><br>
> void SheppLoganFilter< TInputImage, TOutputImage >::PrintSelf(std::ostream&<br>
> os, itk::Indent indent) const<br>
> {<br>
> Superclass::PrintSelf(os,indent);<br>
> os << "VRadius = " << m_VRadius << std::endl;<br>
> }<br>
><br>
> #endif<br>
><br>
><br>
</div></div>> _____________________________________<br>
> Powered by <a href="http://www.kitware.com" target="_blank">www.kitware.com</a><br>
><br>
> Visit other Kitware open-source projects at<br>
> <a href="http://www.kitware.com/opensource/opensource.html" target="_blank">http://www.kitware.com/opensource/opensource.html</a><br>
><br>
> Kitware offers ITK Training Courses, for more information visit:<br>
> <a href="http://www.kitware.com/products/protraining.html" target="_blank">http://www.kitware.com/products/protraining.html</a><br>
><br>
> Please keep messages on-topic and check the ITK FAQ at:<br>
> <a href="http://www.itk.org/Wiki/ITK_FAQ" target="_blank">http://www.itk.org/Wiki/ITK_FAQ</a><br>
><br>
> Follow this link to subscribe/unsubscribe:<br>
> <a href="http://www.itk.org/mailman/listinfo/insight-users" target="_blank">http://www.itk.org/mailman/listinfo/insight-users</a><br>
><br>
><br>
</blockquote></div><br></div>