Remove small component

I intend to remove from sitk::Image the smallest component from it (in the first stage). For that, I wrote:

BOOL CMyDoc::Segement(sitk::Image& img)
{
		sitk::Image imgTemp(img);
		int64_t nMaxLabel = 0, nMaxSize = 0;
		sitk::Image cc = sitk::SLIC(imgTemp);
		sitk::LabelIntensityStatisticsImageFilter statistics;
		statistics.Execute(cc, imgTemp);
		std::vector<int64_t>::iterator it;
		std::vector<int64_t> labels = statistics.GetLabels();
		for (it = labels.begin(); it != labels.end(); ++it)
		{
			if (nMaxLabel < statistics.GetPhysicalSize(*it))
			{
				nMaxLabel = *it;
				nMaxSize = statistics.GetPhysicalSize(*it);
			}
		}

		CArray<long, long> arr;
		for (it = labels.begin(); it != labels.end(); ++it)
		{
			if (statistics.GetPhysicalSize(*it) > nMaxSize * 0.5)
				arr.Add(*it);
		}

My question is, how can use it arr object to remove the points from the resulting image ? What kind of filter should I use ?

I have read about this filter:https://itk.org/SimpleITKDoxygen/html/classitk_1_1simple_1_1MaskNegatedImageFilter.html, but I don’t know how to use it in this case … I mean, what mask image should I provide ? https://itk.org/SimpleITKDoxygen/html/classitk_1_1simple_1_1MaskNegatedImageFilter.html#ad5c71726224210803c9233e5ed8473d0

Might be a trivial question, but for me is not. Thank you for your patience and your time.

Flaviu.

Relabel filter reorders the labels and removes the small ones. Would that work for you?

1 Like

Good point, I will try it.

I have tried myself something:

	std::vector<unsigned int> size = imgTemp.GetSize();
	int64_t* p = imgTemp.GetBufferAsInt64();
	unsigned int nCount = size[0] * size[1] * size[2];
	for (unsigned int i = 0; i < nCount; ++i)
	{
		TRACE("%d===%I64d\n", i, p[i]);
	}

but this is no fit with statistics.GetLabels() method:

sitk::ERROR: The image is of type: 16-bit signed integer but the GetBuffer access method requires type: 64-bit signed integer!

… hmm … what could I plugin the data ?

@dzenanz, seem to work sitk::RelabelComponent filter … :slight_smile: the resulting image are not very sharp, but it is a step forward.

I have used sitk::RelabelComponent with pretty well results. But I noticed that if I denoise the image before applying this filter I got an error. Here is the code:

	sitk::Image imgTemp(imgOrg);
	sitk::Image curvature = sitk::CurvatureFlow(imgTemp, 0.125, 5);
	imgOuput = sitk::RelabelComponent(curvature, 200);

and the error is: sitk::ERROR: Pixel type: 64-bit float is not supported in 3D byclass itk::simple::RelabelComponentImageFilter

If I didn’t apply sitk::CurvatureFlow I have no problem … how can I overcome this error ?

Thanks much.
Flaviu.

@blowekamp @zivy?

It makes no sense to run diffusion on a labeled image and then “relabel” it. I can’t help here.

“run diffusion on a labeled image” imgOrg is not labeled image. Here is the functional code:

imgOut = sitk::CurvatureFlow(imgOrg, 0.022, 1);

And here is the code with the error:

sitk::Image curvature = sitk::CurvatureFlow(imgOrg, 0.022, 1);
imgOut = sitk::RelabelComponent(curvature, 200);

The fact is that another filter is run without any problem:

sitk::Image curvature = sitk::CurvatureFlow(imgOrg, 0.022, 1);
imgOut = sitk::ConnectedThreshold(curvature, list, 1400, 2600);

I guess I have found a workaround for CurvatureFlow / RelabelComponent issue, and I am listing here for anyone who meet the same problem:

sitk::Image curvature = sitk::CurvatureFlow(imgOrg, 0.022, 1);
sitk::Image imgCast = sitk::Cast(curvature, imgOrg.GetPixelID());
imgOut = sitk::RelabelComponent(imgCast, 200);

Please correct me if I did something wrong.

Flaviu.

1 Like