[Insight-users] co-occurrence matrix

Glenn Pierce glennpierce@connectfree.co.uk
Sun May 16 09:42:25 EDT 2004


--=-y5KyOvD2dlTzj5owqB0i
Content-Type: text/plain
Content-Transfer-Encoding: 7bit

Ok

I have a first version of a co occurrence filter.
I sure there are many things I can improve.

The main problem is I have stored each pair in a ListSample (each pair
as a new MeasurementVector).
However, I need to increase the frequency of duplicate pairs. I wasn't
sure how to efficiently find if a pair have already been stored and then
increment the frequency of that pair.
see line 76 of itkImageToCooccurenceList.txx


I had to use quite a few typename constructs to remove compiler warnings
of 'implicit typename' if anyone wonders about them.


Also I inherited from ImageToListAdaptor
but I am storing values in a ListSample that is a member of this
class. This is different from the other adaptors as it is storing
values. I don't know whether this is suitable for you?

Any suggestions of improving this filter. Even better itk method names
etc would be great.

I eventually am going to use this to produced an co-occurrence image in
vtk. Does anyone know how you can produce a grey level image with
different intensity values for the pixels in vtk? I probably should ask
on the vtk list -sorry.


I have attached the filter and a small driver program.

Thanks for the help.


Glenn


On Fri, 2004-05-14 at 11:12 -0400, Luis Ibanez wrote:
> Hi Glenn,
> 
> Thanks for the clarification.
> 
> Well...
> 
>      You probably will have to write that
>      ImageToListAdaptor class after alll    :-)
> 
> 
> I would suggest you to write it as a
> 
>          ImageToListFilter
> 
> 
> and take advantage of the Neighborhood
> Iterators.  You probably can get very
> close by looking at the code used for
> the Morphological filters.
> 
> Please read the Iterators chapter on
> the SoftwareGuide. That will help you
> find your way.
> 
> It will be nice let the option to the
> user for defining what neighbors to
> use as cliques for the coorcurrence
> matrix.
> 
> Your filter will populate a List of
> 2D vector values having all the pairs
> of cliques from your images.
> 
> 
> Please let us know if you need any
> help implementing this filter.
> 
> and... of course, we will be happy
> to get it back into the toolkit
> once you are done   :-)
> 



--=-y5KyOvD2dlTzj5owqB0i
Content-Disposition: attachment; filename=itkImageToCooccurenceList.h
Content-Type: text/x-chdr; name=itkImageToCooccurenceList.h; charset=iso-8859-1
Content-Transfer-Encoding: 7bit

#ifndef __itkImageToCooccurenceList_h
#define __itkImageToCooccurenceList_h

#include <typeinfo>

#include "itkImage.h"
#include "itkPixelTraits.h"
#include "itkImageToListAdaptor.h"
#include "itkSmartPointer.h"
#include "itkImageRegionIterator.h"
#include "itkShapedNeighborhoodIterator.h"
#include "itkNeighborhoodIterator.h"
#include "itkNeighborhoodAlgorithm.h"
#include "itkConstantBoundaryCondition.h"
#include "itkListSample.h"
#include "itkFixedArray.h"
#include "itkMacro.h"

#include <vector>
#include <algorithm>
#include <iostream>

namespace itk{ 
namespace Statistics{

template < class TImage >
class ITK_EXPORT ImageToCooccurenceList
  : public ImageToListAdaptor< 
  TImage, 
  FixedArray< typename TImage::PixelType, 2 > >
{
public:
  typedef TImage ImageType;

  typedef FixedArray< typename TImage::PixelType, 2 > MeasurementVectorType ;

  typedef typename itk::Statistics::ListSample< MeasurementVectorType > SampleType ;

  /** Standard class typedefs */
  typedef ImageToCooccurenceList Self;
  typedef ImageToListAdaptor< TImage, MeasurementVectorType > Superclass;
  typedef SmartPointer< Self > Pointer;
  typedef SmartPointer<const Self> ConstPointer;

  /** Neighborhood iterator type. */
  typedef itk::ShapedNeighborhoodIterator< TImage , ConstantBoundaryCondition<TImage> > ShapedNeighborhoodIteratorType;

  /** Offset type used for Neighborhoods **/
  typedef typename ShapedNeighborhoodIteratorType::OffsetType OffsetType;
  typedef typename std::vector<OffsetType> OffsetTable;
  
  void UseNeighbor(OffsetType offset);

  /** Triggers the Computation of the co-occurence matrix */
  void Compute();
 
  /** Run-time type information (and related methods). */
  itkTypeMacro(ImageToCooccurenceList, ListSampleBase);
  
  /** Method for creation through the object factory. */
  itkNewMacro(Self);
  
  /** the number of components in a measurement vector */
  itkStaticConstMacro(MeasurementVectorSize, unsigned int, 2);

  /** Superclass typedefs for Measurement vector, measurement, 
   * Instance Identifier, frequency, size, size element value */
  typedef typename Superclass::FrequencyType FrequencyType ;
  typedef typename Superclass::MeasurementType MeasurementType ;
  typedef typename Superclass::InstanceIdentifier InstanceIdentifier ;
  typedef MeasurementVectorType ValueType ;

protected:
  ImageToCooccurenceList();
  virtual ~ImageToCooccurenceList() {}
  void PrintSelf(std::ostream& os, Indent indent) const;  

private:
  ImageToCooccurenceList(const Self&) ; //purposely not implemented
  void operator=(const Self&) ; //purposely not implemented
  OffsetTable m_OffsetTable;
  typename SampleType::Pointer sample;
} ; // end of class ScalarImageToListAdaptor

} // end of namespace Statistics
} // end of namespace itk

