如何使用Julia实现图像骨架修剪?去除道路骨架中小支路
道路骨架短小支路修剪方案(Julia实现)
核心思路
借助已知的拐角(分支)点作为起点,通过**深度优先搜索(DFS)**遍历骨架分支,统计每个分支的像素长度,设定阈值过滤并移除短支路。
具体实现步骤
- 图像预处理:将骨架图像转为二值矩阵(道路像素标记为
true,背景为false),便于邻域遍历操作。 - 分支遍历与长度统计:
- 以每个拐角点为起点,遍历其8邻域内未被访问的道路像素。
- 沿分支方向逐步遍历,记录所有分支像素位置,直到遇到背景或另一个拐角点(主道路节点)。
- 统计分支的像素总数作为分支长度。
- 短支路移除:设定长度阈值(如根据图像尺度设为15像素),将长度低于阈值的分支像素置为背景值。
Julia 示例代码
using Images # 读取骨架图像并转为二值矩阵 skeleton_img = load("k9quG.png") skeleton = Gray.(skeleton_img) .> 0.5 # 二值化处理 # 已知的拐角点索引(替换为实际的CartesianIndex数组) corner_points = [CartesianIndex(120, 180), CartesianIndex(250, 320)] # 定义8邻域方向 directions = [CartesianIndex(-1,-1), CartesianIndex(-1,0), CartesianIndex(-1,1), CartesianIndex(0,-1), CartesianIndex(0,1), CartesianIndex(1,-1), CartesianIndex(1,0), CartesianIndex(1,1)] # 标记已访问像素 visited = falses(size(skeleton)) # 短支路长度阈值(根据实际场景调整) length_threshold = 15 # 遍历每个拐角点处理分支 for corner in corner_points visited[corner] = true for dir in directions neighbor = corner + dir # 检查邻域是否合法、为道路且未访问 if checkbounds(Bool, skeleton, neighbor) && skeleton[neighbor] && !visited[neighbor] branch = [neighbor] current = neighbor visited[current] = true is_short_branch = true # 遍历分支至终点 while true next_points = [] for d in directions n = current + d if checkbounds(Bool, skeleton, n) && skeleton[n] && !visited[n] push!(next_points, n) end end # 分支终点判断:无未访问邻域 或 遇到新分支点 if isempty(next_points) break elseif length(next_points) > 1 is_short_branch = false break end current = next_points[1] push!(branch, current) visited[current] = true end # 移除短支路 if is_short_branch && length(branch) < length_threshold for p in branch skeleton[p] = false end end end end end # 保存处理后的骨架图像 save("pruned_skeleton.png", Gray.(skeleton))
注意事项
- 长度阈值需根据图像分辨率调整:原始图像分辨率越高,阈值应对应增大。
- 若拐角点包含主道路转折点,可结合原始图像的道路宽度辅助区分主路与支路(主道路通常更宽)。
内容的提问来源于stack exchange,提问作者F612
相关产品推荐
相关产品推荐

