-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #434 from WilhelmusLab/433-add-notebook-with-tilin…
…g-illustrations docs: add nb for image tiling workflow
- Loading branch information
Showing
2 changed files
with
366 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,286 @@ | ||
{ | ||
"cells": [ | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"# Tiling Utilities" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"This notebook contains a demo of the tiling utilities included in `IceFloeTracker.jl`. In particular, the following workflows are illustrated:\n", | ||
"\n", | ||
"- Getting tiling with tiles of a given size\n", | ||
"- Getting the optimal tile size given an initial tile side length\n", | ||
"\n", | ||
"Run the cell below to set up the computation environment." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"HOME = \"../..\" # path to the root of the project two levels up\n", | ||
"\n", | ||
"# Activate the environment\n", | ||
"using Pkg\n", | ||
"Pkg.activate(HOME)\n", | ||
"Pkg.precompile()\n", | ||
"\n", | ||
"using IceFloeTracker: get_tiles, get_tile_dims, load\n", | ||
"using ColorTypes: RGBA" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"#### Load the image" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"imgpath = \"test/test_inputs/NE_Greenland_truecolor.2020162.aqua.250m.tiff\"\n", | ||
"img = load(joinpath(HOME,imgpath))" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"#### Estimate tile size\n", | ||
"\n", | ||
"Say we want to split the image into roughly 8x8 tiles." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"\n", | ||
"prelim_sizes = size(img) .÷ 8" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"#### Choosing tile size and building tilings\n", | ||
"\n", | ||
"The `get_tiles` function builds a tiling given an image (array) and a tile side length.\n", | ||
"\n" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"# Let's view the documentation for the function\n", | ||
"@info @doc get_tiles" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"tiles = get_tiles(img, prelim_sizes[1] + 1) # deliberately using a size that is too large" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"# Top left tile dimensions\n", | ||
"get_tile_dims(tiles[1])" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"Note that the bottom right tile has been extended to cover the rest of the image as a uniform tiling of side length `prelim_sizes[1] + 1` fails to cover the full image." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"# View the first tile\n", | ||
"img[tiles[1]...]" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"Further, note that the tiles on the right and bottom edges are slightly bigger." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"# Bottom right tile dimensions\n", | ||
"get_tile_dims(tiles[end])" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"### View the full tiling" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"function build_tiling_illustration(img, side_length)\n", | ||
"\n", | ||
" # Create new canvas to draw on\n", | ||
" newimg = similar(img, RGBA{Float64})\n", | ||
"\n", | ||
" # Apply transparency to the tiles\n", | ||
" for tile_coords in get_tiles(img, side_length)\n", | ||
" tile = @view img[tile_coords...]\n", | ||
" alpha = rand(0.5:0.05:1)\n", | ||
" transparent_tile = map(c -> RGBA(c.r, c.g, c.b, alpha), tile)\n", | ||
" newimg[tile_coords...] .= transparent_tile\n", | ||
" end\n", | ||
"\n", | ||
" # View the image\n", | ||
" newimg\n", | ||
"end\n", | ||
"\n", | ||
"build_tiling_illustration(img, prelim_sizes[1] + 1)\n" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"### Optimal tile side length\n", | ||
"\n", | ||
"Perhaps there is a fitter tiling that is close to the originally desired tiling. We can use the `get_optimal_tile_size` function to determine whether this is possible." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"using IceFloeTracker: get_optimal_tile_size\n", | ||
"\n", | ||
"@info @doc get_optimal_tile_size" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"best_side_length = get_optimal_tile_size(prelim_sizes[1] + 1, size(img))" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"As expected, a tile size of 1016 is not optimal for this image. The function `get_optimal_tile_size` suggests a fitter tiling is possible using tiles of 1015 pixels in side length for this image." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"build_tiling_illustration(img, best_side_length)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"# Area of corner tile with optimal side length\n", | ||
"get_tile_dims(get_tiles(img, best_side_length)[end]) |> prod" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"Note that the area of the corner tile for the suboptimal tiling is larger." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"get_tile_dims(get_tiles(img, prelim_sizes[1] + 1)[end]) |> prod" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"The proportion of pixels missed by a uniform tiling can be computed with `get_area_missed`." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"using IceFloeTracker: get_area_missed\n", | ||
"areamissed_optimal = get_area_missed(best_side_length, size(img))\n", | ||
"@show areamissed_optimal\n", | ||
"@assert get_area_missed(prelim_sizes[1] + 1, size(img)) > get_area_missed(best_side_length, size(img))" | ||
] | ||
} | ||
], | ||
"metadata": { | ||
"kernelspec": { | ||
"display_name": "Julia 1.9.3", | ||
"language": "julia", | ||
"name": "julia-1.9" | ||
}, | ||
"language_info": { | ||
"file_extension": ".jl", | ||
"mimetype": "application/julia", | ||
"name": "julia" | ||
} | ||
}, | ||
"nbformat": 4, | ||
"nbformat_minor": 2 | ||
} |
Oops, something went wrong.