Remove Noisy Objects

Hi!

I am trying to remove labels from Label Map, which belong to noisy objects. For doing that, I have created the following code:

ITKImgLabelType2D::Pointer
RemoveNoisyObjects( const ITKImgLabelType2D::Pointer& imgIn, std::ofstream& file ){
	itk::Vector<double, 1> contourSize;
	std::vector<unsigned long> labelsToRemove;

	ITKImgLabelType2D::Pointer output = ITKImgLabelType2D::New();
	// We convert a binary image to a shape label map
	using BinaryImageToShapeLabelMapFilterType = itk::BinaryImageToShapeLabelMapFilter<ITKImgLabelType2D>;
	BinaryImageToShapeLabelMapFilterType::Pointer binaryImageToShapeLabelMapFilter = BinaryImageToShapeLabelMapFilterType::New();
	binaryImageToShapeLabelMapFilter->SetInput( imgIn );
	binaryImageToShapeLabelMapFilter->Update();

	// We find the largest contour
	double maxContour = 0;
	auto numberTotalObj = binaryImageToShapeLabelMapFilter->GetOutput()->GetNumberOfLabelObjects();
	file << "numberTotalObj: " << numberTotalObj << std::endl;

	if ( numberTotalObj > 1 ){
		for ( unsigned int cont = 0; cont < numberTotalObj; ++cont ){
			BinaryImageToShapeLabelMapFilterType::OutputImageType::LabelObjectType* labelObject =
				binaryImageToShapeLabelMapFilter->GetOutput()->GetNthLabelObject( cont );

			contourSize[cont] = labelObject->GetNumberOfPixels();

			if ( contourSize[cont] > maxContour )
				maxContour = contourSize[cont];
		}

		// We find similar contours of the largest one
		for ( unsigned int obj = 0; obj < numberTotalObj; ++obj ){
			double cmp = contourSize[obj] / maxContour;
			BinaryImageToShapeLabelMapFilterType::OutputImageType::LabelObjectType* labelObject2 =
				binaryImageToShapeLabelMapFilter->GetOutput()->GetNthLabelObject( obj );
			if (cmp < 0.6)
				labelsToRemove.push_back(labelObject2->GetLabel());
		}

		// We remove the objects which have not similarity with the largest one
		for ( unsigned long iLabel : labelsToRemove )
			binaryImageToShapeLabelMapFilter->GetOutput()->RemoveLabel( iLabel );

		// We convert shape label map to a binary image
		using LabelMapToLabelImageFilterType =
			itk::LabelMapToLabelImageFilter<BinaryImageToShapeLabelMapFilterType::OutputImageType, ITKImgLabelType2D>;
		auto labelMapToLabelImageFilter = LabelMapToLabelImageFilterType::New();
		labelMapToLabelImageFilter->SetInput( binaryImageToShapeLabelMapFilter->GetOutput() );
		try{
			labelMapToLabelImageFilter->Update();
		}
		catch ( const itk::ExceptionObject& err ){
			file << "ExceptionObject caught !" << __func__ << std::endl;
			file << err.what() << std::endl;
		}
		WriteImage(labelMapToLabelImageFilter->GetOutput(), "labelMapToLabelImageFilter.jpg", file);

		output = labelMapToLabelImageFilter->GetOutput();
	}
	else{
		file << "No hay otros objetos que borrar" << std::endl;
		output = imgIn;
	}
	file << "Return " << std::endl;
	return output;

Where 'ITKImgLabelType2D = itk::Image<unsigned char, 2>

If I use this function, if the image I want to process has more than one object, my execution finishes in the return statement.

However, if I don’t refactor the function and I insert all the code in the main, it works with some images. But with some others images, it also doesn’t work.

Just for you to have an idea of my algorithm, It follows the next order:

  1. Code of RemoveNoisyObjects → Here I get a 2D mask.

  2. Apply the 2D mask to a 3D mask

After trying to solve it, I have found that if I put the next sentance:

ITKImgLabelType2D::RegionType desiredRegion;

after applying the 2D mask, it all works.

Have you got an idea of what could be the error?

By the way, do you know some way to recognise if an image corresponds to a thorax or head? I mean, to which part of the body corresponds an image?

Thank you for your time,
Cristina

There is a DICOM tag for that. If your image is in DICOM format you could use that, and hope it is not empty.

I didn’t fully understand the main problem. If you don’t want to use this as a function, and put this code in main, then it sometimes works, sometimes doesn’t? Does it always work as a function? If so, why don’t you keep it as a function and use it that way? Or does it never works properly as a function? What is the output when it doesn’t work?