Hi guys,
We have included elastixlib.h and imported elastix-4.9.lib as a part of a simple C++ project, so that we can call RegisterImages(…).
As a test on that code, we just read fixed image and moving image using itkImageFileReader and later casting the output as a itk::DataObject, type used by Elastix (following also some ideas in an old elastix mailing list post). Parameters and images are read fine.
However we get a runtime error after calling RegisterImage from elastix:
“Unhandled exception at 0x00007FFBCAB08428 (elastix-4.9.dll) in Registration_uTest.exe: 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF.”
The basic code looks as follows:
using namespace elastix;
typedef itk::DataObject Image;
typedef Image::Pointer ImagePointer; // static_cast<typename itk::DataObject::Pointer>
typedef itk::ParameterFileParser::ParameterMapType ParameterMapType;
typedef std::vector< itk::ParameterFileParser::ParameterMapType > ParameterMapListType;
typedef itk::ParameterFileParser ParserType;
typedef itk::ParameterFileParser ParserType;
ParameterMapType& ParameterFileParser(std::string ParameterFile);
int main()
{
std::string ParameterPath = "D:\\Test\\Par0040affineModified.txt";
ParameterMapType& parameters = ParameterFileParser(ParameterPath);
const char* fixedimagePath = "D:\\Registration\\input\\fixedImage.nii";
const char* movingimagePath = "D:\\Registration\\input\\movingImage.nii";
const unsigned int Dimension = 3;
typedef unsigned short PixelType;
typedef itk::Image<PixelType, Dimension> ImageType;
typedef itk::ImageFileReader<ImageType> ReaderType;
ReaderType::Pointer fixedImageReader = ReaderType::New();
ReaderType::Pointer movingImageReader = ReaderType::New();
try
{
fixedImageReader->SetFileName(fixedimagePath);
fixedImageReader->Update();
movingImageReader->SetFileName(movingimagePath);
movingImageReader->Update();
}
catch (itk::ExceptionObject& err)
{
std::cerr << "ExceptionObject caught !" << std::endl;
std::cerr << err << std::endl;
}
Here the relevant part :
elastix::ELASTIX::ImagePointer fixedImage = static_cast<elastix::ELASTIX::ImagePointer>(fixedImageReader->GetOutput());
elastix::ELASTIX::ImagePointer MovingImage = static_cast<elastix::ELASTIX::ImagePointer>(movingImageReader->GetOutput());
elastix::ELASTIX::ImagePointer output_image;
int error = 0;
ELASTIX* elastix1 = new ELASTIX();
try
{
error = elastix1->RegisterImages(static_cast<typename itk::DataObject::Pointer>(fixedImage.GetPointer()),
static_cast<typename itk::DataObject::Pointer>(movingImage.GetPointer(),
parameters, // Parameter map read in previous code
"c:\\Flair2MPRage", // Directory where output is written, if enabled
true, // Enable/disable writing of elastix.log
true, // Enable/disable output to console
0, // Provide fixed image mask (optional, 0 = no mask) For WMLD Mask is not available
0 // Provide moving image mask (optional, 0 = no mask) For WMLD Mask is not available
);
}
catch (const std::exception& exc/*itk::ExceptionObject& err*/)
{
std::cout << "Caught exception \"" << exc.what() << "\"\n";
}
if (error == 0)
{
if (elastix1->GetResultImage().IsNotNull())
{
output_image = static_cast<typename itk::DataObject::Pointer>(
elastix1->GetResultImage().GetPointer());
}
}
else
{
// Registration failure. Do some error handling.
}
// Clean up memory.
delete elastix1;
return 1;
}
maybe you have any hint on this and how we should call elastix from C++ ?
Thanks in advance!