feat: Iterative rectangle refinement

This commit is contained in:
Leni Aniva 2025-04-11 15:53:50 -07:00
parent e468e60fc5
commit 6d2df0e84f
Signed by: aniva
GPG Key ID: 4D9B1C8D10EA4C50
4 changed files with 49 additions and 21 deletions

View File

@ -2,7 +2,7 @@
julia_version = "1.11.4" julia_version = "1.11.4"
manifest_format = "2.0" manifest_format = "2.0"
project_hash = "0a18a0873213e0e8660a5eb202a1fa9f1621a652" project_hash = "ec502e8d73a739a6239b751344af945fa59e7806"
[[deps.AbstractFFTs]] [[deps.AbstractFFTs]]
deps = ["LinearAlgebra"] deps = ["LinearAlgebra"]

View File

@ -7,10 +7,12 @@ version = "0.1.0"
FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549"
Images = "916415d5-f1e6-5110-898d-aaa5f9f070e0" Images = "916415d5-f1e6-5110-898d-aaa5f9f070e0"
Luxor = "ae8d54c2-7ccd-5906-9d76-62fc9837b5bc" Luxor = "ae8d54c2-7ccd-5906-9d76-62fc9837b5bc"
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
VideoIO = "d6d074c3-1acf-5d4c-9a43-ef38773959a2" VideoIO = "d6d074c3-1acf-5d4c-9a43-ef38773959a2"
[compat] [compat]
FileIO = "1.17.0" FileIO = "1.17.0"
Images = "0.26.2" Images = "0.26.2"
Luxor = "4.2.0" Luxor = "4.2.0"
Statistics = "1.11.1"
VideoIO = "1.1.1" VideoIO = "1.1.1"

View File

@ -3,6 +3,6 @@ using Images
""" """
Converts image to grayscale Converts image to grayscale
""" """
function greyscale(c::Images.RGB)::UInt8 function greyscale(c::Images.RGB)::Real
return c.r return Real(c.r)
end end

View File

@ -1,38 +1,64 @@
using Base
using Statistics, Images
# Time-dependent packing # Time-dependent packing
struct Rect @kwdef struct Rect
pos::Tuple{UInt,UInt} pos::Tuple{Int,Int}
size::Tuple{UInt,UInt} size::Tuple{Int,Int}
color::Real color::Real
end end
function area(r::Rect)::Int
return r.size[1] * r.size[2]
end
function aspect_ratio(r::Rect)::Real
return r.size[1] / r.size[2]
end
""" """
divide_image(img::BitMatrix, size_min::UInt=16, size_max::UInt=256) divide_image(img::BitMatrix, size_min::Int=16, size_max::Int=256)
Divides an image into rectangles of the same colour. The rectangles are not Divides an image into rectangles of the same colour. The rectangles are not
allowed to have extreme aspect ratios. There is a minimal size of each retangle. allowed to have extreme aspect ratios. There is a minimal size of each retangle.
""" """
function divide_image(img::Matrix{}, size_min::UInt=16, size_max::UInt=256)::Array{Rect} function divide_image(img::Matrix{}, size_min::Int=16, size_max::Int=256, threshold_aspect::Real=3.0, threshold_std::Real=0.4)::Array{Rect}
remainder = Rect[Rect(pos=(1,1), size=size(img), color=mean(img))]
result = Rect[] result = Rect[]
# Remaining area
area = sizeof(img)
# Loop until the entire field is filled # Loop until the entire field is filled
while area > 0 while length(remainder) > 0
pos = (9, 9) section = pop!(remainder)
size = (threshold, threshold)
region = img.size width = size_min
height = size_min
# Try to expand this rectangle to the maximum size # Try to expand this rectangle to the maximum size
while size[1] < region[1] || size[2] < region[2] while width < section.size[1] || height < section.size[2]
subimg = img[section.pos[1]:section.pos[1]+width-1, section.pos[2]:section.pos[2]+height-1]
if std(subimg) >= threshold_std
break
end
colour = mean(subimg)
ar = width / height
if width < section.size[1] && ar < threshold_aspect
width += 1
elseif height < section.size[1]
height += 1
else
break
end
end end
subimg = img[section.pos[1]:section.pos[1]+width-1, section.pos[2]:section.pos[2]+height-1]
rect = Rect(
pos=section.pos,
size=(width, height),
color=mean(subimg),
)
push!(result, rect)
color = 0.5 # FIXME: Add next iteration region
push!(result, Rect(pos, size, color))
# Update the boundary markers for the next iteration
area -= size[1] * size[2]
end end
return result return result