来自于这里:基于OpenCV实现二值图细化,骨骼化并求出端点和交叉点_晴堂的博客-CSDN博客
我用python实现,并且改进了一下,看到回复发出来
def LineMid(binary): binary[binary == 255] = 1 skeleton0 = morphology.skeletonize(binary, method="lee") # 细化提取骨架 skeleton = skeleton0.astype(np.uint8) * 255 intMat = skeleton0.astype(int) return skeleton, intMat def getPoints(thinSrc, raudis=4, thresholdMax=6, thresholdMin=4): height, width = thinSrc.shape[0], thinSrc.shape[1] tmp = thinSrc.copy() points = [] for i in prange(height): for j in prange(width): if (tmp[i][j]) == 0: continue count = 0 for k in range(i - raudis, i + raudis + 1): for l in range(j - raudis, j + raudis + 1): if k < 0 or l < 0 or k > height - 1 or l > width - 1: continue elif tmp[k][l] == 255: count += 1 if count > thresholdMax: point = (j, i) points.append(point) return points def SplitImg(binary, points): Mat = binary.copy() if points: for poin in points: cv2.circle(Mat, (poin[0], poin[1]), 15, (0, 0, 0), -1) # 将交点抹除,这里以圆的方式拆除交点 splitmat = Mat.copy() conts, hierarchy = cv2.findContours(Mat, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) # 区域分块操作 for j in range(len(conts)): # 拆除交点后进行预支判定,小于阈值的就不要 area = cv2.contourArea(conts[j]) if area < 100: cv2.fillPoly(Mat, [conts[j]], 0) return Mat, splitmat
binary = Mat.copy() skeleton, intMat = LineMid(binary) points = getPoints(skeleton, raudis=1, thresholdMax=3, thresholdMin=4) # 找存在分支的交点 sigMat, SplitMat = SplitImg(Mat, points) # 根据交点拆解区域,去除交点区域