Skip to content

new demo: block-by-block visualization as GIF #191

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: source
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ ImageMorphology = "0.2"
ImageSegmentation = "1"
ImageShow = "0"
ImageTransformations = "0"
Images = "0.23"
Images = "0.24"
IndirectArrays = "0"
MappedArrays = "0"
MosaicViews = "0"
Expand Down
64 changes: 64 additions & 0 deletions docs/examples/visualization/block_visualization.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# ---
# title: Block-by-Block Visualization
# description: This demo shows you how to create a block-by-block image visualization.
# cover: assets/block_visualization.gif
# author: Johnny Chen
# date: 2021-05-05
# ---

using Images
using PaddedViews, OffsetArrays
using TestImages
using ImageBinarization

# !!! note
# It is recommended to read the demo [Layer Compositing](@ref Layer-Compositing) first to get an idea
# of how [OffsetArrays.jl](https://github.com/JuliaArrays/OffsetArrays.jl) and
# [PaddedViews.jl](https://github.com/JuliaArrays/PaddedViews.jl) can be used to simplify the
# canvas/axes organization.

img = imresize(testimage("lighthouse"), ratio=0.5)
img₀₁ = binarize(img, AdaptiveThreshold())

# As you may have seen in other demos, the simplest way to compare multiple images is to use `mosaic`:

mosaic(img, img₀₁; nrow=1)

# In this demo, we will use `Images.gif` to create something different by adding a "time" axis. As
# an example, we use `TiledIteration` to move our focus on a block/patch/tile level.

using TiledIteration
tile_indices = TileIterator(axes(img), (32, 32))[:]
tiles = [img[R...] for R in tile_indices]
## visualize the tiles at fps rate 5, i.e., 5 frames per second.
Images.gif(tiles; fps=5)

# This is not very meaningful as it simply stacks all tiles together, so next we'll add
# back the axes information for each block. We also use the original image as the
# background.

function create_frames(img, background, tile_indices; rf=0.8, rb=1-rf)
map(tile_indices) do R
## add back axes information to given blcok
block = OffsetArray(img[R...], OffsetArrays.Origin(first.(R)))
canvas, block = paddedviews(zero(eltype(background)), background, block)
frame = clamp01!(@. rb*canvas .+ rf*block)
end
Comment on lines +41 to +46
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are extra memory allocations here so it's not very efficient. The main reason I didn't optimize it is that the current ImageShow.gif is a little bit broken when dealing with non-Array array types.

end

frames = create_frames(img, img, tile_indices)
Images.gif(frames; fps=5)

# Now, instead of using `mosaic`, we use this to compare our images.

frames = create_frames(img₀₁, img, tile_indices; rb=0.4)
Images.gif(frames; fps=5)

# This may not be the best way to visually compare these two images, but you get the
# idea of how to add back axes information to each block, and visualize it as an animated
# GIF.

# make cover image #src
tile_indices = TileIterator(axes(img), (48, 48))[:] #src
frames = create_frames(img₀₁, img, tile_indices; rb=0.4) #src
save("assets/block_visualization.gif", Images.gif(frames); fps=2) #src