Skip to content

Commit 0c963dc

Browse files
Add max min filter demo (#190)
Co-authored-by: Johnny Chen <[email protected]>
1 parent f0f6c2f commit 0c963dc

File tree

2 files changed

+81
-0
lines changed

2 files changed

+81
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
*.jl.cov
22
*.jl.*.cov
33
*.jl.mem
4+
.vscode
45
docs/build
56
docs/site
67
docs/Manifest.toml

docs/demos/filters/min_max_filter.jl

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# ---
2+
# title: Max min filters
3+
# cover: assets/max_min.gif
4+
# author: Deeptendu Santra
5+
# date: 2020-10-08
6+
# ---
7+
8+
# In this tutorial we see how can we can effectively use max and min filter to distinguish
9+
# between smooth and texture edges in grayscale images.
10+
11+
# We will use the [`mapwindow`](@ref) function in `ImageFiltering.jl` which provides a general
12+
# functionality to apply any function to the window around each pixel.
13+
14+
using ImageCore, ImageShow, ImageFiltering
15+
using TestImages
16+
17+
img = Gray.(testimage("house");) # Original Image
18+
19+
# We can use the `minimum` function to compute the minimum of the grayscale values in the given
20+
# matrix or array. For example:
21+
minimum([Gray(0.7),Gray(0.5),Gray(0.0)]) # Should return Gray(0.0) i.e black.
22+
#
23+
filter_size = (15, 15)
24+
## Using the `mapwindow` function, we create an image of the local minimum.
25+
## `mapwindow` maps the given function over a moving window of given size.
26+
img_min = mapwindow(minimum, img, filter_size)
27+
## Similarly for maximum
28+
img_max = mapwindow(maximum, img, filter_size)
29+
## The max(min) filter
30+
img_max_min = mapwindow(maximum, img_min, filter_size)
31+
## The min(max) filter
32+
img_min_max = mapwindow(minimum, img_max, filter_size)
33+
mosaicview(img_min, img_max, img_max_min, img_min_max; nrow=1)
34+
35+
# Now that we are done with the basic filtered images, we proceed to the next part
36+
# which is edge detection using these filters.
37+
38+
# For edge detection, we need to define thresholds for our image. The threshold is an important tool
39+
# to binarize a grayscale image. The threshold value for a given pixel practically
40+
# decides if the pixel visible or not in the output image. However, appyling a global threshold might not consider the
41+
# variation of colors/brightness within the image. Thus we consider an adaptive type theresholding method
42+
# here using max/min results.
43+
44+
# The max(min) and min(max) filter effectively follows the smooth edges of the image. Therefore,
45+
# their average also follows the smooth parts of the image. If we use this image as a threshold for the original
46+
# image, the smooth parts of the original image will get filtered out, leaving only the texture and/or noise behind.
47+
# So we can use the average of `img_max_min` and `img_min_max` as the texture threshold.
48+
49+
# The average of min and max filters also gives us the smooth edges, but it also includes the noise in the image.
50+
# So using average of `img_min` and `img_max` as a threshold will yeild only texture.
51+
52+
img_texture_noise_threshold = (img_max_min + img_max_min) ./ 2
53+
img_texture_threshold = (img_max + img_min) ./ 2
54+
mosaicview(img_texture_noise_threshold, img_texture_threshold; nrow=1)
55+
#
56+
## The Dynamic Gist is obtained by subtracting the img_texture_threshold from the original image.
57+
## The filtered image gives us the texture of the image.
58+
img_dynamic_gist = img - img_texture_threshold
59+
## The Texture Gist is obtained by subtracting img_texture_noise_threshold from the original image.
60+
## The filtered image gives us the texture along with the noise of the image.
61+
img_texture_gist = img - img_texture_noise_threshold
62+
mosaicview(img_dynamic_gist, img_texture_gist; nrow=1)
63+
#
64+
## We extract out the smooth/ramp parts of the image.
65+
## The darker section of the image consist of the ramp edges. The brighter pixels are mostly noise.
66+
ramp = img_dynamic_gist - img_texture_gist
67+
## Filtered-out edges
68+
edge = img_max - img_min
69+
## Smoothed-out version of edge
70+
edge_smoothed = img_min_max - img_max_min
71+
mosaicview(img, ramp, edge, edge_smoothed; nrow=2)
72+
73+
# # References
74+
75+
# Verbeek, P. W., Vrooman, H. A., & Van Vliet, L. J. (1988). [Low-level image processing by max-min filters](https://core.ac.uk/download/pdf/194053536.pdf). Signal Processing, 15(3), 249-258.
76+
77+
## save covers #src
78+
using ImageMagick #src
79+
mkpath("assets") #src
80+
ImageMagick.save("assets/max_min.gif", cat(img, edge, edge_smoothed, map(clamp01nan, ramp);dims=3);fps=1) #src

0 commit comments

Comments
 (0)