Skip to content

Commit

Permalink
downsample the image before clustering
Browse files Browse the repository at this point in the history
This commit also adds ImageBase dependency; a drop-in replacement
for ImageCore with a few handy operators.
  • Loading branch information
johnnychen94 committed Apr 28, 2022
1 parent fb22593 commit 14da941
Show file tree
Hide file tree
Showing 7 changed files with 24 additions and 11 deletions.
4 changes: 2 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@ authors = ["Adrian Hill"]
version = "2.3.1"

[deps]
ImageCore = "a09fc81d-aa75-5fe9-8630-4744c3626534"
ImageBase = "c817782e-172a-44cc-b673-b171935fbb9e"
IndirectArrays = "9b13fd28-a010-5f03-acff-a1bbcff69959"
OffsetArrays = "6fe1bfb0-de20-5000-8ca7-80f57d26f881"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
Requires = "ae029012-a4dd-5104-9daa-d747884805df"

[compat]
ImageBase = "0.1.3"
Clustering = "0.14"
ColorSchemes = "3"
ImageCore = "0.8.1, 0.9"
IndirectArrays = "0.5, 1.0"
OffsetArrays = "1"
Requires = "1"
Expand Down
6 changes: 3 additions & 3 deletions src/DitherPunk.jl
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
module DitherPunk

using ImageCore
using ImageCore: NumberLike, Pixel, GenericImage, GenericGrayImage, MappedArrays
using ImageCore.Colors: DifferenceMetric
using ImageBase
using ImageBase.ImageCore: NumberLike, Pixel, GenericImage, GenericGrayImage, MappedArrays
using ImageBase.ImageCore.Colors: DifferenceMetric
using Random
using IndirectArrays
using OffsetArrays
Expand Down
15 changes: 14 additions & 1 deletion src/clustering.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,26 @@ function get_colorscheme(
tol=Clustering._kmeans_default_tol,
)::Vector{Lab}
# Cluster in Lab color space
data = reshape(channelview(Lab.(img)), 3, :)

# Clustering on the downsampled image already generates good enough colormap estimation
# This significantly reduces the algorithmic complexity.
img = _restrict_to(img, ncolors*100)
data = convert(Array{Float32}, reshape(channelview(Lab.(img)), 3, :))
R = Clustering.kmeans(data, ncolors; maxiter=maxiter, tol=tol)

# Make color scheme out of cluster centers
return [Lab(c...) for c in eachcol(R.centers)]
end

function _restrict_to(img, n)
length(img) <= n && return img
out = restrict(img)
while length(out) > n
out = restrict(out)
end
return out
end

function _colordither(
::Type{T},
img,
Expand Down
2 changes: 1 addition & 1 deletion test/test_color.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using DitherPunk
using DitherPunk: ColorNotImplementedError
using IndirectArrays
using ImageCore
using ImageBase
using ReferenceTests
using TestImages

Expand Down
2 changes: 1 addition & 1 deletion test/test_fixed_color.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using DitherPunk
using ImageCore
using ImageBase
using ReferenceTests
using TestImages

Expand Down
4 changes: 2 additions & 2 deletions test/test_gradient.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ using DitherPunk
using DitherPunk: gradient_image
using ReferenceTests

using ImageCore
using ImageCore: GenericGrayImage
using ImageBase
using ImageBase.ImageCore: GenericGrayImage
using UnicodePlots

w = 200
Expand Down
2 changes: 1 addition & 1 deletion test/test_utils.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using DitherPunk
using DitherPunk: srgb2linear, clamp_limits
using ImageCore
using ImageBase

@test srgb2linear(true) == true
@test srgb2linear(false) == false
Expand Down

0 comments on commit 14da941

Please sign in to comment.