<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=ISO-8859-1" http-equiv="Content-Type">
<title></title>
</head>
<body bgcolor="#ffffff" text="#000000">
<font face="Helvetica, Arial, sans-serif"><small>Hi insight-users,<br>
<br>
I am using the <font face="Courier New, Courier, monospace">itk::HessianRecursiveGaussianImageFilter</font>
and have noticed it executes quite slow for 'large' 3-D datasets. Here
are some times I recorded:<br>
<br>
itkTestHessian TestHessian_128x128x128.mhd 1 1.0 >> Time = 4.28sec<br>
</small></font><font face="Helvetica, Arial, sans-serif"><small>itkTestHessian
TestHessian_256x256x256.mhd 1 1.0 >> Time = 6.2e+003sec = 1hr
43min<br>
</small></font><font face="Helvetica, Arial, sans-serif"><small>itkTestHessian
TestHessian_512x512x512.mhd 1 1.0 >> I gave up...</small></font><br>
<font face="Helvetica, Arial, sans-serif"><small><br>
<b>My questions:</b><br>
1. Have other people experienced similar execution times using this
filter, or am I doing something wrong? I understand the filter performs
separable convolution multiple times in multiple dimensions (ie. it's
not a simple computation), but these times seem impractical for
datasets 256x256x256 or bigger...<br>
2. Are there any techniques (besides relying on Moore's Law) to speed
up this filter? I am interested in the <i>whole</i> image, so using an
image function would not help. </small></font><font
face="Helvetica, Arial, sans-serif"><small>(NOTE: I compiled my test
in <font face="Courier New, Courier, monospace">Release</font> mode
with optimization for maximum speed ie. <font
face="Courier New, Courier, monospace">/O2</font>).</small></font><br>
<font face="Helvetica, Arial, sans-serif"><small><br>
Thanks for any help and/or ideas.<br>
<br>
Cheers, Dan<br>
<a class="moz-txt-link-abbreviated" href="mailto:d.mueller@qut.edu.au">d.mueller@qut.edu.au</a><br>
<b><br>
</b></small></font><small><font face="Helvetica, Arial, sans-serif"><b>My
system:</b><br>
</font></small><small><font face="Helvetica, Arial, sans-serif">Platform:
Windows XP SP2<br>
Computer: Intel Pentium 3.00 GHz, dual core, 1GB physical RAM<br>
Compiler: Microsoft Visual Studio 2005 (v8.0.50727.762 SP1)<br>
CMake: 2.4.2<br>
ITK: 3.2.0 CVS on Tues 27 Mar 2007</font></small><br>
<font face="Helvetica, Arial, sans-serif"><small><br>
<b>My test code:</b><br>
<font face="Courier New, Courier, monospace">/*=========================================================================<br>
itkTestHessian.cxx<br>
=========================================================================*/<br>
<br>
#include <iomanip><br>
#include "itkImage.h"<br>
#include "itkNumericTraits.h"<br>
#include "itkCommand.h"<br>
#include "itkImageFileReader.h"<br>
#include "itkImageFileWriter.h"<br>
#include "itkHessianRecursiveGaussianImageFilter.h"<br>
#include "itkTimeProbe.h"<br>
<br>
// Declare general types<br>
const unsigned int Dimension = 3;<br>
typedef float PixelType;<br>
typedef itk::Image< PixelType, Dimension > ImageType;<br>
typedef itk::ImageFileReader< ImageType > ReaderType;<br>
typedef itk::ImageFileWriter< ImageType > WriterType;<br>
typedef itk::HessianRecursiveGaussianImageFilter< ImageType >
HessianFilterType;<br>
<br>
// Declare a command to display the progress in a nice block format<br>
class ProgressCommand : public itk::Command <br>
{<br>
public:<br>
typedef ProgressCommand Self;<br>
typedef itk::Command Superclass;<br>
typedef itk::SmartPointer<Self> Pointer;<br>
itkNewMacro( Self );<br>
<br>
protected:<br>
ProgressCommand() { m_LastProgress = -1; };<br>
float m_LastProgress;<br>
<br>
public:<br>
<br>
void Execute(itk::Object *caller, const itk::EventObject & event)<br>
{<br>
Execute( (const itk::Object *)caller, event);<br>
}<br>
<br>
void Execute(const itk::Object * object, const itk::EventObject &
event)<br>
{<br>
const itk::ProcessObject* process = dynamic_cast< const
itk::ProcessObject* >( object );<br>
<br>
if( ! itk::ProgressEvent().CheckEvent( &event ) )<br>
return;<br>
<br>
int fprogress = (process->GetProgress() * 100.0);<br>
int progress = (int)(process->GetProgress() * 100.0);<br>
if ((int)m_LastProgress == progress)<br>
return;<br>
if ((int)m_LastProgress != (progress - 1))<br>
{<br>
std::cout << std::setfill('0') << std::setw(3)
<< (progress - 1) << " ";<br>
if (fprogress > 0.0 && (progress - 1) % 10 == 0)<br>
std::cout << std::endl;<br>
}<br>
if (fprogress > 0.0 && fprogress <= 100.0)<br>
std::cout << std::setfill('0') << std::setw(3)
<< progress << " ";<br>
if (fprogress > 0.0 && progress % 10 == 0)<br>
std::cout << std::endl;<br>
m_LastProgress = fprogress;<br>
} <br>
};<br>
<br>
int main(int argc, char* argv[])<br>
{<br>
// Display header<br>
std::cout << "Hessian Test -------------------------"
<< std::endl;<br>
<br>
// Check arguments<br>
if (argc < 4)<br>
{<br>
std::cerr << "Usage: " << argv[0] <<<br>
" InputFilename" <<<br>
" NormalizeAcrossScale" <<<br>
" Sigma" <<<br>
" \n";<br>
return EXIT_FAILURE;<br>
}<br>
<br>
// Setup the algorithm parameters<br>
unsigned int argn = 1;<br>
char* InputFilename = argv[argn++];<br>
bool NormalizeAcrossScale = (bool)atoi( argv[argn++] );<br>
double Sigma = atof( argv[argn++] );<br>
<br>
// Display parameters<br>
std::cout << "InputFilename:" << InputFilename <<
std::endl;<br>
std::cout << "NormalizeAcrossScale:" <<
NormalizeAcrossScale << std::endl;<br>
std::cout << "Sigma:" << Sigma << std::endl;<br>
std::cout << "------------------------------------" <<
std::endl;<br>
<br>
try<br>
{<br>
// Read input image<br>
std::cout << "Reading input..." << std::endl;<br>
ReaderType::Pointer reader = ReaderType::New();<br>
reader->SetFileName( InputFilename );<br>
reader->Update();<br>
<br>
// Setup Hessian<br>
std::cout << "Computing Hessian..." << std::endl;<br>
HessianFilterType::Pointer filterHessian =
HessianFilterType::New();<br>
filterHessian->SetInput( reader->GetOutput() );<br>
filterHessian->SetSigma( Sigma );<br>
filterHessian->SetNormalizeAcrossScale( NormalizeAcrossScale
);<br>
ProgressCommand::Pointer observerHessian =
ProgressCommand::New();<br>
filterHessian->AddObserver( itk::ProgressEvent(),
observerHessian );<br>
<br>
// Compute and time hessian<br>
itk::TimeProbe time;<br>
time.Start();<br>
filterHessian->Update( );<br>
time.Stop();<br>
std::cout << std::setprecision(3) << "Time: "
<< time.GetMeanTime() << std::endl;<br>
}<br>
<br>
catch (itk::ExceptionObject & err)<br>
{ <br>
std::cout << "ExceptionObject caught !" <<
std::endl; <br>
std::cout << err << std::endl; <br>
return EXIT_FAILURE;<br>
}<br>
<br>
//Return<br>
return EXIT_SUCCESS;<br>
}</font><br>
</small></font>
</body>
</html>