<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=Content-Type content="text/html; charset=gb2312">
<META content="MSHTML 6.00.2900.3020" name=GENERATOR>
<STYLE>
<!--
/* Font Definitions */
@font-face
{font-family:宋体;
panose-1:2 1 6 0 3 1 1 1 1 1;}
@font-face
{font-family:Verdana;
panose-1:2 11 6 4 3 5 4 4 2 4;}
@font-face
{font-family:"\@宋体";
panose-1:2 1 6 0 3 1 1 1 1 1;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
font-size:10.5pt;
font-family:"Times New Roman";}
a:link, span.MsoHyperlink
{color:blue;
text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
{color:purple;
text-decoration:underline;}
span.EmailStyle17
{mso-style-type:personal-compose;
font-family:Verdana;
color:windowtext;
font-weight:normal;
font-style:normal;
text-decoration:none none;}
/* Page Definitions */
@page Section1
{size:595.3pt 841.9pt;
margin:72.0pt 90.0pt 72.0pt 90.0pt;
layout-grid:15.6pt;}
div.Section1
{page:Section1;}
-->
</STYLE>
</HEAD>
<BODY>
<DIV><FONT face=Verdana size=2>Hi Patrick,</FONT></DIV>
<DIV><FONT face=Verdana size=2></FONT> </DIV>
<DIV><FONT face=Verdana size=2>The trick do solve the problem.</FONT></DIV>
<DIV><FONT face=Verdana size=2></FONT> </DIV>
<DIV><FONT face=Verdana size=2>It seems that the code may be put into
ResetRegistrationProcessing(),</FONT></DIV>
<DIV><FONT face=Verdana size=2></FONT> </DIV>
<DIV><FONT face=Verdana size=2> m_Transform = NULL;
<DIV> m_Transform = TransformType::New();</DIV>
<DIV> </DIV>
<DIV>Thank you very much!</DIV>
<DIV> </DIV>
<DIV>Fucang</DIV>
<DIV> </DIV></FONT></DIV>
<DIV><FONT face=Verdana size=2>
<HR>
</FONT></DIV>
<DIV><FONT face=Verdana size=2><STRONG></STRONG></FONT> </DIV>
<DIV><FONT face=Verdana size=2>
<DIV>Hi Fucang,</DIV>
<DIV> </DIV>
<DIV>I found the cause of this issue.</DIV>
<DIV> </DIV>
<DIV>Around line 337 in igstkLandmark3DRegistration class,</DIV>
<DIV> m_TransformInitializer-
>SetFixedLandmarks(m_TrackerLandmarks);</DIV>
<DIV> m_TransformInitializer-
>SetMovingLandmarks(m_ImageLandmarks);</DIV>
<DIV> m_TransformInitializer-
>SetTransform( m_Transform );</DIV>
<DIV> </DIV>
<DIV>If I change this into:</DIV>
<DIV> m_TransformInitializer-
>SetFixedLandmarks(m_TrackerLandmarks);</DIV>
<DIV> m_TransformInitializer-
>SetMovingLandmarks(m_ImageLandmarks);</DIV>
<DIV> m_Transform = NULL;</DIV>
<DIV> m_Transform = TransformType::New();</DIV>
<DIV> m_TransformInitializer-
>SetTransform( m_Transform );</DIV>
<DIV> </DIV>
<DIV>Your code will give a consistent result.</DIV>
<DIV> </DIV>
<DIV>The igstkLandmark3DRegistration uses</DIV>
<DIV>itkLandmarkBaseTransformInitializer.txx inside. I thought</DIV>
<DIV> m_TransformInitializer-
>SetTransform( m_Transform );</DIV>
<DIV>is just passing a pointer to store the resulting transform.</DIV>
<DIV>But in the itkLandmarkBaseTransformInitializer.txx class line 123.</DIV>
<DIV> RotationCenterType rotationCenter = transform-
>GetCenter();</DIV>
<DIV>So it's using the center of the transform as the rotation center. I</DIV>
<DIV>don't quite understand this algorithm.</DIV>
<DIV> </DIV>
<DIV>So when you reuse the igstkLandmark3DRegistration, because m_Transform</DIV>
<DIV>in this class, stores the results from last registration, so you are</DIV>
<DIV>passing a different m_Transform to the m_TransformInitializer, that's</DIV>
<DIV>why it's giving a different results.</DIV>
<DIV> </DIV>
<DIV>I still don't quite understand why it's behaving like that. Maybe ITK</DIV>
<DIV>guru can answer this question?</DIV>
<DIV> </DIV>
<DIV>Thank you,</DIV>
<DIV>Patrick</DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV>jiafucang@126.com wrote:</DIV>
<DIV>> </DIV>
<DIV>> Hi,</DIV>
<DIV>> </DIV>
<DIV>> I encoutered a strange problem. I need to reuse landmark registration </DIV>
<DIV>> for several times.</DIV>
<DIV>> In FourViewsTrackingWithCT application, I see that when the second set </DIV>
<DIV>> of image and tracker</DIV>
<DIV>> landmarks were set, the landmark registration could not give the correct </DIV>
<DIV>> result.</DIV>
<DIV>> </DIV>
<DIV>> Here is an example, could anyone find anything wrong in the following code?</DIV>
<DIV>> </DIV>
<DIV>> </DIV>
<DIV>> #if defined(_MSC_VER)</DIV>
<DIV>> #pragma warning( disable : 4786 )</DIV>
<DIV>> #endif</DIV>
<DIV>> #include <iostream ></DIV>
<DIV>> #include "igstkLandmark3DRegistration.h"</DIV>
<DIV>> #include "igstkLandmark3DRegistrationErrorEstimator.h"</DIV>
<DIV>> #include "itkLogger.h"</DIV>
<DIV>> #include "itkStdStreamLogOutput.h"</DIV>
<DIV>> #include "itkObject.h"</DIV>
<DIV>> #include "itkCommand.h"</DIV>
<DIV>> #include "itkMacro.h"</DIV>
<DIV>> #include "igstkEvents.h"</DIV>
<DIV>> #include "igstkTransform.h"</DIV>
<DIV>> </DIV>
<DIV>> class Landmark3DRegistrationGetTransformCallback: public itk::Command</DIV>
<DIV>> {</DIV>
<DIV>> public:</DIV>
<DIV>> typedef Landmark3DRegistrationGetTransformCallback Self;</DIV>
<DIV>> typedef itk::SmartPointer <Self
> Pointer;</DIV>
<DIV>> typedef itk::Command Superclass;</DIV>
<DIV>> itkNewMacro(Self);</DIV>
<DIV>> </DIV>
<DIV>> typedef igstk::TransformModifiedEvent TransformModifiedEventType;</DIV>
<DIV>> </DIV>
<DIV>> void Execute( const itk::Object *caller, const itk::EventObject & event )</DIV>
<DIV>> {</DIV>
<DIV>> }</DIV>
<DIV>> </DIV>
<DIV>> void Execute( itk::Object *caller, const itk::EventObject & event )</DIV>
<DIV>> {</DIV>
<DIV>> std::cout <
< " TransformEvent is thrown" <
< std::endl;</DIV>
<DIV>> const TransformModifiedEventType * transformEvent =</DIV>
<DIV>> dynamic_cast
< const TransformModifiedEventType*
> ( &event );</DIV>
<DIV>> m_Transform = transformEvent-
>Get();</DIV>
<DIV>> m_EventReceived = true;</DIV>
<DIV>> }</DIV>
<DIV>> bool GetEventReceived()</DIV>
<DIV>> {</DIV>
<DIV>> return m_EventReceived;</DIV>
<DIV>> }</DIV>
<DIV>> igstk::Transform GetTransform()</DIV>
<DIV>> {</DIV>
<DIV>> return m_Transform;</DIV>
<DIV>> } </DIV>
<DIV>> protected:</DIV>
<DIV>> </DIV>
<DIV>> Landmark3DRegistrationGetTransformCallback() </DIV>
<DIV>> {</DIV>
<DIV>> m_EventReceived = true;</DIV>
<DIV>> }</DIV>
<DIV>> </DIV>
<DIV>> private:</DIV>
<DIV>> bool m_EventReceived;</DIV>
<DIV>> igstk::Transform m_Transform;</DIV>
<DIV>> };</DIV>
<DIV>> int main( int argv, char * argc[] )</DIV>
<DIV>> {</DIV>
<DIV>> </DIV>
<DIV>> </DIV>
<DIV>> </DIV>
<DIV>> igstk::RealTimeClock::Initialize();</DIV>
<DIV>> </DIV>
<DIV>> </DIV>
<DIV>> typedef itk::Logger LoggerType;</DIV>
<DIV>> typedef itk::StdStreamLogOutput LogOutputType;</DIV>
<DIV>> </DIV>
<DIV>> typedef igstk::Landmark3DRegistration</DIV>
<DIV>> Landmark3DRegistrationType;</DIV>
<DIV>> typedef igstk::Landmark3DRegistration::LandmarkPointContainerType</DIV>
<DIV>> LandmarkPointContainerType;</DIV>
<DIV>> typedef igstk::Landmark3DRegistration::LandmarkImagePointType</DIV>
<DIV>> LandmarkImagePointType;</DIV>
<DIV>> typedef igstk::Landmark3DRegistration::LandmarkTrackerPointType</DIV>
<DIV>> LandmarkTrackerPointType;</DIV>
<DIV>> typedef Landmark3DRegistrationType::TransformType::OutputVectorType</DIV>
<DIV>> OutputVectorType;</DIV>
<DIV>> typedef igstk::Transform TransformType;</DIV>
<DIV>> </DIV>
<DIV>> </DIV>
<DIV>> </DIV>
<DIV>> Landmark3DRegistrationType::Pointer landmarkRegister =</DIV>
<DIV>> Landmark3DRegistrationType::New();</DIV>
<DIV>> </DIV>
<DIV>> LandmarkImagePointType imagePoint;</DIV>
<DIV>> LandmarkTrackerPointType trackerPoint;</DIV>
<DIV>> </DIV>
<DIV>> </DIV>
<DIV>> </DIV>
<DIV>> typedef itk::VersorRigid3DTransform <double
> </DIV>
<DIV>> VersorRigid3DTransformType;</DIV>
<DIV>> typedef VersorRigid3DTransformType::ParametersType ParametersType;</DIV>
<DIV>> </DIV>
<DIV>> TransformType transform;</DIV>
<DIV>> ParametersType parameters(6);</DIV>
<DIV>> </DIV>
<DIV>> </DIV>
<DIV>> Landmark3DRegistrationGetTransformCallback::Pointer lrtcb =</DIV>
<DIV>> Landmark3DRegistrationGetTransformCallback::New();</DIV>
<DIV>> landmarkRegister-
>AddObserver( igstk::TransformModifiedEvent(), lrtcb );</DIV>
<DIV>> </DIV>
<DIV>> typedef igstk::Landmark3DRegistrationErrorEstimator ErrorEstimatorType;</DIV>
<DIV>> </DIV>
<DIV>> typedef ErrorEstimatorType::TargetPointType TargetPointType;</DIV>
<DIV>> typedef ErrorEstimatorType::ErrorType ErrorType;</DIV>
<DIV>> </DIV>
<DIV>> ErrorType landmarkRegistrationError;</DIV>
<DIV>> </DIV>
<DIV>> // test landmark registration reuse</DIV>
<DIV>> if(1)</DIV>
<DIV>> {</DIV>
<DIV>> imagePoint[0] = 78.3163;</DIV>
<DIV>> imagePoint[1] = 15.3252;</DIV>
<DIV>> imagePoint[2] = 16;</DIV>
<DIV>> landmarkRegister-
>RequestAddImageLandmarkPoint(imagePoint);</DIV>
<DIV>> </DIV>
<DIV>> trackerPoint[0] = 199.274;</DIV>
<DIV>> trackerPoint[1] = -26.6466;</DIV>
<DIV>> trackerPoint[2] = -869.895;</DIV>
<DIV>> landmarkRegister-
>RequestAddTrackerLandmarkPoint(trackerPoint);</DIV>
<DIV>> </DIV>
<DIV>> imagePoint[0] = 12.5937;</DIV>
<DIV>> imagePoint[1] = 9.9381;</DIV>
<DIV>> imagePoint[2] = 16;</DIV>
<DIV>> landmarkRegister-
>RequestAddImageLandmarkPoint(imagePoint);</DIV>
<DIV>> </DIV>
<DIV>> trackerPoint[0] = 218.485;</DIV>
<DIV>> trackerPoint[1] = -2.90349;</DIV>
<DIV>> trackerPoint[2] = -882.859;</DIV>
<DIV>> landmarkRegister-
>RequestAddTrackerLandmarkPoint(trackerPoint);</DIV>
<DIV>> </DIV>
<DIV>> </DIV>
<DIV>> imagePoint[0] = 45.3473;</DIV>
<DIV>> imagePoint[1] = 7.78325;</DIV>
<DIV>> imagePoint[2] = 60;</DIV>
<DIV>> landmarkRegister-
>RequestAddImageLandmarkPoint(imagePoint);</DIV>
<DIV>> </DIV>
<DIV>> trackerPoint[0] = 304.046;</DIV>
<DIV>> trackerPoint[1] = -34.6625;</DIV>
<DIV>> trackerPoint[2] = -885.358;</DIV>
<DIV>> landmarkRegister-
>RequestAddTrackerLandmarkPoint(trackerPoint);</DIV>
<DIV>> </DIV>
<DIV>> landmarkRegister-
>RequestComputeTransform();</DIV>
<DIV>> </DIV>
<DIV>> landmarkRegister- >RequestGetTransform();</DIV>
<DIV>> </DIV>
<DIV>> transform = lrtcb-
>GetTransform();</DIV>
<DIV>> std::cout <
< "Transform " < < transform <
< std::cout;</DIV>
<DIV>> </DIV>
<DIV>> landmarkRegistrationError = landmarkRegister-
>ComputeRMSError();</DIV>
<DIV>> std::cout < <"RMS Error is "
< <landmarkRegistrationError < <std::endl;</DIV>
<DIV>> }</DIV>
<DIV>> </DIV>
<DIV>> </DIV>
<DIV>> // reuse landmark registration</DIV>
<DIV>> landmarkRegister- >RequestResetRegistration();</DIV>
<DIV>> </DIV>
<DIV>> imagePoint[0] = 77.2389;</DIV>
<DIV>> imagePoint[1] = 15.9716;</DIV>
<DIV>> imagePoint[2] = 16;</DIV>
<DIV>> landmarkRegister-
>RequestAddImageLandmarkPoint(imagePoint);</DIV>
<DIV>> trackerPoint[0] = 230.525;</DIV>
<DIV>> trackerPoint[1] = -44.7263;</DIV>
<DIV>> trackerPoint[2] = -894.183;</DIV>
<DIV>> landmarkRegister-
>RequestAddTrackerLandmarkPoint(trackerPoint);</DIV>
<DIV>> </DIV>
<DIV>> // Add 2nd landmark</DIV>
<DIV>> imagePoint[0] = 14.1021;</DIV>
<DIV>> imagePoint[1] = 10.3691;</DIV>
<DIV>> imagePoint[2] = 16;</DIV>
<DIV>> landmarkRegister-
>RequestAddImageLandmarkPoint(imagePoint);</DIV>
<DIV>> trackerPoint[0] = 211.976;</DIV>
<DIV>> trackerPoint[1] = -41.8738;</DIV>
<DIV>> trackerPoint[2] = -875.216;</DIV>
<DIV>> landmarkRegister-
>RequestAddTrackerLandmarkPoint(trackerPoint);</DIV>
<DIV>> </DIV>
<DIV>> // Add 3d landmark</DIV>
<DIV>> imagePoint[0] = 45.9937;</DIV>
<DIV>> imagePoint[1] = 6.27483;</DIV>
<DIV>> imagePoint[2] = 68;</DIV>
<DIV>> landmarkRegister-
>RequestAddImageLandmarkPoint(imagePoint);</DIV>
<DIV>> trackerPoint[0] = 303.781;</DIV>
<DIV>> trackerPoint[1] = -35.4769;</DIV>
<DIV>> trackerPoint[2] = -887.587;</DIV>
<DIV>> landmarkRegister-
>RequestAddTrackerLandmarkPoint(trackerPoint);</DIV>
<DIV>> </DIV>
<DIV>> landmarkRegister- >RequestComputeTransform();</DIV>
<DIV>> landmarkRegister- >RequestGetTransform();</DIV>
<DIV>> </DIV>
<DIV>> transform = lrtcb- >GetTransform();</DIV>
<DIV>> std::cout < < "Transform " <
< transform < < std::cout;</DIV>
<DIV>> </DIV>
<DIV>> landmarkRegistrationError = landmarkRegister-
>ComputeRMSError();</DIV>
<DIV>> std::cout < <"RMS Error is " <
<landmarkRegistrationError < <std::endl;</DIV>
<DIV>> </DIV>
<DIV>> return 0;</DIV>
<DIV>> }</DIV>
<DIV>> </DIV>
<DIV>> </DIV>
<DIV>> Thank you very much!</DIV>
<DIV>> </DIV>
<DIV>> Best,</DIV>
<DIV>> Fucang</DIV>
<DIV>> </DIV>
<DIV>> </DIV>
<DIV>> </DIV>
<DIV>> </DIV>
<DIV>> ------------------------------------------------------------------------</DIV>
<DIV>> 独家!网易3G免费邮,还赠送280兆网盘 www.126.com <<A
href="http://www.126.com/">http://www.126.com/</A> ></DIV>
<DIV>> </DIV>
<DIV>> </DIV>
<DIV>> ------------------------------------------------------------------------</DIV>
<DIV>> </DIV>
<DIV>> _______________________________________________</DIV>
<DIV>> IGSTK-Users mailing list</DIV>
<DIV>> IGSTK-Users@public.kitware.com</DIV>
<DIV>> <A
href="http://public.kitware.com/cgi-bin/mailman/listinfo/igstk-users">http://public.kitware.com/cgi-bin/mailman/listinfo/igstk-users</A></DIV>
<DIV> </DIV></FONT></DIV></BODY></HTML>