Reputation: 566
I'm working with Julia. I've the following result from a road's binary image after Thinning (skeleton) After thinning, I used Harris corner detection, which gets me red dots. To get line segments, I remove the red dots and each line is a line-segment with unique number. The problem is that some red points are too close. How can I make red dots white (i.e. not corner points) if the points are too close?
using Images
using LinearAlgebra
t = thinning(road_image)
detection_method = harris
corners = imcorner(t, Percentile(99.5); method=detection_method)
labels = label_components(corners)
new_labels = label_components(labels) #because some labels are cluster of points, so this makes them 1
all_nodes = component_centroids(new_labels)
centre_line_node = CartesianIndex.(map(i -> trunc.(Int, all_nodes[i]), 1:length(all_nodes)))
img_labels = RGB{N0f8}.(t)
img_labels[centre_line_node] .= RGB(1.0, 0.0, 0.0)
Upvotes: 0
Views: 79
Reputation: 6355
Although you didn't provide enough details about your code (even the full code) again, I managed to get the job done using my previous answer using a little bit of justification:
using Images, ImageBinarization
road_image = load("oxLCJ.png") # The raw image
gimg = Gray.(road_image)
bin = binarize(gimg, UnimodalRosin()) .> 0.5
thinned = thinning(bin)
function check_adjacent(
loc::CartesianIndex{2},
all_locs::Vector{CartesianIndex{2}}
)
conditions = [
loc - CartesianIndex(0,1) ∈ all_locs,
loc + CartesianIndex(0,1) ∈ all_locs,
loc - CartesianIndex(1,0) ∈ all_locs,
loc + CartesianIndex(1,0) ∈ all_locs,
loc - CartesianIndex(1,1) ∈ all_locs,
loc + CartesianIndex(1,1) ∈ all_locs,
loc - CartesianIndex(1,-1) ∈ all_locs,
loc + CartesianIndex(1,-1) ∈ all_locs
]
return sum(conditions)
end;
function find_the_contour_branches(img::BitMatrix)
img_matrix = convert(Array{Float64}, img)
not_black = findall(!=(0.0), img_matrix)
contours_branches = Vector{CartesianIndex{2}}()
for nb∈not_black
t = check_adjacent(nb, not_black)
(t==1 || t==3) && push!(contours_branches, nb)
end
return contours_branches
end;
function highlight_contours(img, contours; resize::Bool=false, scale::Union{Int64, Float64}=1)
img_matrix = convert(Array{RGB, 2}, img)
img_matrix[contours] .= RGB(1,0,0)
if resize
img_matrix = typeof(scale)==Int64 ? imresize(img_matrix, size(img).*scale) : imresize(img_matrix, ratio=scale)
end
return img_matrix
end;
contours = find_the_contour_branches(thinned)
highlight_contours(thinned, contours)
Gives me a result that if I zoom in, I see the following:
If you want details about the functions, see the previous answer I mentioned above (It's documented). Here, I just replaced contours
with contours_branches
and t==1 && push!(contours, nb)
with (t==1 || t==3) && push!(contours_branches, nb)
as far as I remember. But the idea is the same.
Update:
The code can get enhanced further. For example, I replaced the for
loop in the highlight_contours
function with img_matrix[contours] .= RGB(1,0,0)
. But other improvements are out of the interest of this answer.
Upvotes: 1