[Insight-users] variogram / cancel update method
Glenn Pierce
glennpierce at connectfree.co.uk
Mon Aug 2 08:06:15 EDT 2004
Hi
I have developed a variogram filter that still needs a bit of tidying
work. I have attached it.
This variogram is very processor intensive.
In the worst case O(N^2), where N is the number of pixels of an image.
(In reality there are optimisations I have placed in means the
performance is quite a bit better than this). However for large images
it would still be slow.
For my main project I am calling the update method of the variogram
filter in a separate thread, and wanted to allow users to cancel the
execution.
For this reason I wondered if there is an accepted way in ITK or any
examples to cancel the update method or in my case tell the variogram
filter to stop the loop in the update method ?
Thanks for the help
Glenn
-------------- next part --------------
A non-text attachment was scrubbed...
Name: itkImageToVariogram.h
Type: text/x-chdr
Size: 5675 bytes
Desc: not available
Url : http://public.kitware.com/pipermail/insight-users/attachments/20040802/94016506/itkImageToVariogram-0001.h
-------------- next part --------------
/*=========================================================================
Program: Insight Segmentation & Registration Toolkit
Module: $RCSfile: itkImageToVariogram.txx,v $
Language: C++
Date: $Date: 2004/05/16 19:03:40 $
Version: $Revision: 1.1 $
Copyright (c) Insight Software Consortium. All rights reserved.
See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.
=========================================================================*/
#ifndef _itkImageToVariogram_txx
#define _itkImageToVariogram_txx
#include "itkProgressReporter.h"
#include "itkConstantBoundaryCondition.h"
namespace itk{
namespace Statistics{
template < class TImage >
ImageToVariogram< TImage >
::ImageToVariogram()
{
this->semi_variance_maximum = 0;
this->background_intensity = 0;
}
template < class TImage >
ImageToVariogram< TImage >
::~ImageToVariogram()
{
delete lagContainer;
}
template < class TImage >
void
ImageToVariogram< TImage >
::PrintSelf(std::ostream& os, Indent indent) const
{
Superclass::PrintSelf(os,indent);
}
template < class TImage >
void
ImageToVariogram< TImage >
::SetImage(const TImage* image)
{
m_Image = image ;
// get spacing between data points
spacing_x = m_Image->GetSpacing()[0];
spacing_y = m_Image->GetSpacing()[1];
// Set the max lag distance to use as one third to the image diagonal
this->max_lag = MaximumPossibleLag() / 4;
IndexType index = m_Image->ComputeIndex( this->Size() - 1 );
width = index[0];
height = index[1];
}
/** returns the number of pixels in this container */
template < class TImage >
inline unsigned int
ImageToVariogram< TImage >
::Size() const
{
return m_Image->GetPixelContainer()->Size() ;
}
/** returns the number of lags in this image */
template < class TImage >
unsigned int
ImageToVariogram< TImage >
::TotalLags()
{
long unsigned int size = this->Size();
// The sum of a arithmetrix series given by (number of terms) * (average of first and last terms)
return ((size * (size - 1)) / 2);
}
/** returns the maximum lag in this image */
template < class TImage >
inline int
ImageToVariogram< TImage >
::MinimumLag()
{
// Get the distance between the first and the next
return this->CalculateLag(m_Image->ComputeIndex( 0 ), m_Image->ComputeIndex( 1 ));
}
/** returns the maximum lag in this image */
template < class TImage >
inline int
ImageToVariogram< TImage >
::MaximumPossibleLag()
{
// Get the distance between the first and last pixel
return static_cast<int>(this->CalculateLag(m_Image->ComputeIndex( 0 ),
m_Image->ComputeIndex( this->Size() - 1 )));
}
/** Set the max lag that the variogram shall be calculated to
The default is 1/4 of the maximum lag of the image diagonal */
template < class TImage >
inline void
ImageToVariogram< TImage >
::SetMaxLag(int lag)
{
// Get the maximum lag distance to operate over
if(lag > 0 && lag <= this->MaximumPossibleLag())
{
this->max_lag = lag;
}
}
template < class TImage >
void
ImageToVariogram< TImage >
::GenerateData()
{
unsigned int size = this->Size();
int lag;
int maxi = 0;
lagContainer = new LagDetail[this->max_lag + 1];
// Create a progress reporter
ProgressReporter progress(this, 0, size);
ConstIteratorType mainPixelIter( m_Image, m_Image->GetRequestedRegion() );
ConstIteratorType nextPixelIter( m_Image, m_Image->GetRequestedRegion() );
IndexType nextPixelIndex;
IndexType index;
int max_x, min_x, max_y;
for ( mainPixelIter.GoToBegin(); !mainPixelIter.IsAtEnd(); ++mainPixelIter)
{
IndexType currentPixelIndex = mainPixelIter.GetIndex();
PixelType currentPixelValue = mainPixelIter.Get();
if(currentPixelValue == this->background_intensity)
{
progress.CompletedPixel();
continue;
}
// Calculate the maximum and minumum pixels within the max lag circle
// So we dont have to deal with all points
max_x = currentPixelIndex[0] + this->max_lag;
if(max_x > this->width)
{
max_x = this->width;
}
min_x = currentPixelIndex[0] - this->max_lag;
if(min_x < 0)
{
min_x = 0;
}
// If the next pixel is further right than the max lag chosen move on to the next line
max_y = currentPixelIndex[1] + this->max_lag;
if(max_y > this->height)
{
max_y = this->height;
}
nextPixelIter = mainPixelIter;
++nextPixelIter;
while (!nextPixelIter.IsAtEnd())
{
nextPixelIndex = nextPixelIter.GetIndex();
if(nextPixelIter.Get() == this->background_intensity)
{
++nextPixelIter;
continue;
}
// If the next pixel is lower than the max lag chosen move on the current pixel
if( nextPixelIndex[1] > max_y )
{
break;
}
// If the next pixel is further right than the max lag chosen move on to the next line
if( ( nextPixelIndex[0] > max_x ) )
{
// move to next line
index[0] = 0;
index[1] = nextPixelIndex[1] + 1;
nextPixelIter.SetIndex(index);
nextPixelIndex = nextPixelIter.GetIndex();
continue;
}
// If the next pixel is further left than the max lag chosen move on the
// first pixel within range.
if( nextPixelIndex[0] < min_x )
{
// move to first pixel within reach
index[0] = min_x;
index[1] = nextPixelIndex[1];
nextPixelIter.SetIndex(index);
nextPixelIndex = nextPixelIter.GetIndex();
continue;
}
lag = this->CalculateLag(currentPixelIndex, nextPixelIndex);
// Check the pixel is within the max lag
if (lag <= this->max_lag)
{
lagContainer[lag].count++;
lagContainer[lag].sum_squared_diff += pow((currentPixelValue - nextPixelIter.Get()), 2);
}
++nextPixelIter;
}
progress.CompletedPixel();
}
}
template < class TImage >
inline double
ImageToVariogram< TImage >
::GetSemiVariance(int lag)
{
if (lag > 0 && lag <= max_lag)
{
double tmp = lagContainer[lag].sum_squared_diff / (2.0 * lagContainer[lag].count);
if(tmp > this->semi_variance_maximum)
{
this->semi_variance_maximum = tmp;
}
return tmp;
}
else
{
return -1.0;
}
}
template < class TImage >
inline int
ImageToVariogram< TImage >
::CalculateLag(ImageToVariogram< TImage >::IndexType index1, ImageToVariogram< TImage >::IndexType index2)
{
// Difference between pixels
typename ImageToVariogram< TImage >::IndexType::IndexValueType x_pixel_difference = abs(index2[0] - index1[0]);
typename ImageToVariogram< TImage >::IndexType::IndexValueType y_pixel_difference = abs(index2[1] - index1[1]);
if(!y_pixel_difference)
return x_pixel_difference;
if(!x_pixel_difference)
return y_pixel_difference;
// Always round up
int tmp = static_cast<int>(ceil(sqrt(pow(x_pixel_difference,2) + pow(y_pixel_difference,2))));
return tmp;
}
} // end of namespace Statistics
} // end of namespace itk
#endif
More information about the Insight-users
mailing list