[Insight-developers] Simplifying traits

Stephen R. Aylward aylward@unc.edu
Thu, 29 Mar 2001 14:11:14 -0500


I think this is a great idea - the user has to assume some
responsibility for what they are trying to do.

Now if only we could have the image class return an iterator so as to
better resemble the stl standard....perhaps the simple region iterator
or linear iterator.   Then, some of our methods could treat an image as
it does any type of stl container.

Stephen

"Miller, James V (CRD)" wrote:
> 
> I am still leaning towards eliminating scalar traits. I would really like to get back to standard
> pointer/iterator semantics.
> 
> foo = *it;
> *it = garf;
> 
> The effect of this would be:
> 
> 1. DataAccessors would have to return a reference.  This would mean that data accessors could only be
> used to map memory (i.e. access a scalar from a pixel that held a scalar and vector).  DataAccessors
> could not be used for casting or for calculating a function of a pixel.
> 
> 2. A given filter would assume its inputs were of the correct "type".  If a filter is expecting to
> work on scalars, dereferencing an iterator would have to return a scalar.  If a filter is expecting
> to work on vectors, derefencing an iterator would have to return a vector. If an algorithm needed
> both scalars and vectors, they would be passed in as separate inputs.
> 
> The reason for leaning in this direction is that the syntax for accessing a pixel within a filter is
> getting rather complicated. Furthermore, we are having reference and const issues in the current
> framework.  Last night I was working on a line of code that read
> 
> value = (double) ScalarTraits<PixelType>::GetScalar( it.Get() );
> 
> and the compiler was giving the error:
> 
> GetScalar() cannot convert parameter 1 from "float" to "float &"
> 
> Note that this error wasn't even a const issue! Just a reference issue.
> 
> Jim
> 
> -----Original Message-----
> From: Brad King [mailto:brad.king@kitware.com]
> Sent: Friday, March 23, 2001 4:37 PM
> To: Insight Developers
> Subject: [Insight-developers] Simplifying traits
> 
> Hello, all:
> 
> Here are some ideas to consider before deciding to throw out the use of
> ScalarTraits an VectorTraits.  Our current approach is not the simplest
> approach to using traits.
> 
> We can make traits easier to use.  Consider the following filter:
> 
> template <class TInputImage, class TOutputImage>
> class MyFilter
> {
> public:
>   typedef TInputImage InputImageType;
>   typedef typename InputImageType::PixelType InputPixelType;
>   typedef ScalarTraits<InputPixelType> PixelScalarTraits;
>   typedef typename PixelScalarTraits::ScalarValueType
>           PixelScalarValueType;
> 
>   inline static PixelScalarValueType& GetPixelScalar(PixelType& p)
>     { return PixelScalarTraits::GetScalar(p); }
> 
>   inline static void SetPixelScalar(PixelType& p,
>                                     const PixelScalarValueType& v)
>     { PixelScalarTraits::SetScalar(p, v); }
> 
>   // ....
> };
> 
> Note that the function definitions can be put in ImageToImageFilter and be
> inherited into other filters.  Then, with minimal setup work, a filter
> implementation can access a Pixel's scalar value like this:
> 
> PixelScalarValueType v = GetPixelScalar(myPixel);
>   // do something to v.
> SetPixelScalar(myPixel, v);
> 
> This is in place of the current code:
> 
> typename ScalarTraits<PixelType>::ScalarValueType v =
>   ScalarTraits<PixelType>::GetScalar(myPixel);
>   // do something to v.
> ScalarTraits<PixelType>::SetScalar(myPixel, v);
> 
> Also, I have noticed that there are a bunch of extra ScalarTrait
> specializations for more than the basic types.  An example is
> "ScalarTraits< RGBPixel<float> >".  These should not be done, because if
> someone wants to use an RGBPixel with a template argument other than those
> defined in itkPixelTraits.h, they will have to figure out how to write
> their own trait specialization for it.  Currently, this can be solved (I
> think) by putting the proper typedefs (ValueType, etc) into RGBPixel and
> letting the primary template of ScalarTraits handle it from there.
> 
> The "real" way to do such a specialization of the ScalarTraits for
> RGBPixel would be to do a partial specialization:
> 
> template <typename TComponent>
> class ScalarTraits< RGBPixel<TComponent> > { /* ... */ };
> 
> Unfortunately, not all of our compilers support partial specialization, so
> we can't do this.
> 
> The other option is to not require scalar traits to be a speicalization of
> ScalarTraits at all.  If instead we make such traits a template argument,
> then any class can be defined and passed to the argument:
> 
> template <class TPixel, unsigned int VDimension,
>           class TPixelTraits = ScalarTraits<TPixel> >
> class Image
> {
> public:
>   typedef TPixel PixelType;
>   enum { Dimension = VDimension };
>   typedef TPixelTraits PixelTraits;
>   // ....
> };
> 
> Then, filters could pull the Pixel traits out of their image template
> parameters:
> 
> template <class TInputImage, class TOutputImage>
> class MyFilter
> {
> public:
>   typedef TInputImage InputImageType;
>   typedef typename InputImageType::PixelTraits InputPixelTraits;
>   // ... use traits as in previous MyFilter example.
> };
> 
> Making traits a template argument is currently the approach that the Mesh
> class uses.  It even encapsulates the "CellTraits" as a member of the
> "MeshTraits" template argument.  We could make the same relationship for
> the Image.  That is:
> 
> template <typename TPixel, unsigned int VDimension>
> class DefaultImageTraits
> {
> public:
>   typedef TPixel PixelType;
>   enum { Dimension = VDimension };
>   typedef DefaultPixelTraits<PixelType> PixelTraits;
>   // ... other useful traits?
> };
> 
> template <typename TPixel,
>           unsigned int VDimension,
>           class TImageTraits = DefaultImageTraits<TPixel, VDimension> >
> class Image
> {
> public:
>   typedef TImageTraits ImageTraits;
>   typedef typename ImageTraits::PixelType   PixelType;
>   typedef typename ImageTraits::PixelTraits PixelTraits;
> 
>   // ...
> };
> 
> Assume that we have encapsulated both the current scalar and vector traits
> into "DefaultPixelTraits".
> 
> Thoughts, anyone?
> -Brad
> 
> _______________________________________________
> Insight-developers mailing list
> Insight-developers@public.kitware.com
> http://public.kitware.com/mailman/listinfo/insight-developers
> 
> _______________________________________________
> Insight-developers mailing list
> Insight-developers@public.kitware.com
> http://public.kitware.com/mailman/listinfo/insight-developers

-- 
===============================================
Stephen R. Aylward
Assistant Professor of Radiology
Adjunct Assistant Professor of Computer Science
http://www.cs.unc.edu/~aylward
aylward@unc.edu
(919) 966-9695