Skip to content

Implementation of poly2mask from matlab #56

@VPetukhov

Description

@VPetukhov

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions