[Insight-users] [Question] 3D Fill
Maximilien Renard
iixamaxii at gmail.com
Thu Aug 20 04:19:55 EDT 2009
Hi ITK users,
I have succeeded in using the PasteImageFilter. I, obviously, was dumb
enough to have misunderstood the doc. Now that I have carefully read
it, I spotted what I was doing wrong.
Well, now I'm facing another problem with the ConnectedThresholdImageFilter.
When I execute the code below, I get the following output which is OK :
TEST1 345 304 0
TEST2 0 4000 4095 4095
TEST3 4095
TEST4 512 512 1
If I set the original image as the new image (using SetITK3DImage() )
I see it as it was, so no problem with input.
If I set the filter output as the new image, it is completely black
(I've checked it and there are no other values than 0).
If I set the seed pixel to 4095, it is displayed in white as expected
and I've also checked that it is white in the original image.
The input image is a thresholded image which is binary (0 and 4095 are
the two gray levels) but it could also be not segmented.
Do someone have any clue what I'm doing wrong ?
Thank you very much for any help,
Regards,
Maximilien Renard
void CVolumeData::Fill3D(int X, int Y, int Z, unsigned short
LowThreshold, unsigned short HighThreshold, unsigned short
ReplacementValue) {
typedef itk::ConnectedThresholdImageFilter < ITK3DImageType,
ITK3DImageType> FilterType;
FilterType::Pointer filter = FilterType::New();
ITK3DImageType::IndexType seed;
seed[0] = X;
seed[1] = Y;
seed[2] = Z;
qDebug() << "TEST1" << X << Y << Z;
int DimX, DimY, DimZ, x, y, z;
unsigned short Min, Max;
GetMinMaxValue(Min, Max);
qDebug() << "TEST2" << Min << LowThreshold << HighThreshold << Max;
qDebug() << "TEST3" << GetVoxel(X, Y, Z);
filter->SetSeed(seed);
filter->SetLower(LowThreshold);
filter->SetUpper(HighThreshold);
filter->SetReplaceValue(2000);
filter->SetInput(GetITK3DImage());
filter->Update();
SetITK3DImage(filter->GetOutput());
GetDimensions(DimX, DimY, DimZ);
qDebug() << "TEST4" << DimX << DimY << DimZ;
}
2009/7/30 Maximilien Renard <iixamaxii at gmail.com>:
> Hi Luis,
>
> Thank you for your answer!
>
> I've taken a look to the MaskImageFilter and the
> MaskNegatedImageFilter. If I'm right, the MaskNegatedImageFilter would
> be what I want to do BUT it replaces the pixels of the MaskImage with
> a value != 0 by a 0 pixel in the output image. I could not figure out
> if it possible to change that behaviour and make the filter replace
> those pixels by another value (like 4000 for example).
> Is this possible ?
>
> Thank you very much,
>
> Best regards,
>
>
> Maximilien Renard
>
> 2009/7/28 Luis Ibanez <luis.ibanez at kitware.com>:
>> Hi Maximilien,
>>
>> A) For pasting the values back in to the image,
>> you may want to use the MaskImageFilter or
>> the NegatedMaskImageFilter.
>>
>>
>> B) Most ITK filters are N-Dimensional.
>> The region growing filters will work fine in
>> 2D, 3D, 4D....
>>
>> C) You may start by debugging your process of
>> copying images in and out of ITK. It doesn't
>> seem that your problem is related to the
>> region growing itself.
>>
>>
>> Regards,
>>
>>
>> Luis
>>
>>
>> ------------------------------------------------
>> On Sat, Jul 25, 2009 at 6:17 AM, Maximilien Renard <iixamaxii at gmail.com>
>> wrote:
>>>
>>> Hi there,
>>>
>>> I'm trying to realize a function (Fill3D) that uses the connected
>>> threshold filter to fill a region of a 3D image with another value
>>> based on a threshold.
>>>
>>> This is the function I'm using now :
>>>
>>> void CVolumeData::Fill3D(int X, int Y, int Z, unsigned short
>>> LowThreshold, unsigned short HighThreshold, unsigned short
>>> ReplacementValue) {
>>> typedef itk::ConnectedThresholdImageFilter < ITK3DImageType,
>>> ITK3DImageType> FilterType;
>>> FilterType::Pointer filter = FilterType::New();
>>> ITK3DImageType::IndexType seed;
>>> seed[0] = X;
>>> seed[1] = Y;
>>> seed[2] = Z;
>>> CVolumeData *pResultImage;
>>> int DimX, DimY, DimZ, x, y, z;
>>>
>>> filter->SetSeed(seed);
>>> filter->SetLower(LowThreshold);
>>> filter->SetUpper(HighThreshold);
>>> filter->SetReplaceValue(4000);
>>>
>>> filter->SetInput(GetITK3DImage());
>>> filter->Update();
>>> pResultImage = new CVolumeData(m_MainView);
>>> pResultImage->SetITK3DImage(filter->GetOutput());
>>>
>>> GetDimensions(DimX, DimY, DimZ);
>>>
>>> for (z = 0; z < DimZ; z++)
>>> for (y = 0; y < DimY; y++)
>>> for (x = 0; x < DimX; x++) {
>>> if (pResultImage->GetVoxel(x, y, z) >=
>>> 4000) {
>>> SetVoxel(x, y, z,
>>> ReplacementValue);
>>> }
>>> }
>>>
>>> delete(pResultImage);
>>> }
>>>
>>> The last 3 for (DimZ, DimY and DimX) are necessary to replace the
>>> filled zone in the original image without replacing the zone of the
>>> original image which lies outside the threshold values. Sadly it takes
>>> lots of time. Is there a better way to do this ?
>>>
>>> Next question, I need to do a Fill2D function too. Here again I have a
>>> problem. I use the extract image filter to extract the slice I need,
>>> then I apply the Fill3D filter on the image (Fill3D that doesn't work
>>> properly now) and what I wanted to do is use the PasteImageFilter to
>>> paste the result of the Fill3D (which has only one slice) back into
>>> the original 3D Image.
>>>
>>> But once again it doesn't work. The result is that the new slice is
>>> entirely black...
>>>
>>> void CVolumeData::Fill2D(int X, int Y, int Z, unsigned short
>>> LowThreshold, unsigned short HighThreshold, unsigned short
>>> ReplacementValue, int SubView) {
>>> int DimX, DimY, DimZ;
>>> int x, y, z;
>>>
>>> GetDimensions(DimX, DimY, DimZ);
>>>
>>> typedef itk::ExtractImageFilter< ITK3DImageType, ITK3DImageType >
>>> FilterType;
>>> FilterType::Pointer filter = FilterType::New();
>>>
>>> ITK3DImageType::RegionType inputRegion =
>>> GetITK3DImage()->GetLargestPossibleRegion();
>>>
>>> if (SubView == CMainView::MODE_XY) {
>>> CVolumeData SliceVolume(m_MainView);
>>>
>>> SliceVolume.CreateVolume(DimX, DimY, 1, 1.0f, 1.0f, 1.0f,
>>> 0, false);
>>>
>>> ITK3DImageType::SizeType size = inputRegion.GetSize();
>>> size[2] = 1;
>>> ITK3DImageType::IndexType start = inputRegion.GetIndex();
>>> start[2] = Z;
>>> ITK3DImageType::RegionType desiredRegion;
>>> desiredRegion.SetSize(size);
>>> desiredRegion.SetIndex(start);
>>>
>>> filter->SetExtractionRegion(desiredRegion);
>>>
>>> filter->SetInput(GetITK3DImage());
>>>
>>> filter->Update();
>>>
>>> SliceVolume.SetITK3DImage(filter->GetOutput());
>>>
>>> SliceVolume.Fill3D(X, Y, 0, LowThreshold, HighThreshold,
>>> ReplacementValue);
>>>
>>> typedef itk::PasteImageFilter< ITK3DImageType,
>>> ITK3DImageType,
>>> ITK3DImageType > ImageReplacementFilterType;
>>> ImageReplacementFilterType::Pointer ImageReplacementFilter
>>> =
>>> ImageReplacementFilterType::New();
>>>
>>>
>>> ImageReplacementFilter->SetSourceImage(SliceVolume.GetITK3DImage());
>>>
>>> ImageReplacementFilter->SetSourceRegion(SliceVolume.GetITK3DImage()->GetLargestPossibleRegion());
>>>
>>>
>>> ImageReplacementFilter->SetDestinationImage(GetITK3DImage());
>>> ImageReplacementFilter->SetDestinationIndex(start);
>>>
>>> ImageReplacementFilter->Update();
>>> SetITK3DImage(ImageReplacementFilter->GetOutput());
>>> }
>>> }
>>>
>>> I'd enjoy any kind of help !
>>>
>>> Thank you very much,
>>>
>>> Best regards,
>>>
>>>
>>> Maximilien Renard
>>> _____________________________________
>>> Powered by www.kitware.com
>>>
>>> Visit other Kitware open-source projects at
>>> http://www.kitware.com/opensource/opensource.html
>>>
>>> Please keep messages on-topic and check the ITK FAQ at:
>>> http://www.itk.org/Wiki/ITK_FAQ
>>>
>>> Follow this link to subscribe/unsubscribe:
>>> http://www.itk.org/mailman/listinfo/insight-users
>>
>>
>
More information about the Insight-users
mailing list