[Insight-developers] ImageToImageFilter: dimension reductionp roblem

Miller, James V (Research) millerjv@crd.ge.com
Mon, 29 Apr 2002 10:10:24 -0400


Wilson,

I am guessing the problem here is that the function object ivar m_RegionCopier
is held as an instance of an ImageRegionCopier as opposed to a "reference
to" or a "pointer to" an ImageRegionCopier.  So the SetRegionCopier() method
is casting your subclass back to the baseclass and copying it into the baseclass
type.  It must be loosing the virtual function table.

I tried to model the RegionCopier after STL.  Specifically, the priority_queue
class (snippet below) has an ivar of type std::less<> but allows the value of 
this function object to be overridden at constructor time. Truthfully, I am surprised that this works
in STL.  I would have thought that passing in a subclass to 
std::less<> would still end up calling std::less<>::operator() and not the 
subclass's version.  Perhaps the only reason STL allows you to override this 
function object at constructor time is to allow you to use a function object 
which is a subclass of less that carries around additional information but 
still uses std::less<>::operator() for the call operator. If STL does allow
you to reroute the function object's call operator by passing in a subclass
of std::less at constructor time, then the difference between STL and the RegionCopier
is that STL calls the function object's copy constructor where we are calling
the RegionCopier's operator=().

Unless someone has another idea, I would suggest making the RegionCopier ivar
a pointer (smart pointer?) to a RegionCopier.

A less optimal solution be to change line 137 of ImageToImageFilter.txx from

m_RegionCopier(inputRegion, this->GetOutput()->GetRequestedRegion());

to

this->CallRegionCopier(inputRegion, this->GetOutput()->GetRequestedRegion());

where CallRegionCopier() is a virual method in ImageToImageFilter which has the 
original line 137 of ImageToImageFilter.txx as its implementation. ExtractImageFilter
would override the CallRegionCopier() method and use an ExtractImageFilterDetail
instead of the standard region copier. This is the "less optimal" solution because
the ExtractImageFilter ends up with two ivars for the RegionCopier.  It could
get confusing as to which ivar is used when...

(By the by, I think your class should be called ExtractImageFilterRegionCopier
and not ExtractImageFilterDetail (as shown in your code snippets)).

  

		// TEMPLATE CLASS priority_queue
template<class _Ty, class _C = vector<_Ty>,
	class _Pr = less<_C::value_type> >
	class priority_queue {
public:
	typedef _C::allocator_type allocator_type;
	typedef _C::value_type value_type;
	typedef _C::size_type size_type;
	explicit priority_queue(const _Pr& _X = _Pr(),
		const allocator_type& _Al = allocator_type())
		: c(_Al), comp(_X) {}
	typedef const value_type *_It;
	priority_queue(_It _F, _It _L, const _Pr& _X = _Pr(),
		const allocator_type& _Al = allocator_type())
		: c(_Al), comp(_X)
		{for (; _F != _L; ++_F)
			push(*_F); }
	allocator_type get_allocator() const
		{return (c.get_allocator()); }
	bool empty() const
		{return (c.empty()); }
	size_type size() const
		{return (c.size()); }
	value_type& top()
		{return (c.front()); }
	const value_type& top() const
		{return (c.front()); }
	void push(const value_type& _X)
		{c.push_back(_X);
		push_heap(c.begin(), c.end(), comp); }
	void pop()
		{pop_heap(c.begin(), c.end(), comp);
		c.pop_back(); }
protected:
	_C c;
	_Pr comp;
	};


-----Original Message-----
From: Wilson Chang [mailto:wmcst6+@pitt.edu]
Sent: Friday, April 26, 2002 4:18 PM
To: Insight-developers (E-mail)
Subject: Re: [Insight-developers] ImageToImageFilter: dimension
reductionproblem


Within the ImageToImageFilterDetail namespace, I have been trying to make a
class called ExtractImageRegionCopier that derives from ImageRegionCopier:

  template <unsigned int D1, unsigned int D2>
  class ITK_EXPORT ExtractImageFilterDetail: public ImageRegionCopier<D1,
D2>
  {

  public:
    void operator() (ImageRegion<D1> &destRegion,
                     const ImageRegion<D2> &srcRegion) const
    {
      std::cout<<"ExtractImageFilterDetail call"<<std::endl;
      ExtractImageCopyRegion<D1, D2>(BinaryUnsignedIntDispatch<D1,
D2>::ComparisonType(),
                         destRegion, srcRegion);
    }
  };

In the ExtractImageFilter class:

  typedef
    ImageToImageFilterDetail::ExtractImageFilterDetail<InputImageDimension,
                     OutputImageDimension> ExtractImageFilterDetailType;

and in ExtractImageFilter's constructor:

this->SetRegionCopier(m_ExtractImageRegionCopier);

But for some reason, all of the to "CopyRegion()" are getting routed to the
parent class ImageRegionCopier and not the child class
ExtractImageRegionCopier.
Ideas?
Does this have somethign to do with the fact that the "SetRegionCopier" call
expects a type of ImageRegionCopier, and not a child class?

wilson



_______________________________________________
Insight-developers mailing list
Insight-developers@public.kitware.com
http://public.kitware.com/mailman/listinfo/insight-developers