我有下面的代码,我想从ubuntu中的bash脚本中运行它。在我的bash脚本中,我写了下面的命令。
$DOANTS/SmoothImage $216*512*512 $RESULTS/Registration/NiftyReg/StructureGuided/Pat28_MLAF0113_pv_Aff_BSpline_Iso_ArgMax.nii.gz $1 $RESULTS/Registration/NiftyReg/StructureGuided/Pat28_${CASES[$i]}_Prostate_Aff_BSpline_Iso_ArgMax_smoothed.nii.gz
但我得到以下错误:
Unsupported dimension
我不知道为什么维度没有通过。如果你能告诉我原因,我将不胜感激。图像的真实大小为.216*512*512
代码如下:
#include "antsUtilities.h"
#include <algorithm>
#include "itkMedianImageFilter.h"
#include "itkDiscreteGaussianImageFilter.h"
#include "ReadWriteData.h"
namespace ants
{
template <unsigned int ImageDimension>
int SmoothImage(int argc, char *`1 [])
{
typedef float PixelType;
typedef itk::Image<PixelType, ImageDimension> ImageType;
std::vector<float> sigmaVector = ConvertVector<float>( argv[3] );
typename ImageType::Pointer image1 = ITK_NULLPTR;
typename ImageType::Pointer varimage = ITK_NULLPTR;
ReadImage<ImageType>(image1, argv[2]);
typedef itk::DiscreteGaussianImageFilter<ImageType, ImageType> dgf;
typedef itk::MedianImageFilter<ImageType, ImageType> medf;
typename dgf::Pointer filter = dgf::New();
typename medf::Pointer filter2 = medf::New();
bool usespacing = false;
if( argc > 5 )
{
usespacing = atoi(argv[5]);
}
bool usemedian = false;
if( argc > 6 )
{
usemedian = atoi(argv[6]);
}
if( !usespacing )
{
filter->SetUseImageSpacingOff();
}
else
{
filter->SetUseImageSpacingOn();
}
if( !usemedian )
{
if( sigmaVector.size() == 1 )
{
filter->SetVariance( vnl_math_sqr( sigmaVector[0] ) );
}
else if( sigmaVector.size() == ImageDimension )
{
typename dgf::ArrayType varianceArray;
for( unsigned int d = 0; d < ImageDimension; d++ )
{
varianceArray[d] = vnl_math_sqr( sigmaVector[d] );
}
filter->SetVariance( varianceArray );
}
else
{
std::cerr << "Incorrect sigma vector size. Must either be of size 1 or ImageDimension." << std::endl;
}
filter->SetMaximumError( 0.01f );
filter->SetInput( image1 );
filter->Update();
varimage = filter->GetOutput();
}
else
{
typename ImageType::SizeType rad;
if( sigmaVector.size() == 1 )
{
rad.Fill( static_cast<unsigned long>( sigmaVector[0] ) );
}
else if( sigmaVector.size() == ImageDimension )
{
for( unsigned int d = 0; d < ImageDimension; d++ )
{
rad[d] = sigmaVector[d];
}
}
else
{
std::cerr << "Incorrect sigma vector size. Must either be of size 1 or ImageDimension." << std::endl;
}
filter2->SetRadius(rad);
filter2->SetInput( image1 );
filter2->Update();
varimage = filter2->GetOutput();
}
WriteImage<ImageType>( varimage, argv[4] );
return EXIT_SUCCESS;
}
// entry point for the library; parameter 'args' is equivalent to 'argv' in (argc,argv) of commandline parameters to
// 'main()'
int SmoothImage( std::vector<std::string> args, std::ostream* /*out_stream = NULL */ )
{
// put the arguments coming in as 'args' into standard (argc,argv) format;
// 'args' doesn't have the command name as first, argument, so add it manually;
// 'args' may have adjacent arguments concatenated into one argument,
// which the parser should handle
args.insert( args.begin(), "SmoothImage" );
int argc = args.size();
char* * argv = new char *[args.size() + 1];
for( unsigned int i = 0; i < args.size(); ++i )
{
// allocate space for the string plus a null character
argv[i] = new char[args[i].length() + 1];
std::strncpy( argv[i], args[i].c_str(), args[i].length() );
// place the null character in the end
argv[i][args[i].length()] = ' ';
}
argv[argc] = ITK_NULLPTR;
// class to automatically cleanup argv upon destruction
class Cleanup_argv
{
public:
Cleanup_argv( char* * argv_, int argc_plus_one_ ) : argv( argv_ ), argc_plus_one( argc_plus_one_ )
{
}
~Cleanup_argv()
{
for( unsigned int i = 0; i < argc_plus_one; ++i )
{
delete[] argv[i];
}
delete[] argv;
}
private:
char* * argv;
unsigned int argc_plus_one;
};
Cleanup_argv cleanup_argv( argv, argc + 1 );
// antscout->set_stream( out_stream );
if( argc < 4 )
{
std::cout << "Usage: " << std::endl;
std::cout << argv[0]
<<
" ImageDimension image.ext smoothingsigma outimage.ext {sigma-is-in-spacing-coordinates-0/1} {medianfilter-0/1}"
<< std::endl;
std::cout << " if median, then sigma means radius of filtering " << std::endl;
std::cout << " A separate sigma can be specified for each dimension, e.g., 1.5x1x2 " << std::endl;
if( argc >= 2 &&
( std::string( argv[1] ) == std::string("--help") || std::string( argv[1] ) == std::string("-h") ) )
{
return EXIT_SUCCESS;
}
return EXIT_FAILURE;
}
switch( atoi(argv[1]) )
{
case 2:
{
return SmoothImage<2>(argc, argv);
}
break;
case 3:
{
return SmoothImage<3>(argc, argv);
}
break;
case 4:
{
return SmoothImage<4>(argc, argv);
}
break;
default:
std::cout << "Unsupported dimension" << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
} // namespace ants
enter code here
我认为您可能在假设bash在命令行上执行内联数学。事实并非如此。举个例子-
$ echo $216*512*512
$ 16*512*512
事实上,除非我遗漏了一些我不知道的语法魔术,否则$2只是被解释为父脚本的第二个参数,如-
$ function check() { echo $216*512*512; }
$ check fragile rock
$ rock16*512*512
看到了吗?然而,我认为你这里有一个拼写错误。$2可能是单独的,因为程序的第一个参数是一个选择器,您可以在接近尾声时使用它来实例化平滑函数的模板版本。因此,调用脚本的第二个参数成为SmoothImage
的第一个参数,如-中所示
$DOANTS/SmoothImage $2 16*512*512 $RESULTS/Registration/NiftyReg/StructureGuided/Pat28_MLAF0113_pv_Aff_BSpline_Iso_ArgMax.nii.gz $1 $RESULTS/Registration/NiftyReg/StructureGuided/Pat28_${CASES[$i]}_Prostate_Aff_BSpline_Iso_ArgMax_smoothed.nii.gz
然而,如果如您所说,size参数是16*512*512或216*512*5512(视情况而定(,那么您仍然会遇到bash在命令行中没有以这种方式进行数学运算的问题。你想要的是类似的东西
declare -ri size=16*512*512
# or just "let size=16*512*512", the "declare -ri" just makes it a read-only integer
$DOANTS/SmoothImage $2 $size $RESULTS/Registration/NiftyReg/StructureGuided/Pat28_MLAF0113_pv_Aff_BSpline_Iso_ArgMax.nii.gz $1 $RESULTS/Registration/NiftyReg/StructureGuided/Pat28_${CASES[$i]}_Prostate_Aff_BSpline_Iso_ArgMax_smoothed.nii.gz
我想这就是你要去的地方。如果你想要一些证据来证明这是有效的,在你的bash命令行上,试试-
$ let size=16*512*512
$ echo $size
$ 4194304
您的C++可能还不错(虽然我还没有详细介绍,但乍一看还可以(。问题在于你的狂欢。如果你想要像内联数学这样的功能,你可以考虑用Python来驱动你的C++程序。只是一个想法。