Implementation of poly2mask from matlab
Hi,
I was looking for implementation of a function, which would fill an image region based on the provided polygon. It exists in Matlab (poly2mask) and also was re-implemented in python (see the discussion).
The implementation is almost trivial (see below), and the function seems generally useful. Would you be interested in me making a PR?
function point_in_polygon(poly_xs::Vector{T}, poly_ys::Vector{T}, x::T, y::T) where T<: Real
n_verts = length(poly_xs)
j = n_verts
c = false
for i in 1:n_verts
if (((poly_ys[i] <= y) && (y < poly_ys[j])) || ((poly_ys[j] <= y) && (y < poly_ys[i]))) &&
(x < (poly_xs[j] - poly_xs[i]) * (y - poly_ys[i]) / (poly_ys[j] - poly_ys[i]) + poly_xs[i])
c = !c
end
j = i
end
return c
end
function draw_polygon!(mask::Matrix{T2}, poly_xs::Vector{T}, poly_ys::Vector{T}, value::T2) where T<: Integer where T2 <: Real
min_x, max_x = max(minimum(poly_xs), 1), min(maximum(poly_xs), size(mask, 2))
min_y, max_y = max(minimum(poly_ys), 1), min(maximum(poly_ys), size(mask, 1))
for y in min_y:max_y
for x in min_x:max_x
if point_in_polygon(poly_xs, poly_ys, x, y)
mask[y, x] = value
end
end
end
end
function polygons_to_mask(polygons::Array{Matrix{T}, 1} where T <: Real, max_x::Int, max_y::Int)
poly_mask = zeros(Int, max_y, max_x);
for (i,p) in enumerate(polygons)
draw_polygon!(poly_mask, round.(Int, p[:,1]), round.(Int, p[:,2]), i)
end
return poly_mask
end
It might be interesting. However, what was the inspiration for this code? If you looked at the Matlab implementation then you are license-contaminated, and we can't accept it.
Could be possibly added to ImageDraw.jl with a new field fill in Polygon
https://github.com/JuliaImages/ImageDraw.jl/blob/d0324f84e9730b633e441fe34fe926ca1fc713e7/src/paths.jl#L19-L22
I guess fill here is not ambiguous to Base.fill?
struct Polygon <: Drawable
vertices::Vector{Point}
fill::Bool
end
However, what was the inspiration for this code?
It was python scikit-image. Looks like they use a variation of the MIT license.
Could be possibly added to ImageDraw.jl with a new field fill in Polygon
If you think people would use it for other purposes.. Otherwise, changing an existing class for such tiny functionality seems like over-kill to me. Though I agree that having both draw!(img, polygon) and draw_polygon! is a bad style. Would it maybe be better to add fill_color::T where T<: Colorant as a keyword argument instead?
Adding an extra fill_color keyword to draw! sounds good to me.
Yes, scikit-image is not a problem with regards to licenses, and the plan you've come up with seems fine to me.
But maybe Union{Number,Colorant}, some people might want a Bool instead (if it's a mask).
Just realized that it does not exactly work, as the current draw! works only with Colorant, while working with a mask assumes it to be Integer or Bool. Maybe I'm missing something, but converting integers to Colorant and then back introduces a lot of hustle.
Generally, we require functions accepting AbstractArray{<:Colorant}, with AbstractArray{<:Real} treated as gray image.
The type annotations in your example codes seem to be quite too restrictive.