#ifndef ITK_MANUAL_INSTANTIATION
#include "itkImageToCooccurenceList.txx"
#endif

#endif

--=-y5KyOvD2dlTzj5owqB0i
Content-Disposition: attachment; filename=itkImageToCooccurenceList.txx
Content-Type: text/plain; name=itkImageToCooccurenceList.txx; charset=iso-8859-1
Content-Transfer-Encoding: 7bit

#ifndef _itkImageToCooccurenceList_txx
#define _itkImageToCooccurenceList_txx

namespace itk{ 
namespace Statistics{

template < class TImage >
ImageToCooccurenceList< TImage >
::ImageToCooccurenceList()
{
  sample = SampleType::New();
}

template < class TImage >
void
ImageToCooccurenceList< TImage >
::PrintSelf(std::ostream& os, Indent indent) const
{
  Superclass::PrintSelf(os,indent);
}

template < class TImage >
void
ImageToCooccurenceList< TImage >
::Compute()
{
  typename ShapedNeighborhoodIteratorType::RadiusType radius;
  radius.Fill(1);

  itk::ConstantBoundaryCondition<TImage> boundaryCondition;
  // 0 is valid so I chose -1. Is this valid for all images ?
  boundaryCondition.SetConstant( -1 );

  typedef itk::NeighborhoodAlgorithm::ImageBoundaryFacesCalculator<
                                                ImageType > FaceCalculatorType;
                                                                                                                            
  FaceCalculatorType faceCalculator;
  typename FaceCalculatorType::FaceListType faceList;
  typename FaceCalculatorType::FaceListType::iterator fit;
  typename ShapedNeighborhoodIteratorType::ConstIterator ci;    
  ShapedNeighborhoodIteratorType it;
  typename ImageType::IndexType index;
  typename ImageType::PixelType pixel_intensity, center_pixel_intensity;
  typename OffsetTable::iterator iter;
  typename SampleType::MeasurementVectorType coords;  
                                                                                                                      
  faceList = faceCalculator( GetImage(),
                             GetImage()->GetRequestedRegion(),
                             radius );

  OffsetType center_offset = {{0,0}};

  for ( fit=faceList.begin(); fit != faceList.end(); ++fit) {

    it = ShapedNeighborhoodIteratorType( radius, GetImage(), *fit );
    it.OverrideBoundaryCondition(&boundaryCondition);

    for (iter = m_OffsetTable.begin(); iter != m_OffsetTable.end(); iter++) {
      it.ActivateOffset(*iter);
    }
                                                                                                                            
    for (it.GoToBegin(); !it.IsAtEnd(); ++it) {

        center_pixel_intensity = it.GetPixel(center_offset);

        for (ci = it.Begin(); ci != it.End(); ci++) {

            pixel_intensity = ci.Get();
            std::cout << "pixel value: " << pixel_intensity << "  " << std::endl;

            // We have the intensity values for the center pixel and one of it's neighbours.
            // We can now place these in the SampleList
            coords[0] = center_pixel_intensity;
            coords[1] = pixel_intensity;

            sample->PushBack(coords) ;

        }
    }
   }

}


template < class TImage >
void
ImageToCooccurenceList< TImage >
::UseNeighbor(OffsetType offset)
{
  // Don't add the center pixel
  if(offset[0] == 0 && offset[1] == 0) {
      //std::cout << "HERE " << std::endl;
      return;
  }

  m_OffsetTable.push_back(offset);
}


} // end of namespace Statistics 
} // end of namespace itk

#endif

--=-y5KyOvD2dlTzj5owqB0i
Content-Disposition: attachment; filename=Test.cxx
Content-Type: text/x-c++src; name=Test.cxx; charset=iso-8859-1
Content-Transfer-Encoding: 7bit

#include "itkImage.h"

#include "itkImageFileReader.h"
#include "itkImageToCooccurenceList.h"

int main( int argc, char * argv [] )
{
  typedef float      PixelType;
  const   unsigned int        Dimension = 2;
  typedef itk::Image< PixelType, Dimension >    ImageType;
  typedef itk::ImageFileReader< ImageType >  ReaderType;
  typedef itk::Statistics::ImageToCooccurenceList < ImageType > CooccurenceListType;

  ReaderType::Pointer reader = ReaderType::New();
                                                                                                                            
  reader->SetFileName( "/home/glenn/development/histogram/test.png" );
                                                                                                                            
  try {
      reader->Update();
  }
  catch( itk::ExceptionObject & exp )
  {
      std::cerr << "Exception caught" << std::endl;
      std::cerr << exp << std::endl;
  }

  CooccurenceListType::Pointer list = CooccurenceListType::New();
  list->SetImage(reader->GetOutput());

  CooccurenceListType::OffsetType offset0 = {{-1,0}};
  CooccurenceListType::OffsetType offset1 = {{1,0}};
  CooccurenceListType::OffsetType offset2 = {{0,-1}};
  CooccurenceListType::OffsetType offset3 = {{0,1}};

  list->UseNeighbor(offset0);
  list->UseNeighbor(offset1);
  list->UseNeighbor(offset2);
  list->UseNeighbor(offset3);

  list->Compute();

  return 0;
  
}



--=-y5KyOvD2dlTzj5owqB0i--




More information about the Insight-users mailing list