<!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>