0
点赞
收藏
分享

微信扫一扫

检测二值骨架栅格图的断点以及断线方向、十、丁字路口点


文章目录

  • ​​应用背景​​
  • ​​代码​​
  • ​​结果​​
  • ​​进阶版​​
  • ​​获得断点后获取该断点所在线段的方向向量​​
  • ​​获得路口点​​
  • ​​稀疏化​​

应用背景

下面介绍一种方法,对骨架线的断点进行提取。
检测二值骨架栅格图的断点以及断线方向、十、丁字路口点_方向向量

代码

import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
from skimage import morphology
import os


def detect_breakpoints(img):
r, c = img.shape
new_image = np.zeros((r, c))
detection_operator = np.array([[1, 1, 1], [1, 1, 1], [1, 1, 1]])
break_points = []
for i in range(r-2):
for j in range(c-2):
if img[i+1, j+1] == 0:
new_image[i + 1, j + 1] = 0
else:
if np.sum(img[i:i + 3, j:j + 3] * detection_operator) == 2:
new_image[i+1, j+1] = 1
break_points.append([i+1, j+1])
else:
new_image[i+1, j+1] = 0
return np.uint8(new_image), break_points

结果

检测二值骨架栅格图的断点以及断线方向、十、丁字路口点_方向向量_02

进阶版

获得断点后获取该断点所在线段的方向向量

检测二值骨架栅格图的断点以及断线方向、十、丁字路口点_方向向量_03

def detectCenterDirection(img, centerPoint):
detection_operator = np.array([[1, 1, 1], [1, 1, 1], [1, 1, 1]])
x, y = centerPoint
dx, dy = x, y
whilestopSignal = False
count = 0

linePoints = []
linePoints.append((x, y))
while True:
forStopSiganl = False

for i in [-1, 0, 1]:
for j in [-1, 0, 1]:
start_center_x, start_center_y = x + i, y + j
# print(f'***********{linePoints}')
if (start_center_x, start_center_y) in linePoints:
# print(f'***********{linePoints}')
continue

subImg = img[start_center_x - 1: start_center_x + 2, start_center_y - 1: start_center_y + 2]
if np.sum(subImg * detection_operator) > 3:
dx, dy = start_center_x, start_center_y
linePoints.append((start_center_x, start_center_y))
whilestopSignal = True
forStopSiganl = True
break

if np.sum(subImg * detection_operator) == 3 and subImg[1, 1] == 1:

x, y = start_center_x, start_center_y
dx, dy = x, y
linePoints.append((start_center_x, start_center_y))
forStopSiganl = True
break

if forStopSiganl == True:
break

if whilestopSignal == True:
break

count += 1
if count > 8:
whilestopSignal = True

print(f'count:{count}, linePoints:{linePoints}')
return [centerPoint[0], centerPoint[1], dx, dy]

获得路口点

检测二值骨架栅格图的断点以及断线方向、十、丁字路口点_深度学习_04

def detect_intersection(img):
r, c = img.shape
new_image = np.zeros((r, c))
detection_operator = np.array([[1, 1, 1], [1, 1, 1], [1, 1, 1]])
break_points = []
for i in range(r-2):
for j in range(c-2):
if img[i+1, j+1] == 0:
new_image[i + 1, j + 1] = 0
else:
if np.sum(img[i:i + 3, j:j + 3] * detection_operator) > 3 and img[i+1, j+1] == 1:
new_image[i+1, j+1] = 1
break_points.append([i+1, j+1])
else:
new_image[i+1, j+1] = 0
return np.uint8(new_image), break_points

稀疏化

利用欧式距离进行点的稀疏化操作。

v1

def compute_euc(pointlist, point, thresh=12):
if len(pointlist) > 0:
distances = np.sqrt(np.sum(np.asarray(np.array(point) - np.array(pointlist)) ** 2, axis=1))
keep = np.where(distances < thresh, 1, 0).sum()
return keep
else:
return 0


def point_sparse(pointlist, thresh=12):
order = pointlist.copy()
pointKeep = []
while len(order) > 0:
point = order[0]
otherPoints = order[1:]
keep = compute_euc(otherPoints, point, thresh)
if keep == 0:
pointKeep.append(point)
order.pop(0)
return pointKeep

