opencv---曲线断点检测(八邻域断点检测)


前言

该方法适用于激光照射的背景图像,没有交叉,仅限一条曲线断裂检测

原始图像

原始图像越干净、简单,检测效果越好
原始图像越干净、简单,检测效果越好
原始图像越干净、简单,检测效果越好
原始图像越干净、简单,检测效果越好
在这里插入图片描述

预处理(很重要)处理越好,检测越准确

在这里插入图片描述
在图像预处理这里,对图像的噪声处理越干净越好,因为如何对于噪声点没有处理干净,对于后面的断点检测会出现巨大的误差。

端点检测

在这里插入图片描述

断点检测

在这里插入图片描述

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

最后根据端点的位置,排除收尾端点,在进行端点两两配对,找出断点位置

完整代码

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)

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
希望这篇文章对你有用!

谢谢点赞评论!

猜你喜欢

转载自blog.csdn.net/qq_44936246/article/details/126508880