[Insight-users] ImageFunction Evaluate constness

Luis Ibanez luis.ibanez at kitware.com
Mon Dec 21 19:18:56 EST 2009


Hi Dan,

Thanks for the additional details on the algorithm.

It looks like you could benefit from using the same
trick that LevelSet filters use for storing a data
structure that is to be shared by multiple-threads.

You may want to take a look at the LevelSetFunction
and its interactions with the LevelSetFilters. In particular,
look at the Global data structure....

   It may help you with the design of your filter....


         Regards,


                 Luis


---------------------------------------------------
On Mon, Dec 14, 2009 at 11:27 PM, Dan Mueller <dan.muel at gmail.com> wrote:
> 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