Skip to content

Commit

Permalink
binary Search in find_weight_scale
Browse files Browse the repository at this point in the history
  • Loading branch information
guoyongzhi authored and guo-yong-zhi committed Apr 8, 2021
1 parent 00189cc commit d24ea2a
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 11 deletions.
2 changes: 1 addition & 1 deletion examples/animation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ df = CSV.File(pkgdir(WordCloud)*"/res/guxiang_frequency.txt", header=false)|> Da
words = df[!, "Column2"]
weights = df[!, "Column3"]

wc = wordcloud(words, weights, density=0.7)
wc = wordcloud(words, weights, density=0.65)
gifdirectory = "guxiang_animation"
#eval# try rm("guxiang_animation", force=true, recursive=true) catch end
generate_animation!(wc, 100, outputdir=gifdirectory)
Expand Down
2 changes: 1 addition & 1 deletion examples/benchmark.jl
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ for (i,wc) in enumerate(wcs)
println("\n", i-1, "==== ", j, "/", length(ts), " ", nameof(t))
placement!(wc)
@time e = @elapsed generate!(wc, trainer=t, retry=1)
push!(es[i],nameof(t)=>e)
push!(es[i], string(nameof(t)) * (getstate(wc)==:generate! ? "" : "")=>e)
end
end
println("SUMMARY")
Expand Down
4 changes: 2 additions & 2 deletions examples/highdensity.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ using WordCloud
#md# mask = shape(box, 400, 300, 10),
#md# colors = :Dark2_3,
#md# angles = (0, 90),
#md# density = 0.75) |> generate!
#md# density = 0.7) |> generate!
#md# paint(wc, "highdensity.png")
#md# ```
#md# But you may find that doesn't work. That is because there should be at least 1 pixel gap between two words, which is controlled by the `border` parameter (default 1) in `wordcloud`. While, when the picture is small, 1 pixel is expensive. So, that can be done as follows:
Expand All @@ -15,7 +15,7 @@ wc = wordcloud(
mask = shape(box, 400*2, 300*2, 10*2),
colors = :Dark2_3,
angles = (0, 90),
density = 0.75) |> generate!
density = 0.7) |> generate!
paint(wc, "highdensity.png", ratio=0.5)
#md#
println("results are saved to highdensity.png")
Expand Down
42 changes: 35 additions & 7 deletions src/strategy.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ end
function feelingoccupied(imgs, border=0, bgvalue=imgs[1][1])
bs = boxoccupied.(imgs, border)
os = occupied.(imgs, bgvalue)
s = (0.8 * sum(bs) .+ 0.2 * sum(os)) / 0.93 #兼顾饱满字体(华文琥珀)和清瘦字体(仿宋)
s = (0.8 * sum(bs) + 0.2 * sum(os)) / 0.93 #兼顾饱满字体(华文琥珀)和清瘦字体(仿宋)
# sum(os) ≈ 2/3 sum(bs), 故除以0.93还原到sum(bs)的大小
th = 10quantile(bs, 0.1)
bigind = findall(x->x>th, bs)
Expand Down Expand Up @@ -53,7 +53,7 @@ function prepareword(word, fontsize, color, angle; backgroundcolor=(0,0,0,0), fo
angle=angle, border=border, font=font, type=:both)
end

wordmask(img, bgcolor, border) = dilate(img.!=img[1], border)
wordmask(img, bgcolor, border) = dilate(img.!=img[1], border)
#use `img[1]` instead of `convert(eltype(img), parsecolor(bgcolor))`
#https://github.com/JuliaGraphics/Luxor.jl/issues/107

Expand All @@ -75,12 +75,17 @@ function find_weight_scale!(wc::WC; initialscale=0, density=0.3, maxiter=5, erro
ground_size = wc.params[:groundoccupied]
words = wc.words
if initialscale <= 0
initialscale = (ground_size/length(words)/0.4*density) #初始值假设字符的字面框面积占正方格比率为0.4(低估了汉字)
initialscale = (ground_size/length(words)/0.45*density) #初始值假设字符的字面框面积占正方格比率为0.45(低估了汉字)
end
@assert sum(wc.weights.^2 .* length.(words)) / length(wc.weights) 1.0
target = density * ground_size
target_lower = (density - error) * ground_size
target_upper = (density + error) * ground_size
target = density * ground_size
best_tar_H = Inf
best_tar_L = -Inf
best_scale_H = Inf
best_scale_L = -Inf
step = 0
sc1 = initialscale
fonts = getfonts(wc, words)
Expand All @@ -89,24 +94,47 @@ function find_weight_scale!(wc::WC; initialscale=0, density=0.3, maxiter=5, erro
while true
step = step + 1
if step > maxiter
@warn "find_weight_scale reach maxiter. This may be caused by too small background image or too many words or too big `minfontsize`."
@warn "find_weight_scale reach maxiter. This may be caused by too small background or too many words or too big `minfontsize`."
break
end
# cal tg1
@assert sc1 < 50initialscale #防止全空白words的输入,计算出sc过大渲染字体耗尽内存
wc.params[:scale] = sc1
tg1 = textoccupied(words, getfontsizes(wc, words), fonts)
dens = tg1 / ground_size
println("scale=$(wc.params[:scale]), density=$dens\t", dens>density ? "" : "")
if tg1 > target
if best_tar_H > tg1
best_tar_H = tg1
best_scale_H = sc1
end
else
if best_tar_L <= tg1
best_tar_L = tg1
best_scale_L = sc1
end
end
# cal sc2
sc2 = scalestep(sc0, tg0, sc1, tg1, target)
# @show sc0, tg0, sc1, tg1, sc2
if !(best_scale_L < sc2 < best_scale_H)
if isfinite(best_tar_H + best_tar_L)
sc2_ = ((best_scale_H^2 + best_scale_L^2)/2.)
println("bisection takes effect: scale $sc2 -> $sc2_")
sc2 = sc2_
# @show best_scale_L best_scale_H
else
Base.error("scalestep failed!")
end
end
# next iter init
tg0 = tg1
sc0 = sc1
sc1 = sc2
@assert sc1 < 50initialscale #防止全空白words的输入,计算出sc过大渲染字体耗尽内存
if target_lower <= tg1 <= target_upper
break
end

end
# @show textoccupied(words, weights, sc, radius=border)
wc.params[:scale] = sc1
return sc1
end
Expand Down

2 comments on commit d24ea2a

@guo-yong-zhi
Copy link
Owner

Choose a reason for hiding this comment

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

@JuliaRegistrator register()

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

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

Registration pull request created: JuliaRegistries/General/33850

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v0.6.5 -m "<description of version>" d24ea2a263f48d7a2ae34f5d7cffc08c4c2ae2c6
git push origin v0.6.5

Please sign in to comment.