opencv---curve breakpoint detection (eight neighborhood breakpoint detection)


foreword

The method works on 激光illuminated background images with no intersections and only one curve break detection

The original image

The cleaner and simpler the original image , the better the detection The cleaner and simpler
the original image , the better the detection The cleaner and simpler the original image , the better the detection The cleaner and simpler the original image , the better the detection


insert image description here

preprocessing (very important)处理越好,检测越准确

insert image description here
In image preprocessing, the cleaner the image noise processing, the better, because if the noise points are not processed cleanly, there will be huge errors in the subsequent breakpoint detection .

端点detection

insert image description here

断点detection

insert image description here

端点的坐标为:x:1381 y:273
端点的坐标为:x:37 y:281
端点的坐标为:x:1039 y:532
端点的坐标为:x:917 y:548
提取端点个数:4

Finally, according to the position of the endpoint, the ending endpoint is excluded, and the endpoints are paired in pairs to find the breakpoint position

full code

import cv2
from skimage import morphology
import numpy as np

img0 = cv2.imread('./silie/4232.jpg', 1)   # 读取图片
img = cv2.cvtColor(img0, cv2.COLOR_BGR2GRAY)
_,img = cv2.threshold(img, 30, 255, cv2.THRESH_BINARY)  # 二值化处理

ess = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (2,8))
img = cv2.dilate(img, ess, iterations=1)  # 形态学膨胀

contours, _ = cv2.findContours(img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

n = len(contours)  # 轮廓的个数
cv_contours = []
for contour in contours:
    area = cv2.contourArea(contour)
    if area <= 2000:# 筛选面积大于500的,小于500的全部变为255,
        cv_contours.append(contour)
cv2.fillPoly(img, cv_contours, (0, 0, 0)) # 多个多边形填充

img[img==255] = 1
skeleton0 = morphology.skeletonize(img)   # 骨架提取
skeleton = skeleton0.astype(np.uint8)*255
cv2.imshow('s',skeleton)

def breakImage(img):
    pointxy = list()
    img_size = img.shape  # height,width,passageway
    for i in range(1,img_size[0]-1):
        PX_PRE = img[i-1]
        PX_curr = img[i]
        PX_Next = img[i+1]
        for j in range(1,img_size[1]-1):
            p1 = PX_curr[j]
            if p1 != 255:
                continue
            p2 = PX_PRE[j]
            p3 = PX_PRE[j+1]
            p4 = PX_curr[j+1]
            p5 = PX_Next[j+1]
            p6 = PX_Next[j]
            p7 = PX_Next[j-1]
            p8 = PX_curr[j-1]
            p9 = PX_PRE[j-1]
            if p1 ==255:
                if (p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9) == 255:
                    pointxy.append((j,i))
                    # pointy.append(i)

    return pointxy

pointxy = breakImage(skeleton)
pointxy = sorted(pointxy)
pointxy = pointxy[1:][:-1]

num = len(pointxy)
if num % 2 == 0:
    for i in range(int(num / 2)):
        cv2.rectangle(img0, pointxy[i * 2], pointxy[i * 2 + 1], (0, 255, 0), 2)
elif num % 2 == 1 and num != 1:
    for i in range(int(len(pointxy) / 2) - 1):
        cv2.rectangle(img0, pointxy[i * 2], pointxy[i * 2 + 1], (0, 255, 0), 2)
    cv2.rectangle(img0, pointxy[-3], pointxy[-1], (0, 255, 0), 2)

cv2.imwrite("skeleton.png", img0)        # 保存骨架提取后的图片
cv2.waitKey(0)

insert image description here

insert image description here

insert image description here
insert image description here
Hope this article is useful to you!

Thank you for your likes and comments!

Guess you like

Origin blog.csdn.net/qq_44936246/article/details/126508880