Morphological operations, part 2¶
In this demonstration, we'll look at morphological operations such as filling, poking, and border cleaning.
Let's start by connecting the necessary libraries.
Pkg.add(["ImageBinarization", "Noise", "ImageDraw", "TestImages", "ImageMorphology"])
Pkg.add("ImageBinarization")
using Images, Noise, ImageMorphology
using ImageBinarization
using ImageDraw
using TestImages
Let's load an image and perform its threshold processing.
img_src = testimage("morphology_test_512")
img_input = binarize(Gray.(img_src), UnimodalRosin()) .> 0.5
We will use this image in the further work, assigning it the grey shades format, because the operations below are applied to images in Gray format.
Gray.(img_input)
Selecting borders¶
The convexhull function outputs the outer most coverage-like boundary of the image and returns the vertices of the boundary object as an array CartesianIndex.
cordinates = convexhull(img_input)
img_convex = RGB.(copy(img_input))
push!(cordinates, cordinates[1])
draw!(img_convex, Path(cordinates), RGB(1))
img_convex
Image filling¶
The image fill operation finds related image components and uses them to produce the resulting image. After the fill function is executed, this image falls within the range of the specified interval.
img_noise = salt_pepper(img_input, 0.5)
fill_image_1 = imfill(img_noise, (0.1, 1))
fill_image_2 = imfill(img_noise, (0.1, 10)) # this configuration gets us best results
fill_image_3 = imfill(img_noise, (1, 10))
fill_image_4 = imfill(img_noise, (5, 20)) # objects of smaller sizes gets left out
Gray.([img_noise fill_image_1 fill_image_2 fill_image_3 fill_image_4])
Image thinning¶
The thinning operation applies a Go algorithm that determines which pixels to leave behind.
img_thinning = thinning(img_input, algo = GuoAlgo());
Gray.([img_input img_thinning])
Border cleaning¶
You can use the Clearborder method to clear objects associated with an image border.
cleared_img_1 = clearborder(img_input, 20); # 20 is the width of border that's examined
cleared_img_2 = clearborder(img_input, 30); # notice how it remove the inner circle even if it's outside its range
cleared_img_3 = clearborder(img_input, 30, 1);
The default colour to remove is 0, which means to remove RGB(0), but now, since it is 1, it clears the whole image because of the fill algorithm.
Gray.([img_input cleared_img_1 cleared_img_2 cleared_img_3])
Conclusion¶
In this example, we have broken down some useful morphological operations that can be applied to images.