[Insight-users] ImageFunction Evaluate constness

Dan Mueller dan.muel at gmail.com
Mon Dec 14 23:27:10 EST 2009


Hi Luis,

Thanks for your quick response, even it wasn't exactly the answer I
wanted. I wanted someone to tell me I was justified in abusing the
ImageFunction...oh well! :P

> Could you help us understand the algorithm ?
Obviously the overall context of my problem is somewhat complicated,
hence the omission from my original email. I'll try to explain as best
I can.

Essentially I am implementing something similar (the outcome is the
same, but the method to get there is quite different) to "propagation
freezing for thin structures" described on pp. 158-162 of Thomas
Deschamps' PhD thesis:
    http://math.lbl.gov/~deschamp/

The basic premise is as follows: (1) fast marching is prone to
"leakage," (2) for vascular/thin structures the leakage typically
occurs in regions far away from the "active" area of the propagating
front, (3) restricting the movement of the front in these regions will
prevent unwanted leakage.

With this in mind I am constructing an image function which takes as
input the current fast marching arrival function. The geodesic
distance is computed for the current point, and compared to the
maximum distance previously computed. If the maximum distance minus
the current distance is larger than some threshold (ie. the current
point is far away from the active propagation), the image function
should return small values, and vice versa.

Using the ImageFunction class to compute the current geodesic distance
is no problem. However, the issue is comparing the current distance to
the maximum distance previously computed, which obviously has to be
stored somewhere. The maximum distance is the "state" which I want to
store as a member of the ImageFunction. This image function will be
employed in a context which requires it to be invoked in a
"standalone" manner ie. it is not possible to pass in and out the
previous maximum geodesic distance. Because the function will be
invoked within a fast marching context, the operation is inherently
single-threaded.

While I am still in the "testing out some ideas" phase, in my
experience if I don't do something right the first time, I never seem
to get around to fixing it...

Thanks for any advice.

Regards, Dan

2009/12/13 Luis Ibanez <luis.ibanez at kitware.com>:
> Hi Dan,
>
>              Interesting dilemma...
>
> The short answer is:     Yes,
>
> You are abusing the Functor.    :-)
>
>
> Given that the functor is, by design, intended
> to perform pixel-wise stateless operations.
>
>
> However,
> your algorithmic needs are certainly legitimate,
> and therefore we should find a way of making
> easy to implement your algorithm.
>
>
> One option that comes to mind is the design
> used in the pairs of LevelSet Function+Filter.
>
> In particular the use of a data structure that
> is own by the filter and it is passed to the
> Function as "working space". I believe that in
> that context the motivation is mostly to deal
> with multiple threads, nonetheless, the solution
> may be applicable to your problem.
>
> You could implement a functor that at initialization
> time receives a pointer to that data structure (own
> by the Filter), and then, during the Evaluate() method
> that structure will be modified.
>
> This however, requires to mark that structure as
> "mutable", and therefore, one would think that
> we could have just made your double variable
> to be "mutable" in the first place.
>
> Using "mutable" here, however, is another design
> conflict, since "mutable" should only be used for
> values that perform caching, and not for values that
> represent "state".  In your case, it looks like you are
> really managing a "state" with this internal number.
>
> It is good that you mention the implications for
> threading as well, since, hosting state in the Functor
> will make it non-thread-safe.
>
> Could you help us understand the algorithm ?
>
> That is, please describe the algorithm that you
> want to implement, instead of describing the
> problem that you have found in one of the
> potential mechanisms of implementing such
> algorithm.
>
> It is quite likely that we may have another trick
> in store that could be used for that algorithm.
>
> ...and...
> if we don't find anything, then we should
> design something that have a lot of potential
> for reuse, as you pointed out.
>
>
>    Thanks
>
>
>          Luis
>
> ----------------------------------------------------------------
> On Sun, Dec 13, 2009 at 2:44 AM, Dan Mueller <dan.muel at gmail.com> wrote:
>> Hi Insight community,
>>
>> I am writing an ImageFunction for which the value depends on the image
>> point AND previous calls to the function.
>>
>> To implement this I have added a member variable (a double) to my
>> subclassed image function. I want to set this member variable within:
>>    virtual TOutput Evaluate( const PointType& point ) const
>>
>> I guess you can see my issue: Evaluate is marked const, so calls such as
>>    this->m_MemberVariable = 123.456;
>> do not compile. I get the following error with Visual Studio 2005:
>>    error C2166: l-value specifies const object
>>
>> Of course I can get around this using const_cast on the this pointer:
>>    MyImageFunction<TInputImage,TOutput>* function =
>>      const_cast<MyImageFunction<TInputImage,TOutput>*>( this );
>>    function->m_MemberVariable = 123.456;
>>
>> Some questions:
>> Am I abusing ImageFunction?
>> Does use of const_cast on the this pointer invoke the wrath of the
>> const-correctness police?
>> Is there a better way?
>>
>> I guess I could create my own NonConstSingleThreadedImageFunction, but
>> then I'd bring the code-reuse police knocking...
>>
>> Any suggestions appreciated.
>>
>> Regards, Dan


More information about the Insight-users mailing list