v2
网格化后再稀疏

import numpy as np
import os
import gdalTools
import time
import sys


def detect_breakpoints2(img):
ignore_border = 4000
r, c = img.shape
new_image = np.zeros((r, c))
detection_operator = np.array([[1, 1, 1], [1, 1, 1], [1, 1, 1]])
break_points = []
for i in range(ignore_border, r-ignore_border):
for j in range(ignore_border, c-ignore_border):
if img[i+1, j+1] == 0:
new_image[i + 1, j + 1] = 0
else:
if np.sum(img[i:i + 3, j:j + 3] * detection_operator) == 2:
new_image[i+1, j+1] = 1
break_points.append([i+1, j+1])
else:
new_image[i+1, j+1] = 0
return break_points


def detect_breakpoints(img, interval=400):
ignore_border = 4000
width, height = img.shape
col = np.ceil(width / interval).astype(np.uint16)
row = np.ceil(height / interval).astype(np.uint16)
print(f"col :{col}, row: {row}")
length = col * row
new_image = np.zeros((width, height))
detection_operator = np.array([[1, 1, 1], [1, 1, 1], [1, 1, 1]])
break_points = {}
for i in range(length):
break_points[i] = []
for i in range(ignore_border, width-ignore_border):
for j in range(ignore_border, height-ignore_border):
if img[i+1, j+1] == 0:
new_image[i + 1, j + 1] = 0
else:
val = np.sum(img[i:i + 3, j:j + 3] * detection_operator)
if val == 2 or val == 5:
sub_col = np.floor(i / interval).astype(np.uint16)
sub_row = np.floor(j / interval).astype(np.uint16)
new_image[i+1, j+1] = 1
index = sub_col * row + sub_row
break_points[index].append([i + 1, j + 1])
else:
new_image[i+1, j+1] = 0
return break_points, new_image


def compute_euc(pointlist, point, thresh=12):
if len(pointlist) > 0:
distances = np.sqrt(np.sum(np.asarray(np.array(point) - np.array(pointlist)) ** 2, axis=1))
keep = np.where(distances < thresh, 1, 0).sum()
return keep
else:
return 0


def point_sparse(pointlist, thresh=12):
order = pointlist.copy()
pointKeep = []
while len(order) > 0:
point = order[0]
otherPoints = order[1:]
keep = compute_euc(otherPoints, point, thresh)
if keep == 0:
pointKeep.append(point)
order.pop(0)
return pointKeep


def point_sparse2(pointlist, thresh=12):
order = pointlist.copy()
pointKeep = []
while len(order) > 0:
point = order[0]
otherPoints = order[1:]
keep = compute_euc(otherPoints, point, thresh)
if keep == 0:
pointKeep.append(point)
order.pop(0)
return pointKeep


if __name__ == '__main__':
CoarseSegPath = r'D:\MyWorkSpace\MyUtilsCode\segmentation\CroplandPredict\eval8\skeleton.tif'
outPath = CoarseSegPath.replace("skeleton", "points")

im_proj, im_geotrans, im_width, im_height, coarseImg = gdalTools.read_img(CoarseSegPath)
coarseImg = np.where(coarseImg > 0, 1, 0)

break_points, mask = detect_breakpoints(coarseImg, 200)
gdalTools.write_img(outPath, im_proj, im_geotrans, mask)
# print(break_points)
break_points2 = []
for k, v in break_points.items():
# print(f"key:{k}, val:{v}")
break_points2 += v
print(f"detect {len(break_points2)}")

s1 = time.time()
sparsePoints = []
for k, v in break_points.items():
sub_break_points = point_sparse(v, 30)
sparsePoints += sub_break_points
print(f"process {time.time() - s1}, length:{len(sparsePoints)}")

s2 = time.time()
break_points2 = point_sparse(break_points2, 30)
print(f"process {time.time() - s2}, length:{len(break_points2)}")

检测二值骨架栅格图的断点以及断线方向、十、丁字路口点_深度学习_05
速度要快不少


举报

相关推荐

0 条评论