<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<TITLE></TITLE>

<META content="MSHTML 6.00.2900.3059" name=GENERATOR></HEAD>
<BODY text=#000000 bgColor=#ffffff>
<DIV dir=ltr align=left><SPAN class=281511214-10052007><FONT face=Arial 
color=#0000ff size=2>Hi Dan,</FONT></SPAN></DIV>
<DIV dir=ltr align=left><SPAN class=281511214-10052007><FONT face=Arial 
color=#0000ff size=2></FONT></SPAN>&nbsp;</DIV>
<DIV dir=ltr align=left><SPAN class=281511214-10052007><FONT face=Arial 
color=#0000ff size=2>I think the problem could be the amount of memory the 
filter is consuming in the process.&nbsp;For&nbsp;an 
output&nbsp;with&nbsp;PixelType float the output data in the first case is 
consuming :</FONT></SPAN></DIV>
<DIV dir=ltr align=left><SPAN class=281511214-10052007><FONT face=Arial 
color=#0000ff size=2></FONT></SPAN>&nbsp;</DIV>
<DIV dir=ltr align=left><SPAN class=281511214-10052007></SPAN><SPAN 
class=281511214-10052007></SPAN><SPAN class=281511214-10052007><FONT face=Arial 
color=#0000ff size=2>128x128x128 tensors&nbsp;x 6 pixels/tensor x 2 bytes / 
pixel = 25.165.824 bytes</FONT></SPAN></DIV>
<DIV dir=ltr align=left><SPAN class=281511214-10052007><FONT face=Arial 
color=#0000ff size=2></FONT></SPAN>&nbsp;</DIV>
<DIV dir=ltr align=left><SPAN class=281511214-10052007><FONT face=Arial 
color=#0000ff size=2>next case is 8 times the number of pixels so you 
have</FONT></SPAN></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT face=Arial color=#0000ff size=2></FONT>
<DIV dir=ltr align=left><SPAN class=281511214-10052007><FONT face=Arial 
color=#0000ff size=2>256x256x256 tensors&nbsp;x 6 pixels/tensor x 2 bytes / 
pixel = 201.326.592 bytes</FONT></SPAN></DIV>
<DIV dir=ltr align=left><SPAN class=281511214-10052007><FONT face=Arial 
color=#0000ff size=2>512x512x512 tensors&nbsp;x 6 pixels/tensor x 2 bytes / 
pixel = 1.610.612.736 bytes</FONT></SPAN></DIV>
<DIV dir=ltr align=left><SPAN class=281511214-10052007><FONT face=Arial 
color=#0000ff size=2></FONT></SPAN>&nbsp;</DIV>
<DIV dir=ltr align=left><SPAN class=281511214-10052007><FONT face=Arial 
color=#0000ff size=2>but probably the filter is consuming more memory in the 
process itself. So maybe in the second case you have already run out of physical 
memory. If you are using double precision then multiply these numbers by 2 so in 
the second case only with the output you are consuming 400 Mb. I would check out 
this first&nbsp;before considering a problem in the filter 
itself.</FONT></SPAN></DIV>
<DIV dir=ltr align=left><SPAN class=281511214-10052007><FONT face=Arial 
color=#0000ff size=2></FONT></SPAN>&nbsp;</DIV>
<DIV dir=ltr align=left><SPAN class=281511214-10052007><FONT face=Arial 
color=#0000ff size=2>Answering your second questions, for computing gaussian 
derivatives probably recursive filters are among&nbsp;the fastest. 
Implementation in ITK follows Deriche's work :</FONT></SPAN></DIV>
<DIV dir=ltr align=left><SPAN class=281511214-10052007><FONT face=Arial 
color=#0000ff size=2><A 
href="http://citeseer.ist.psu.edu/deriche93recursively.html">http://citeseer.ist.psu.edu/deriche93recursively.html</A></FONT></SPAN></DIV>
<DIV dir=ltr align=left><SPAN class=281511214-10052007><FONT face=Arial 
color=#0000ff size=2></FONT></SPAN>&nbsp;</DIV>
<DIV dir=ltr align=left><SPAN class=281511214-10052007><FONT face=Arial 
color=#0000ff size=2>You may find useful information and references 
here</FONT></SPAN></DIV>
<DIV dir=ltr align=left><SPAN class=281511214-10052007><FONT face=Arial 
color=#0000ff size=2><A 
href="http://en.wikipedia.org/wiki/Scale_space_implementation">http://en.wikipedia.org/wiki/Scale_space_implementation</A></FONT></SPAN></DIV>
<DIV dir=ltr align=left><SPAN class=281511214-10052007><FONT face=Arial 
color=#0000ff size=2></FONT></SPAN>&nbsp;</DIV>
<DIV dir=ltr align=left><SPAN class=281511214-10052007><FONT face=Arial 
color=#0000ff size=2>Regards</FONT></SPAN></DIV>
<DIV dir=ltr align=left><SPAN class=281511214-10052007><FONT face=Arial 
color=#0000ff size=2></FONT></SPAN>&nbsp;</DIV>
<DIV dir=ltr align=left><SPAN class=281511214-10052007><FONT face=Arial 
color=#0000ff size=2>Ivan Macía</FONT></SPAN></DIV>
<DIV dir=ltr align=left><SPAN class=281511214-10052007><FONT face=Arial 
color=#0000ff size=2></FONT></SPAN>&nbsp;</DIV>
<DIV dir=ltr align=left>
<HR tabIndex=-1>
<FONT face=Tahoma size=2><B>De:</B> 
insight-users-bounces+imacia=vicomtech.es@itk.org 
[mailto:insight-users-bounces+imacia=vicomtech.es@itk.org] <B>En nombre de 
</B>Dan Mueller<BR><B>Enviado el:</B> jueves, 10 de mayo de 2007 
3:53<BR><B>Para:</B> insight-users<BR><B>Asunto:</B> [Insight-users] 
HessianRecursiveGaussian execution speed<BR></FONT><BR></DIV></DIV>
<DIV></DIV><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 
&gt;&gt; Time = 4.28sec<BR></SMALL></FONT><FONT 
face="Helvetica, Arial, sans-serif"><SMALL>itkTestHessian 
TestHessian_256x256x256.mhd 1 1.0 &gt;&gt; Time = 6.2e+003sec = 1hr 
43min<BR></SMALL></FONT><FONT 
face="Helvetica, Arial, sans-serif"><SMALL>itkTestHessian 
TestHessian_512x512x512.mhd 1 1.0 &gt;&gt; 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>&nbsp; 
itkTestHessian.cxx<BR>=========================================================================*/<BR><BR>#include 
&lt;iomanip&gt;<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&lt; PixelType, Dimension 
&gt; ImageType;<BR>typedef itk::ImageFileReader&lt; ImageType &gt; 
ReaderType;<BR>typedef itk::ImageFileWriter&lt; ImageType &gt; 
WriterType;<BR>typedef itk::HessianRecursiveGaussianImageFilter&lt; ImageType 
&gt; 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>&nbsp; typedef&nbsp; ProgressCommand&nbsp;&nbsp; 
Self;<BR>&nbsp; typedef&nbsp; 
itk::Command&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
Superclass;<BR>&nbsp; typedef&nbsp; itk::SmartPointer&lt;Self&gt;&nbsp; 
Pointer;<BR>&nbsp; itkNewMacro( Self );<BR><BR>protected:<BR>&nbsp; 
ProgressCommand() { m_LastProgress = -1; };<BR>&nbsp; float 
m_LastProgress;<BR><BR>public:<BR><BR>&nbsp; void Execute(itk::Object *caller, 
const itk::EventObject &amp; event)<BR>&nbsp; {<BR>&nbsp;&nbsp;&nbsp; Execute( 
(const itk::Object *)caller, event);<BR>&nbsp; }<BR><BR>&nbsp; void 
Execute(const itk::Object * object, const itk::EventObject &amp; 
event)<BR>&nbsp; {<BR>&nbsp;&nbsp;&nbsp; &nbsp; const itk::ProcessObject* 
process = dynamic_cast&lt; const itk::ProcessObject* &gt;( object 
);<BR><BR>&nbsp;&nbsp;&nbsp; &nbsp; if( ! itk::ProgressEvent().CheckEvent( 
&amp;event ) )<BR>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 
return;<BR><BR>&nbsp;&nbsp;&nbsp; &nbsp; int fprogress = 
(process-&gt;GetProgress() * 100.0);<BR>&nbsp;&nbsp;&nbsp; &nbsp; int progress = 
(int)(process-&gt;GetProgress() * 100.0);<BR>&nbsp;&nbsp;&nbsp; &nbsp; if 
((int)m_LastProgress == progress)<BR>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 
&nbsp; return;<BR>&nbsp;&nbsp;&nbsp; &nbsp; if ((int)m_LastProgress != (progress 
- 1))<BR>&nbsp;&nbsp;&nbsp; &nbsp; {<BR>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 
&nbsp; std::cout &lt;&lt; std::setfill('0') &lt;&lt; std::setw(3) &lt;&lt; 
(progress - 1) &lt;&lt; " ";<BR>&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (fprogress &gt; 0.0 &amp;&amp; (progress - 1) 
% 10 == 0)<BR>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; std::cout 
&lt;&lt; std::endl;<BR>&nbsp;&nbsp;&nbsp; &nbsp; }<BR>&nbsp;&nbsp;&nbsp; &nbsp; 
if (fprogress &gt; 0.0 &amp;&amp; fprogress &lt;= 100.0)<BR>&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp; &nbsp; std::cout &lt;&lt; std::setfill('0') &lt;&lt; 
std::setw(3) &lt;&lt; progress &lt;&lt; " ";<BR>&nbsp;&nbsp;&nbsp; &nbsp; if 
(fprogress &gt; 0.0 &amp;&amp; progress % 10 == 0)<BR>&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp; &nbsp; std::cout &lt;&lt; std::endl;<BR>&nbsp;&nbsp;&nbsp; 
&nbsp; m_LastProgress = fprogress;<BR>&nbsp; }&nbsp;&nbsp; <BR>};<BR><BR>int 
main(int argc, char* argv[])<BR>{<BR>&nbsp;&nbsp;&nbsp; // Display 
header<BR>&nbsp;&nbsp;&nbsp; std::cout &lt;&lt; "Hessian Test 
-------------------------" &lt;&lt; std::endl;<BR>&nbsp;&nbsp;&nbsp; 
<BR>&nbsp;&nbsp;&nbsp; // Check arguments<BR>&nbsp;&nbsp;&nbsp; if (argc &lt; 
4)<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; std::cerr 
&lt;&lt; "Usage: " &lt;&lt; argv[0] &lt;&lt;<BR>&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; " InputFilename" 
&lt;&lt;<BR>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp; " NormalizeAcrossScale" &lt;&lt;<BR>&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; " Sigma" 
&lt;&lt;<BR>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp; " \n";<BR>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 
EXIT_FAILURE;<BR>&nbsp;&nbsp;&nbsp; }<BR><BR>&nbsp;&nbsp;&nbsp; // Setup the 
algorithm parameters<BR>&nbsp;&nbsp;&nbsp; unsigned int argn = 
1;<BR>&nbsp;&nbsp;&nbsp; char* 
InputFilename&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = 
argv[argn++];<BR>&nbsp;&nbsp;&nbsp; bool NormalizeAcrossScale&nbsp; = 
(bool)atoi( argv[argn++] );<BR>&nbsp;&nbsp;&nbsp; double 
Sigma&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
= atof( argv[argn++] );<BR><BR>&nbsp;&nbsp;&nbsp; // Display 
parameters<BR>&nbsp;&nbsp;&nbsp; std::cout &lt;&lt; "InputFilename:" &lt;&lt; 
InputFilename &lt;&lt; std::endl;<BR>&nbsp;&nbsp;&nbsp; std::cout &lt;&lt; 
"NormalizeAcrossScale:" &lt;&lt; NormalizeAcrossScale &lt;&lt; 
std::endl;<BR>&nbsp;&nbsp;&nbsp; std::cout &lt;&lt; "Sigma:" &lt;&lt; Sigma 
&lt;&lt; std::endl;<BR>&nbsp;&nbsp;&nbsp; std::cout &lt;&lt; 
"------------------------------------" &lt;&lt; std::endl;<BR>&nbsp;&nbsp;&nbsp; 
<BR>&nbsp;&nbsp;&nbsp; try<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp; // Read input image<BR>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 
std::cout &lt;&lt; "Reading input..." &lt;&lt; std::endl;<BR>&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp; ReaderType::Pointer reader = 
ReaderType::New();<BR>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 
reader-&gt;SetFileName( InputFilename );<BR>&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp; reader-&gt;Update();<BR><BR>&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp; // Setup Hessian<BR>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 
std::cout &lt;&lt; "Computing Hessian..." &lt;&lt; 
std::endl;<BR>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; HessianFilterType::Pointer 
filterHessian = HessianFilterType::New();<BR>&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp; filterHessian-&gt;SetInput( reader-&gt;GetOutput() 
);<BR>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; filterHessian-&gt;SetSigma( Sigma 
);<BR>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 
filterHessian-&gt;SetNormalizeAcrossScale( NormalizeAcrossScale 
);<BR>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ProgressCommand::Pointer 
observerHessian = ProgressCommand::New();<BR>&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp; filterHessian-&gt;AddObserver( itk::ProgressEvent(), 
observerHessian );<BR>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Compute and time 
hessian<BR>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; itk::TimeProbe 
time;<BR>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 
time.Start();<BR>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; filterHessian-&gt;Update( 
);<BR>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; time.Stop();<BR>&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp; std::cout &lt;&lt; std::setprecision(3) &lt;&lt; "Time: " 
&lt;&lt; time.GetMeanTime() &lt;&lt; std::endl;<BR>&nbsp;&nbsp;&nbsp; 
}<BR><BR>&nbsp;&nbsp;&nbsp; catch (itk::ExceptionObject &amp; 
err)<BR>&nbsp;&nbsp;&nbsp; { <BR>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; std::cout 
&lt;&lt; "ExceptionObject caught !" &lt;&lt; std::endl; <BR>&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp; std::cout &lt;&lt; err &lt;&lt; std::endl; 
<BR>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 
EXIT_FAILURE;<BR>&nbsp;&nbsp;&nbsp; }<BR><BR>&nbsp;&nbsp;&nbsp; 
//Return<BR>&nbsp;&nbsp;&nbsp; return 
EXIT_SUCCESS;<BR>}</FONT><BR></SMALL></FONT><BR>
<P><FONT size=2>No virus found in this incoming message.<BR>Checked by AVG Free 
Edition.<BR>Version: 7.5.467 / Virus Database: 269.6.6/794 - Release Date: 
08/05/2007 14:23<BR></FONT></P>
<P><FONT face=Arial size=2></FONT></P></BODY></HTML>
<BR>

<P><FONT SIZE=2>No virus found in this outgoing message.<BR>
Checked by AVG Free Edition.<BR>
Version: 7.5.467 / Virus Database: 269.6.6/795 - Release Date: 09/05/2007 15:07<BR>
</FONT> </P>