use of boofcv.gui.ListDisplayPanel in project BoofCV by lessthanoptimal.
the class ExampleWatershedWithSeeds method main.
public static void main(String[] args) {
BufferedImage image = UtilImageIO.loadImage(UtilIO.pathExample("particles01.jpg"));
GrayU8 input = ConvertBufferedImage.convertFromSingle(image, null, GrayU8.class);
// declare working data
GrayU8 binary = new GrayU8(input.width, input.height);
GrayS32 label = new GrayS32(input.width, input.height);
// Try using the mean pixel value to create a binary image then erode it to separate the particles from
// each other
double mean = ImageStatistics.mean(input);
ThresholdImageOps.threshold(input, binary, (int) mean, true);
GrayU8 filtered = BinaryImageOps.erode8(binary, 2, null);
int numRegions = BinaryImageOps.contour(filtered, ConnectRule.EIGHT, label).size() + 1;
// +1 to regions because contour only counts blobs and not the background
// The labeled image can be used as is. A precondition for seeded watershed is that all seeds have an
// ID > 0. Luckily, a value of 0 was used for background pixels in the contour algorithm.
WatershedVincentSoille1991 watershed = FactorySegmentationAlg.watershed(ConnectRule.FOUR);
watershed.process(input, label);
GrayS32 output = watershed.getOutput();
BufferedImage outLabeled = VisualizeBinaryData.renderLabeledBG(label, numRegions, null);
VisualizeRegions.watersheds(output, image, 1);
// Removing the watersheds and update the region count
// NOTE: watershed.getTotalRegions() does not return correct results if seeds are used!
watershed.removeWatersheds();
numRegions -= 1;
BufferedImage outRegions = VisualizeRegions.regions(output, numRegions, null);
ListDisplayPanel gui = new ListDisplayPanel();
gui.addImage(image, "Watersheds");
gui.addImage(outRegions, "Regions");
gui.addImage(outLabeled, "Seeds");
ShowImages.showWindow(gui, "Watershed", true);
// Additional processing would be needed for this example to be really useful.
// The watersheds can be used to characterize the background while the seed binary image the particles
// From this the particles could be more accurately classified by assigning each pixel one of the two
// just mentioned groups based distance
}
use of boofcv.gui.ListDisplayPanel in project BoofCV by lessthanoptimal.
the class ExampleFourierTransform method applyBoxFilter.
/**
* Demonstration of how to apply a box filter in the frequency domain and compares the results
* to a box filter which has been applied in the spatial domain
*/
public static void applyBoxFilter(GrayF32 input) {
// declare storage
GrayF32 boxImage = new GrayF32(input.width, input.height);
InterleavedF32 boxTransform = new InterleavedF32(input.width, input.height, 2);
InterleavedF32 transform = new InterleavedF32(input.width, input.height, 2);
GrayF32 blurredImage = new GrayF32(input.width, input.height);
GrayF32 spatialBlur = new GrayF32(input.width, input.height);
DiscreteFourierTransform<GrayF32, InterleavedF32> dft = DiscreteFourierTransformOps.createTransformF32();
// Make the image scaled from 0 to 1 to reduce overflow issues
PixelMath.divide(input, 255.0f, input);
// compute the Fourier Transform
dft.forward(input, transform);
// the image edges
for (int y = 0; y < 15; y++) {
int yy = y - 7 < 0 ? boxImage.height + (y - 7) : y - 7;
for (int x = 0; x < 15; x++) {
int xx = x - 7 < 0 ? boxImage.width + (x - 7) : x - 7;
// Set the value such that it doesn't change the image intensity
boxImage.set(xx, yy, 1.0f / (15 * 15));
}
}
// compute the DFT for the box filter
dft.forward(boxImage, boxTransform);
// Visualize the Fourier Transform for the input image and the box filter
displayTransform(transform, "Input Image");
displayTransform(boxTransform, "Box Filter");
// apply the filter. convolution in spacial domain is the same as multiplication in the frequency domain
DiscreteFourierTransformOps.multiplyComplex(transform, boxTransform, transform);
// convert the image back and display the results
dft.inverse(transform, blurredImage);
// undo change of scale
PixelMath.multiply(blurredImage, 255.0f, blurredImage);
PixelMath.multiply(input, 255.0f, input);
// For sake of comparison, let's compute the box blur filter in the spatial domain
// NOTE: The image border will be different since the frequency domain wraps around and this implementation
// of the spacial domain adapts the kernel size
BlurImageOps.mean(input, spatialBlur, 7, null);
// Convert to BufferedImage for output
BufferedImage originOut = ConvertBufferedImage.convertTo(input, null);
BufferedImage spacialOut = ConvertBufferedImage.convertTo(spatialBlur, null);
BufferedImage blurredOut = ConvertBufferedImage.convertTo(blurredImage, null);
ListDisplayPanel listPanel = new ListDisplayPanel();
listPanel.addImage(originOut, "Original Image");
listPanel.addImage(spacialOut, "Spacial Domain Box");
listPanel.addImage(blurredOut, "Frequency Domain Box");
ShowImages.showWindow(listPanel, "Box Blur in Spacial and Frequency Domain of Input Image");
}
use of boofcv.gui.ListDisplayPanel in project BoofCV by lessthanoptimal.
the class ExampleImageConvert method convert.
void convert() {
// Converting between BoofCV image types is easy with ConvertImage. ConvertImage copies
// the value of a pixel in one image into another image. When doing so you need to take
// in account the storage capabilities of these different class types.
// Going from an unsigned 8-bit image to unsigned 16-bit image is no problem
GrayU16 imageU16 = new GrayU16(gray.width, gray.height);
ConvertImage.convert(gray, imageU16);
// You can convert back into the 8-bit image from the 16-bit image with no problem
// in this situation because imageU16 does not use the full range of 16-bit values
ConvertImage.convert(imageU16, gray);
// Here is an example where you over flow the image after converting
// There won't be an exception or any error messages but the output image will be corrupted
GrayU8 imageBad = new GrayU8(derivX.width, derivX.height);
ConvertImage.convert(derivX, imageBad);
// One way to get around this problem rescale and adjust the pixel values so that they
// will be within a valid range.
GrayS16 scaledAbs = new GrayS16(derivX.width, derivX.height);
GPixelMath.abs(derivX, scaledAbs);
GPixelMath.multiply(scaledAbs, 255.0 / ImageStatistics.max(scaledAbs), scaledAbs);
// If you just want to see the values of a 16-bit image there are built in utility functions
// for visualizing their values too
BufferedImage colorX = VisualizeImageData.colorizeSign(derivX, null, -1);
// Let's see what all the bad image looks like
// ConvertBufferedImage is similar to ImageConvert in that it does a direct coversion with out
// adjusting the pixel's value
BufferedImage outBad = new BufferedImage(imageBad.width, imageBad.height, BufferedImage.TYPE_INT_RGB);
BufferedImage outScaled = new BufferedImage(imageBad.width, imageBad.height, BufferedImage.TYPE_INT_RGB);
ListDisplayPanel panel = new ListDisplayPanel();
panel.addImage(ConvertBufferedImage.convertTo(scaledAbs, outScaled), "Scaled");
panel.addImage(colorX, "Visualized");
panel.addImage(ConvertBufferedImage.convertTo(imageBad, outBad), "Bad");
ShowImages.showWindow(panel, "Image Convert", true);
}
use of boofcv.gui.ListDisplayPanel in project BoofCV by lessthanoptimal.
the class ExampleImageDerivative method main.
public static void main(String[] args) {
BufferedImage input = UtilImageIO.loadImage(UtilIO.pathExample("simple_objects.jpg"));
// We will use floating point images here, but GrayU8 with GrayS16 for derivatives also works
GrayF32 grey = new GrayF32(input.getWidth(), input.getHeight());
ConvertBufferedImage.convertFrom(input, grey);
// First order derivative, also known as the gradient
GrayF32 derivX = new GrayF32(grey.width, grey.height);
GrayF32 derivY = new GrayF32(grey.width, grey.height);
GImageDerivativeOps.gradient(DerivativeType.SOBEL, grey, derivX, derivY, BorderType.EXTENDED);
// Second order derivative, also known as the Hessian
GrayF32 derivXX = new GrayF32(grey.width, grey.height);
GrayF32 derivXY = new GrayF32(grey.width, grey.height);
GrayF32 derivYY = new GrayF32(grey.width, grey.height);
GImageDerivativeOps.hessian(DerivativeType.SOBEL, derivX, derivY, derivXX, derivXY, derivYY, BorderType.EXTENDED);
// There's also a built in function for computing arbitrary derivatives
AnyImageDerivative<GrayF32, GrayF32> derivative = GImageDerivativeOps.createAnyDerivatives(DerivativeType.SOBEL, GrayF32.class, GrayF32.class);
// the boolean sequence indicates if its an X or Y derivative
derivative.setInput(grey);
GrayF32 derivXYX = derivative.getDerivative(true, false, true);
// Visualize the results
ListDisplayPanel gui = new ListDisplayPanel();
gui.addImage(ConvertBufferedImage.convertTo(grey, null), "Input Grey");
gui.addImage(VisualizeImageData.colorizeSign(derivX, null, -1), "Sobel X");
gui.addImage(VisualizeImageData.colorizeSign(derivY, null, -1), "Sobel Y");
// Use colors to show X and Y derivatives in one image. Looks pretty.
gui.addImage(VisualizeImageData.colorizeGradient(derivX, derivY, -1), "Sobel X and Y");
gui.addImage(VisualizeImageData.colorizeSign(derivXX, null, -1), "Sobel XX");
gui.addImage(VisualizeImageData.colorizeSign(derivXY, null, -1), "Sobel XY");
gui.addImage(VisualizeImageData.colorizeSign(derivYY, null, -1), "Sobel YY");
gui.addImage(VisualizeImageData.colorizeSign(derivXYX, null, -1), "Sobel XYX");
ShowImages.showWindow(gui, "Image Derivatives", true);
}
use of boofcv.gui.ListDisplayPanel in project BoofCV by lessthanoptimal.
the class CommonFitPolygonChecks method renderPolygons.
public void renderPolygons(List<Polygon2D_F64> polygons, Class imageType) {
BufferedImage work = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = work.createGraphics();
g2.setColor(Color.WHITE);
g2.fillRect(0, 0, width, height);
g2.setColor(Color.BLACK);
distorted.clear();
for (int i = 0; i < polygons.size(); i++) {
Polygon2D_F64 orig = polygons.get(i);
int[] x = new int[orig.size()];
int[] y = new int[orig.size()];
for (int j = 0; j < orig.size(); j++) {
x[j] = (int) orig.get(j).x;
y[j] = (int) orig.get(j).y;
}
g2.fillPolygon(x, y, orig.size());
distorted.add(orig);
}
orig = null;
image = GeneralizedImageOps.createSingleBand(imageType, width, height);
ConvertBufferedImage.convertFrom(work, image, true);
if (showRendered) {
ListDisplayPanel panel = new ListDisplayPanel();
panel.addImage(work, "Work");
panel.addImage(image, "Image");
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Aggregations