Thanks for pointing this out. I agree with all your observations. I'm not sure what the correct solution is. My guess is that most of us have used the mask spatial objects of the form (a) ImageMaskSpatialObject with masked images (b) EllipsoidSpatialObject with an approximate ellipsoid defining the brain (c) BoxSpatialObject, with a cuboid ROI on the target image. <br>
<br>For RTStruct data, we've converted them to ImageMaskSpatialObject and then used them; because it simply did not seem to be a reasonable thing to represent them as PolygonSpatialObject, given how slow the IsInside() becomes. One has to do the line based voting against every polygon boundary point; and do this for every pixel and transformed pixel; and at do this at every iteration. The marginally improved precision of representing the ROI as a mesh may not to be worth the time.<br>
<br>Thanks<br>--<br>karthik<br><br><div class="gmail_quote">On Tue, Jul 13, 2010 at 2:24 PM, Jäger Andreas <span dir="ltr"><<a href="mailto:A.Jaeger@dkfz-heidelberg.de">A.Jaeger@dkfz-heidelberg.de</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<div link="blue" vlink="purple" lang="DE">
<div>
<p class="MsoNormal"><span lang="EN-US">Hi,</span></p>
<p class="MsoNormal"><span lang="EN-US"> </span></p>
<p class="MsoNormal"><span lang="EN-US">i had a problem concerning the usage of
SpatialObjects (e.g. GroupSpatialObjects, ContourSpatialObjects,
SpatialObjectTreeContainer, PolygonGroupSpatialObjects,
PolygonSpatialObjects...) to mask a specific image for the registration.</span></p>
<p class="MsoNormal"><span lang="EN-US">I think there are probably other people
doing similar stuff, and there could be interest in discussing a few
implementation decisions concerning SpatialObject child classes and the way the
MeanSquaresImageToImageMetric is processing them.</span></p>
<p class="MsoNormal"><span lang="EN-US">I use PolygonGroupSpatialObjects and
PolygonSpatialObjects to create my own Volumes of Interest and Contours out of
a set of points.</span></p>
<p class="MsoNormal"><span lang="EN-US">I use these two SpatialObject types,
because a)i import proprietary structure data, which is not pixel based (Thats
the reason why I don't use ImageMaskSpatialObject for instance).</span></p>
<p class="MsoNormal"><span lang="EN-US"> b)the MeanSquaresImageToImageMetric is not
working with any other combination of SpatialObject I tried so far (at least
for the way i nest SpatialObjects).</span></p>
<p class="MsoNormal"><span lang="EN-US"> </span></p>
<p class="MsoNormal"><span lang="EN-US">I store the Contours in PolygonSpatialObjects
and store all contours of a VOI in PolygonGroupSpatialObjects.</span></p>
<p class="MsoNormal"><span lang="EN-US">The Tree SpatialObject for all VOIs is also
a PolygonGroupSpatialObject.</span></p>
<p class="MsoNormal"><span lang="EN-US"> </span></p>
<p class="MsoNormal"><span lang="EN-US">As mentioned they are actually the only
classes I can use, that’s why I wanted to discuss the implementation of a
few other SpatialObject classes.</span></p>
<p class="MsoNormal"><span lang="EN-US"> </span></p>
<p class="MsoNormal"><span lang="EN-US">For better understanding, here a part of my
test program in pseudocode :</span></p>
<p class="MsoNormal"><span lang="EN-US"> </span></p>
<p class="MsoNormal"><span lang="EN-US">create StructureLoader</span></p>
<p class="MsoNormal"><span lang="EN-US">create RegistrationAlgorithm</span></p>
<p class="MsoNormal"><span lang="EN-US">RegistrationAlgorithm->SetFixedImg()</span></p>
<p class="MsoNormal"><span lang="EN-US">RegistrationAlgorithm->SetMovingImg()</span></p>
<p class="MsoNormal"><span lang="EN-US">RegistrationAlgorithm->SetTargetMask(StrucureLoader->getStructure())
// returns the generated tree node object</span></p>
<p class="MsoNormal"><span lang="EN-US">RegistrationAlgorithm->GetRegistration()
</span></p>
<p class="MsoNormal"><span lang="EN-US"> </span></p>
<p class="MsoNormal"><span lang="EN-US">The program delivers correct values(when
trying to determine which image regios are inside/outside the mask) only,</span></p>
<p class="MsoNormal"><span lang="EN-US">if I use the PolygonGroupSpatialObjects for
nodes(voi and voi groups) and the PolygonSpatialObjects for leaves(contours).</span></p>
<p class="MsoNormal"><span lang="EN-US"> </span></p>
<p class="MsoNormal"><span lang="EN-US">While trying to understand, why my
implementation was not working as planned with other SpacialObject classes
(e.g. GroupSpatialObjects, ContourSpatialObjects), I noticed several
implementation decisions,</span></p>
<p class="MsoNormal"><span lang="EN-US">which are responsible for the unexpected
behavior.</span></p>
<p class="MsoNormal"><span lang="EN-US">I have a few questions concerning the
implementation of
A)MeanSquaresImageToImageMetric::GetValueAndDerivative(...)/GroupSpatialObject::IsInside(...)</span></p>
<p class="MsoNormal"><span lang="EN-US"> B)PolygonSpatialObject::IsInside(...)/PolygonGroupSpatialObject::IsInside(...)</span></p>
<p class="MsoNormal"><span lang="EN-US"> </span></p>
<p class="MsoNormal"><span lang="EN-US">and hope that someone is able to explain
them to me.</span></p>
<p class="MsoNormal"><span lang="EN-US"> </span></p>
<p class="MsoNormal"><span lang="EN-US"> A)</span></p>
<p class="MsoNormal"><span lang="EN-US"> </span></p>
<p class="MsoNormal"><span lang="EN-US"> The
MeanSquaresImageToImageMetric::GetValueAndDerivative() calls the IsInside()
method without a parameter for the depth</span></p>
<p class="MsoNormal"><span lang="EN-US"> </span></p>
<p class="MsoNormal"><span lang="EN-US"> Line 178: if( this->m_FixedImageMask
&& !this->m_FixedImageMask->IsInside( inputPoint ) )</span></p>
<p class="MsoNormal"><span lang="EN-US"> </span></p>
<p class="MsoNormal"><span lang="EN-US"> which has the effect that for all SpatialObject
classes(at least as far as i know) the default depth=0 is used.</span></p>
<p class="MsoNormal"><span lang="EN-US"> </span></p>
<p class="MsoNormal"><span lang="EN-US"> --> Was this implementation done with
respect to the usage of SpatialObjects?</span></p>
<p class="MsoNormal"><span lang="EN-US"> I would assume if someone who is using
SpatialObject would probably like to use the feature of creating tree like
structures by nesting objects,</span></p>
<p class="MsoNormal"><span lang="EN-US"> but actually there are not many
SpatialObjects which really check for existing childern, and rather use a depth
= 0 as default?</span></p>
<p class="MsoNormal"><span lang="EN-US"> e.g. GroupSpatialObjects (i think this
class is a good example, because you would expect a different behavior)</span></p>
<p class="MsoNormal"><span lang="EN-US"> GroupSpatialObject has no own
implementation of IsInside()</span></p>
<p class="MsoNormal"><span lang="EN-US"> So the IsInside() Method checks as follows</span></p>
<p class="MsoNormal"><span lang="EN-US"> </span></p>
<p class="MsoNormal"><span lang="EN-US"> if( depth > 0 )</span></p>
<p class="MsoNormal"><span lang="EN-US"> {</span></p>
<p class="MsoNormal"><span lang="EN-US"> do something</span></p>
<p class="MsoNormal"><span lang="EN-US"> }</span></p>
<p class="MsoNormal"><span lang="EN-US"> else </span></p>
<p class="MsoNormal"><span lang="EN-US"> return false</span></p>
<p class="MsoNormal"><span lang="EN-US"> </span></p>
<p class="MsoNormal"><span lang="EN-US"> --> reasonable you always get false,
when MeanSquaresImageToImageMetric::GetValueAndDerivative(...) checks the
points of the image!</span></p>
<p class="MsoNormal"><span lang="EN-US"> Wouldn't it make more sense not to use the
default IsInside implementation, because assuming a default depth=0 for
GroupSpatialObjects seems to make no real sense.</span></p>
<p class="MsoNormal"><span lang="EN-US"> I can't really imagine, why someone should
use a GroupSpatialObject with a depth of zero (for instance there could be a
check of the childrenList if depth = 0 is passed).</span></p>
<p class="MsoNormal"><span lang="EN-US"> </span></p>
<p class="MsoNormal"><span lang="EN-US"> This is actually one reason why I use
PolygonGroupSpatialObjects, because it was the only class I could find, which
assumes it has children.</span></p>
<p class="MsoNormal"><span lang="EN-US"> I didn't check other metrics so far, so i
don't know if they behave the same way.</span></p>
<p class="MsoNormal"><span lang="EN-US"> </span></p>
<p class="MsoNormal"><span lang="EN-US"> B)</span></p>
<p class="MsoNormal"><span lang="EN-US"> </span></p>
<p class="MsoNormal"><span lang="EN-US"> For testing purposes I wanted to use only
one contour of a VOI, for faster processing</span></p>
<p class="MsoNormal"><span lang="EN-US"> pseudocode:</span></p>
<p class="MsoNormal"><span lang="EN-US"> RegistrationAlgorithm->setTargetMask(structureLoader.getContourSpatialObject()->GetFirstVOI()->GetFirstContour());</span></p>
<p class="MsoNormal"><span lang="EN-US"> </span></p>
<p class="MsoNormal"><span lang="EN-US"> I noticed, that if you use a
PolygonSpecialObject without a PolygonGroupSpatialObjects, you get wrong return
values for IsInside(),</span></p>
<p class="MsoNormal"><span lang="EN-US"> because there is no z-dimension check in
the PolygonSpecialObject::IsInside(...) method.</span></p>
<p class="MsoNormal"><span lang="EN-US"> So if s.o. directly calls the
PolygonSpecialObject::IsInside() method, he gets true for the points even if
they are in an other plane than the polygon.</span></p>
<p class="MsoNormal"><span lang="EN-US"> </span></p>
<p class="MsoNormal"><span lang="EN-US"> this behavour forces you to use a
PolygonGroupSpatialObject even if you would just have 1 PolygonSpecialObject
inside.</span></p>
<p class="MsoNormal"><span lang="EN-US"> Can someone explain me, why
PolygonSpecialObject was implemented that way? I think it is quite cofusing for
someone, who works with theses classes the first time, because IsInside just
doesn't behave as you would expect.</span></p>
<p class="MsoNormal"><span lang="EN-US"> </span></p>
<p class="MsoNormal"><span lang="EN-US"> compare itkPolygonSpatialObject.txx Line
403-485</span></p>
<p class="MsoNormal"><span lang="EN-US"> </span></p>
<p class="MsoNormal"><span lang="EN-US">If I take a look at how
MeanSquaresImageToImageMetric is using the IsInside() method, and the way
method is implemented in the different classes, I somehow miss the
"thread" in the way the parts are designed.</span></p>
<p class="MsoNormal"><span lang="EN-US">But perhaps I just don't get the concept, I
would appreciate it if someone could elucidate it for me ;). If someone thinks
the way I build my Structures is a unfavorable solution, hints and tips are
always welcome!</span></p>
<p class="MsoNormal"><span lang="EN-US"> </span></p>
<p class="MsoNormal">Best regards</p>
<p class="MsoNormal">Andreas</p>
</div>
</div>
<br>_____________________________________<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></blockquote></div><br>