How to output label map in C++?

hello,
I am using label map to remove some undesirable regions in binary image.
first, call BinaryImageToShapeLabelMapFilter to get label map, then output the label map and all the objects’ centroids.
I have checked the label map result’s m_labelobject_container, before output it to the main function, its object container is normal. and when I have got the label map in main function,all the elements in m_labelobject_container is null.
Is there anything wrong with my code?
how to output the label map normally?
thanks a lot.

Here is my code segment:

	template< typename PixelType = bool, uint16_t dim = 3 >
	static void  GetCenroidofObjects(itk::SmartPointer<itk::Image<PixelType, dim>>& image,
		std::map<int, itk::Point<double, dim>>& rmCen,
		itk::LabelMap<itk::ShapeLabelObject<uint64_t, dim>>*& outLabelMap)
	{
		//** calculate all the regions's priority**//
		using BinaryImageToShapeLabelMapFilterType = itk::BinaryImageToShapeLabelMapFilter<itk::Image<PixelType, dim>>;
		BinaryImageToShapeLabelMapFilterType::Pointer binaryImageToShapeLabelMapFilter =
			BinaryImageToShapeLabelMapFilterType::New();
		binaryImageToShapeLabelMapFilter->SetFullyConnected(true);
		binaryImageToShapeLabelMapFilter->SetInput(image);
		binaryImageToShapeLabelMapFilter->Update();
		/*auto*/ outLabelMap = binaryImageToShapeLabelMapFilter->GetOutput();
		auto num = outLabelMap->GetNumberOfLabelObjects();
		
		//uint16_t largestAreaIdx = 0;
		/*uint64_t largestArea = 0;*/
		mippVolumeEngineLog::GetInstance()->PrintDebugInfo(LogInfoType::Information,
			L"region num", std::to_wstring(num));
		
		//concurrency::parallel_for(0, int(num), [&](uint32_t i)
			for (unsigned int i = 0; i < num; i++)
			{
				BinaryImageToShapeLabelMapFilterType::OutputImageType::LabelObjectType* labelObject =
					outLabelMap->GetNthLabelObject(i);
			
				rmCen.emplace(std::make_pair(labelObject->GetLabel(),labelObject->GetCentroid()));

			}//);
	}
int main()
{
        using CentroidType = itk::Point<double, g_Dimension>;
	itk::LabelMap<itk::ShapeLabelObject<uint64_t, 3>>* outLabelMap;
	std::map<int, CentroidType> mCen;
	ITKWrapper::GetCenroidofObjects<bool>(binRes, mCen, outLabelMap);
	//outLabelMap->RemoveLabel(2000);
}

You should declare outLabelMap as a smart pointer, e.g. itk::LabelMap<itk::ShapeLabelObject<uint64_t, 3>>::Pointer outLabelMap;, then assign as a return value: outLabelMap = GetCenroidofObjects(binRes, mCen);.

Take a look at this example.

Thanks for your help. I learned again here.
But it still cannot work in my case. I have learned the example how to return object from function.
In my case, the function is template function. I tried to return a ITK smart pointer, there are some errors in the compilation. For simplicity’s sake, I add a simple function as below.
Here is my code, the compilation is failed with several errors .

	template< typename PixelType = int >
	static itk::Image<PixelType, 2>::Pointer
		ReturnSmartPointer()
	{
		auto                image = itk::Image<PixelType, 2>::New();
		itk::Index<2>       corner = { { 0, 0 } };
		itk::Size<2>        size = { { 10, 10 } };
		itk::ImageRegion<2> region(corner, size);
		image->SetRegions(region);
		image->Allocate();

		return image;
	}

Here are the failed output with several errors:

1>E:\GIT\repos\PostProcessingAlgorithm\Include\Segmentation\ITKWrapper.hpp(1004,2): warning C4346: 'Pointer': dependent name is not a type
1>E:\GIT\repos\PostProcessingAlgorithm\Include\Segmentation\ITKWrapper.hpp(1004,2): message : prefix with 'typename' to indicate a type
1>E:\GIT\repos\PostProcessingAlgorithm\Include\Segmentation\ITKWrapper.hpp(1004,2): error C2061: syntax error: identifier 'Pointer'
1>E:\GIT\repos\PostProcessingAlgorithm\Include\Segmentation\ITKWrapper.hpp(1006,2): error C2334: unexpected token(s) preceding '{'; skipping apparent function body

And then, I have tried the other two functions, no error in the compilation.
first, it is a template function without return. it can be compiled successfully.

	template< typename PixelType = int >
	static void/*itk::Image<PixelType, 2>::Pointer*/
		ReturnSmartPointer()
	{
		auto                image = itk::Image<PixelType, 2>::New();
		itk::Index<2>       corner = { { 0, 0 } };
		itk::Size<2>        size = { { 10, 10 } };
		itk::ImageRegion<2> region(corner, size);
		image->SetRegions(region);
		image->Allocate();

		//return image;
	}

Second, it is a non-template function with smart pointer return type.it can be compiled successfully.

	//template< typename PixelType = int >
	static itk::Image<int, 2>::Pointer
		ReturnSmartPointer()
	{
		auto                image = itk::Image<int, 2>::New();
		itk::Index<2>       corner = { { 0, 0 } };
		itk::Size<2>        size = { { 10, 10 } };
		itk::ImageRegion<2> region(corner, size);
		image->SetRegions(region);
		image->Allocate();

		return image;
	}

I am not good at this part, and looking forward to the help about it. How to write a template function with itk smart pointer return type?
Thanks a lot.

I found the solution. it has nothing to do with ITK.
" prepend typename before itk::Image<int, 2>::Pointer as it is a dependent type ."
from
https://stackoverflow.com/questions/16131838/error-dependent-name-is-not-a-type-when-use-typedef-type-in-class-as-return
In case to someone else encounter the same question, keep all the question and answer here.

I was going to suggest two options:

template< typename PixelType = int >
	static auto
		ReturnSmartPointer() -> itk::Image<PixelType, 2>::Pointer
	{

and

template< typename PixelType = int >
	static itk::SmartPointer<itk::Image<PixelType, 2>>
		ReturnSmartPointer()
	{

I am more confident about the second suggestion.

Thank you so so so much.
I have tested just now, both of them can work. Thanks again. :smiley:

1 Like