Difference between revisions of "Example Thresholding"

From BoofCV
Jump to navigationJump to search
m
m
(6 intermediate revisions by the same user not shown)
Line 11: Line 11:


Example Code:
Example Code:
* [https://github.com/lessthanoptimal/BoofCV/blob/v0.21/examples/src/boofcv/examples/segmentation/ExampleThresholding.java ExampleThresholding.java]
* [https://github.com/lessthanoptimal/BoofCV/blob/v0.37/examples/src/main/java/boofcv/examples/segmentation/ExampleThresholding.java ExampleThresholding.java]


Concepts:
Concepts:
* Segmentation
* Segmentation
* Thresholding
* Thresholding
Relevant Videos:
* [https://youtu.be/TGg-xgTyaU8?t=525 New Algorithms in v0.28]


Relevant Examples/Tutorials:
Relevant Examples/Tutorials:
Line 42: Line 45:


// convert into a usable format
// convert into a usable format
ImageFloat32 input = ConvertBufferedImage.convertFromSingle(image, null, ImageFloat32.class);
GrayF32 input = ConvertBufferedImage.convertFromSingle(image, null, GrayF32.class);
ImageUInt8 binary = new ImageUInt8(input.width,input.height);
GrayU8 binary = new GrayU8(input.width,input.height);


// Display multiple images in the same window
// Display multiple images in the same window
Line 57: Line 60:


// Local method
// Local method
GThresholdImageOps.localSquare(input, binary, 28, 1.0, true, null, null);
GThresholdImageOps.localMean(input, binary, ConfigLength.fixed(57), 1.0, true, null, null,null);
gui.addImage(VisualizeBinaryData.renderBinary(binary, false, null),"Local: Square");
gui.addImage(VisualizeBinaryData.renderBinary(binary, false, null),"Local: Square");
GThresholdImageOps.localBlockMinMax(input, binary, 10, 1.0, true, 15 );
GThresholdImageOps.blockMinMax(input, binary, ConfigLength.fixed(21), 1.0, true, 15 );
gui.addImage(VisualizeBinaryData.renderBinary(binary, false, null),"Local: Block Min-Max");
gui.addImage(VisualizeBinaryData.renderBinary(binary, false, null),"Local: Block Min-Max");
GThresholdImageOps.localGaussian(input, binary, 42, 1.0, true, null, null);
GThresholdImageOps.blockMean(input, binary, ConfigLength.fixed(21), 1.0, true );
gui.addImage(VisualizeBinaryData.renderBinary(binary, false, null),"Local: Block Mean");
GThresholdImageOps.blockOtsu(input, binary, false,ConfigLength.fixed(21),0.5, 1.0, true );
gui.addImage(VisualizeBinaryData.renderBinary(binary, false, null),"Local: Block Otsu");
GThresholdImageOps.localGaussian(input, binary, ConfigLength.fixed(85), 1.0, true, null, null);
gui.addImage(VisualizeBinaryData.renderBinary(binary, false, null),"Local: Gaussian");
gui.addImage(VisualizeBinaryData.renderBinary(binary, false, null),"Local: Gaussian");
GThresholdImageOps.localSauvola(input, binary, 5, 0.30f, true);
GThresholdImageOps.localSauvola(input, binary, ConfigLength.fixed(11), 0.30f, true);
gui.addImage(VisualizeBinaryData.renderBinary(binary, false, null),"Local: Sauvola");
gui.addImage(VisualizeBinaryData.renderBinary(binary, false, null),"Local: Sauvola");
GThresholdImageOps.localNick(input, binary,  ConfigLength.fixed(11), -0.2f, true);
gui.addImage(VisualizeBinaryData.renderBinary(binary, false, null),"Local: NICK");


// Sauvola is tuned for text image.  Change radius to make it run better in others.
// Sauvola is tuned for text image.  Change radius to make it run better in others.

Revision as of 19:39, 21 December 2020

Thresholding gray scale images is one of the most basic ways to segment an image. It is quick and effective in many situations. BoofCV provides several algorithms for computing both global and locally adaptive thresholds.

Example Code:

Concepts:

  • Segmentation
  • Thresholding

Relevant Videos:

Relevant Examples/Tutorials:

Example Code

/**
 * Demonstration of different techniques for automatic thresholding an image to create a binary image.  The binary
 * image can then be used for shape analysis and other applications.  Global methods apply the same threshold
 * to the entire image.  Local methods compute a local threshold around each pixel and can handle uneven
 * lighting, but produce noisy results in regions with uniform lighting.
 *
 * @see boofcv.examples.imageprocessing.ExampleBinaryOps
 *
 * @author Peter Abeles
 */
public class ExampleThresholding {

	public static void threshold( String imageName ) {
		BufferedImage image = UtilImageIO.loadImage(imageName);

		// convert into a usable format
		GrayF32 input = ConvertBufferedImage.convertFromSingle(image, null, GrayF32.class);
		GrayU8 binary = new GrayU8(input.width,input.height);

		// Display multiple images in the same window
		ListDisplayPanel gui = new ListDisplayPanel();

		// Global Methods
		GThresholdImageOps.threshold(input, binary, ImageStatistics.mean(input), true);
		gui.addImage(VisualizeBinaryData.renderBinary(binary, false, null),"Global: Mean");
		GThresholdImageOps.threshold(input, binary, GThresholdImageOps.computeOtsu(input, 0, 255), true);
		gui.addImage(VisualizeBinaryData.renderBinary(binary, false, null),"Global: Otsu");
		GThresholdImageOps.threshold(input, binary, GThresholdImageOps.computeEntropy(input, 0, 255), true);
		gui.addImage(VisualizeBinaryData.renderBinary(binary, false, null),"Global: Entropy");

		// Local method
		GThresholdImageOps.localMean(input, binary, ConfigLength.fixed(57), 1.0, true, null, null,null);
		gui.addImage(VisualizeBinaryData.renderBinary(binary, false, null),"Local: Square");
		GThresholdImageOps.blockMinMax(input, binary, ConfigLength.fixed(21), 1.0, true, 15 );
		gui.addImage(VisualizeBinaryData.renderBinary(binary, false, null),"Local: Block Min-Max");
		GThresholdImageOps.blockMean(input, binary, ConfigLength.fixed(21), 1.0, true );
		gui.addImage(VisualizeBinaryData.renderBinary(binary, false, null),"Local: Block Mean");
		GThresholdImageOps.blockOtsu(input, binary, false,ConfigLength.fixed(21),0.5, 1.0, true );
		gui.addImage(VisualizeBinaryData.renderBinary(binary, false, null),"Local: Block Otsu");
		GThresholdImageOps.localGaussian(input, binary,  ConfigLength.fixed(85), 1.0, true, null, null);
		gui.addImage(VisualizeBinaryData.renderBinary(binary, false, null),"Local: Gaussian");
		GThresholdImageOps.localSauvola(input, binary,  ConfigLength.fixed(11), 0.30f, true);
		gui.addImage(VisualizeBinaryData.renderBinary(binary, false, null),"Local: Sauvola");
		GThresholdImageOps.localNick(input, binary,  ConfigLength.fixed(11), -0.2f, true);
		gui.addImage(VisualizeBinaryData.renderBinary(binary, false, null),"Local: NICK");

		// Sauvola is tuned for text image.  Change radius to make it run better in others.

		// Show the image image for reference
		gui.addImage(ConvertBufferedImage.convertTo(input,null),"Input Image");

		String fileName =  imageName.substring(imageName.lastIndexOf('/')+1);
		ShowImages.showWindow(gui,fileName);
	}

	public static void main(String[] args) {
		// example in which global thresholding works best
		threshold(UtilIO.pathExample("particles01.jpg"));
		// example in which adaptive/local thresholding works best
		threshold(UtilIO.pathExample("segment/uneven_lighting_squares.jpg"));
		// hand written text with non-uniform stained background
		threshold(UtilIO.pathExample("segment/stained_handwriting.jpg"));
	}
}