Problems converting binary array to ITK image

Dear all,

I would like to read in a binary array and convert part of this array into an ITK image. I would like to use the ITK image later on as a mask.
However, my code is not working yet, there has to be a mistake somewhere.
It always crashes in the last line:
importFilter->SetImportPointer(localBuffer, dimPET[0]*dimPET[1]*dimPET[2], importImageFilterWillOwnTheBuffer);

Here is what I have until now:

typedef unsigned char PixelType;
typedef itk::Image< PixelType, 3 > ImageTypeChar;
typedef itk::ImportImageFilter< PixelType, 3 > ImportFilterTypeChar;
ImportFilterTypeChar::Pointer importFilter = ImportFilterTypeChar::New();

ImportFilterTypeChar::SizeType size;
ImageTypeChar::Pointer maskImage;
ifstream prjfile;

//image size
unsigned int dimPET[3] = {{144,144,275}};
//voxel size
float voxelSize[3] = {{4,4,4}};

fstream voiFile;
//open binary file
voiFile.open(voiPath, ios::in | ios::binary);

if (voiFile.is_open() == false) {
std::cout << “Cannot open voi file\n”;
exit(0);
}
//opening the file worked
else {
streampos begin, end;
begin = voiFile.tellg();
voiFile.seekg(0, ios::end);
end = voiFile.tellg();
//get the total file size
int fileSize = (end - begin);
//vector to store the elements of the

vector<char> wholeFile(fileSize);
voiFile.seekg(0, std::ios::beg);
voiFile.read(&wholeFile[0], fileSize);
vector<unsigned char> mask(fileSize);
    //convert whole array to unsigned char - I do not know if this is necessary?
transform(wholeFile.begin(), wholeFile.end(), mask.begin(), [](auto& elem) {return ((unsigned char)(elem)); });
   //in the end, I only want to convert the second half of the image into an ITK image
vector< PixelType> voi(mask.begin() + (fileSize / 2), mask.end());

voiFile.close();
		
size[0]= dimPET[0];
size[1] = dimPET[1];
size[2] = dimPET[2];

ImportFilterTypeChar::IndexType start;
start.Fill(0);

ImportFilterTypeChar::RegionType region;
region.SetIndex(start);
region.SetSize(size);

importFilter->SetRegion(region);
double origin[3];
origin[0]= 0;
origin[1] = 0;
origin[2] = 0;

importFilter->SetOrigin(origin);
double spacing[3];
spacing[0] = voxelSize[0];
    spacing[1] = voxelSize[1];
spacing[2] = voxelSize[2];
importFilter->SetSpacing(spacing);

PixelType * localBuffer = &voi[0];
importFilter->SetOrigin(origin);
importFilter->SetSpacing(spacing);
const bool importImageFilterWillOwnTheBuffer = true;		                                 
    importFilter->SetImportPointer(localBuffer, dimPET[0]*dimPET[1]*dimPET[2], importImageFilterWillOwnTheBuffer);
		
	}
}

Is DimPET already the size of half image ? Otherwise you are overreading the buffer.

Dear tim,

yes, dimPET is half the size of the image…

The code seems good otherwise. Note that I’m not sure that letting the import filter own a vector memory block is a safe behavior. Did you try to run your code through a debugger to have information about your crash ?

Dear Tim,

thanks for your help. I fixed the problem. There was a problem with this
line:

transform(wholeFile.begin(), wholeFile.end(), mask.begin(), [](auto&
elem) {return ((unsigned char)(elem)); });

I changed the imageType to float (what was actually what I wanted) and
changed this line to:

transform(wholeFile.begin(), wholeFile.end(), mask.begin(), [](auto& elem)
{return ((float)(elem)); });

And now its working. I do not really know why it was not working before…

Thanks a lot anyway,

Regards

Elli

2 Likes

Ok, I can’t tell you what was wrong, but I’m glad you managed to get a functional code. :+1:
Maybe something about “char” / “unsigned char” (which are not strictly equivalent) ?
Thanks for reporting the fix.

1 Like