Dear Itk-users,<br><br>I am working on the following template function used to estimate initial parameters for a Gaussian Mixture Model.  I can compile and link the code without any errors. However, the results I am getting from the filter itk::Statistics::CovarianceSampleFilter are wrong.<br>
<br>Could anybody please check the code to see if I am using this filter properly? <br><br>Thank you,<br>Ricardo<br><br><br><br>/// *****************************************************************************************************<br>
/// <br>/// *****************************************************************************************************<br>template&lt; class TArrayImageType &gt;<br>void TKMeansEstimator&lt; TArrayImageType &gt;<br>::Run()<br>
{<br>    ///<br>    /// Gather info from the base class<br>    ///<br>    unsigned int NumberOfClasses = TGMM_InitStrategy&lt; TArrayImageType &gt;::m_NumberOfClasses;<br>    unsigned int NumberOfContrasts = TGMM_InitStrategy&lt; TArrayImageType &gt;::m_NumberOfContrasts; <br>
    const TArrayImageType *InputImage = TGMM_InitStrategy&lt; TArrayImageType &gt;::m_InputImage;<br><br>    ///<br>    /// Generate sample data<br>    ///<br>    typedef itk::Statistics::ImageToListSampleAdaptor&lt; TArrayImageType &gt; ImageToListSampleAdaptorType;<br>
    typename ImageToListSampleAdaptorType::Pointer adaptor = ImageToListSampleAdaptorType::New();<br>    adaptor-&gt;SetImage( InputImage );<br><br>    ///<br>    /// Create KdTree<br>    /// <br>    typedef itk::Statistics::WeightedCentroidKdTreeGenerator &lt; ImageToListSampleAdaptorType &gt; TreeGeneratorType;<br>
    typename TreeGeneratorType::Pointer treeGenerator = TreeGeneratorType::New();<br>    treeGenerator-&gt;SetSample( adaptor );<br>    treeGenerator-&gt;SetBucketSize( m_BuckedSize );<br>    treeGenerator-&gt;Update();<br>
<br>    typedef itk::Statistics::KdTreeBasedKmeansEstimator &lt; typename TreeGeneratorType::KdTreeType &gt; EstimatorType;<br>    typename EstimatorType::Pointer estimator = EstimatorType::New();<br><br>    ///<br>    /// Estimate classes mean vector<br>
    ///<br>    typename EstimatorType::ParametersType initialMeans( NumberOfContrasts * NumberOfClasses );<br>    estimator-&gt;SetParameters( initialMeans );<br>    estimator-&gt;SetKdTree( treeGenerator-&gt;GetOutput() );<br>
    estimator-&gt;SetMaximumIteration( m_MaxNumberOfIterations );<br>    estimator-&gt;SetCentroidPositionChangesThreshold( m_CentroidChangePosThresh );<br>    estimator-&gt;StartOptimization();<br><br>      typename EstimatorType::ParametersType estimatedMeans = estimator-&gt;GetParameters();<br>
    <br>    ///<br>    /// Compute classes labels <br>    ///    <br>    typedef itk::Statistics::SampleClassifierFilter&lt; ImageToListSampleAdaptorType &gt;  SampleClassifierFilterType;<br>    typedef typename SampleClassifierFilterType::MembershipSampleType::ClassLabelType    ClassLabelType;<br>
<br>    typedef typename SampleClassifierFilterType::ClassLabelVectorObjectType  ClassLabelVectorObjectType;<br>    typename ClassLabelVectorObjectType::Pointer classLabelsObject = ClassLabelVectorObjectType::New();<br>    <br>
    typedef typename SampleClassifierFilterType::ClassLabelVectorType  ClassLabelVectorType;<br>      ClassLabelVectorType&amp; classLabelVector = classLabelsObject-&gt;Get();<br>    for( unsigned int i=0; i &lt; NumberOfClasses; i++ )<br>
    {<br>        ClassLabelType classLabel = (i + 1) * 100;<br>        classLabelVector.push_back( classLabel );<br>    }<br>    <br>      /// Set a decision rule type<br>      typedef itk::Statistics::MinimumDecisionRule2  DecisionRuleType;<br>
      typename DecisionRuleType::Pointer decisionRule = DecisionRuleType::New();<br><br>      const typename SampleClassifierFilterType::MembershipFunctionVectorObjectType *membershipFunctionsObject = estimator-&gt;GetOutput();<br>
<br>      /// Instantiate and pass all the required inputs to the filter<br>    typename SampleClassifierFilterType::Pointer classifier = SampleClassifierFilterType::New();<br>      classifier-&gt;SetInput( adaptor );<br>
      classifier-&gt;SetNumberOfClasses( NumberOfClasses );<br>      classifier-&gt;SetClassLabels( classLabelsObject );<br>      classifier-&gt;SetDecisionRule( decisionRule );<br>      classifier-&gt;SetMembershipFunctions( membershipFunctionsObject );<br>
     classifier-&gt;Update();<br>    const typename SampleClassifierFilterType::MembershipSampleType* membershipSample = classifier-&gt;GetOutput();<br><br>    ///<br>    /// Compute the covariance matrices and the weight vectors<br>
    ///<br>    typedef typename SampleClassifierFilterType::MembershipSampleType::ClassSampleType    ClassSampleType;    <br>    typedef itk::Statistics::CovarianceSampleFilter&lt; ClassSampleType &gt;                     CovarianceSampleFilterType;<br>
    <br>    /// Resize weight class vector<br>    TGMM_InitStrategy&lt; TArrayImageType &gt;::m_WeightClassesVector.SetSize( NumberOfClasses );<br>        <br>    /// Now, get the mean &amp; covariance into the parameters vector<br>
    for( unsigned int i=0; i &lt; NumberOfClasses; ++i )<br>    {<br>        /// Get a pointer only to the samples of classLabel        <br>        ClassLabelType classLabel = (i + 1) * 100;<br>        const ClassSampleType* classSample = membershipSample-&gt;GetClassSample( classLabel );<br>
<br>          ///<br> <b>       /// Compute covariance matrix        <br>        /// The problem seems to be here<br>        /// <br>        typename CovarianceSampleFilterType::Pointer covarianceFilter = CovarianceSampleFilterType::New(); <br>
        covarianceFilter-&gt;SetInput( classSample );<br>        covarianceFilter-&gt;Update();<br></b>        <br>          const typename CovarianceSampleFilterType::MeasurementVectorDecoratedType *MeanDecorator = covarianceFilter-&gt;GetMeanOutput();<br>
          typename CovarianceSampleFilterType::MeasurementVectorType mean = MeanDecorator-&gt;Get();<br>          <br>          const typename CovarianceSampleFilterType::MatrixDecoratedType *CovDecorator = covarianceFilter-&gt;GetCovarianceMatrixOutput();<br>
          typename CovarianceSampleFilterType::MatrixType cov = CovDecorator-&gt;Get();<br>          <br>        /// Create a parameter array for the current class <br>        ParametersType *params = new ParametersType( NumberOfContrasts * NumberOfContrasts + NumberOfContrasts );<br>
<br>        unsigned int index = 0;<br>        for( unsigned j=0; j &lt; NumberOfContrasts; j++ )<br>        {<br>            /// Copy mean vector<br>            params-&gt;SetElement( index++, static_cast&lt; double &gt;( mean[j] ) );<br>
            <br>            /// Copy covariance matrix<br>            for( unsigned k=0; k &lt; NumberOfContrasts; k++ )<br>                params-&gt;SetElement( index++, static_cast&lt; double &gt;( cov[j][k] ) );<br>        }        <br>
<br>        TGMM_InitStrategy&lt; TArrayImageType &gt;::m_Parameters.push_back( params );         <br>        TGMM_InitStrategy&lt; TArrayImageType &gt;::m_WeightClassesVector.SetElement( i, (double)classSample-&gt;GetTotalFrequency() / adaptor-&gt;GetTotalFrequency() );<br>
    <br>    }<br>}<br><br>  <br>The input image is created as <br><br><br>///<br>const int NumberOfContrasts = 1; //3;<br>const int Dimension = 3;<br><br>/// Image definition<br>typedef signed short                                            InputPixelType;<br>
typedef itk::Image&lt; InputPixelType, Dimension &gt;                 InputImageType;<br><br>typedef itk::FixedArray&lt; InputPixelType, NumberOfContrasts &gt;    ArrayPixelType;<br>typedef itk::Image&lt; ArrayPixelType, Dimension &gt;                    ArrayImageType;<br>
<br><br>///<br>/// Create a image of array from different image contrasts<br>///<br>
    typedef itk::ScalarToArrayCastImageFilter&lt; InputImageType, ArrayImageType &gt; CasterType;<br>
    CasterType::Pointer caster = CasterType::New();<br>
    for( int i=0; i &lt; NumberOfContrasts; ++i )<br>
        caster-&gt;SetInput( i, ReadMincImage&lt; InputImageType &gt;( inputFileName[i] ) );<br>
    caster-&gt;Update();<br>
<br>const TArrayImageType *InputImage = caster-&gt;GetOutput();<br>
<br><br><br>  <br>