种子点的提取

作者: 大龙10 | 来源:发表于2024-01-29 11:59 被阅读0次

    书名:数字图像处理实战
    作者:杨坦 张良均
    出版社:人民邮电出版社有限公司
    出版时间:2023-11-01
    ISBN:9787115623850


    第9章 钢轨表面缺陷检测

    9.4 基于区域生长算法的钢轨表面缺陷检测

    • 经过9.3节中的预处理,原始图像变为只包含个别深色连通区域且背景为白色的图像。接下来要判断保留下来的连通区域是否对应钢轨表面的疤痕类缺陷。

    9.4.1 种子点的提取

    1、灰度直方图
    • 为了考察缺陷区域的特征,本小节利用数据集中提供的掩模图像,绘制缺陷区域像素的灰度直方图,以此来明确判断标准。
      先将灰度形式的掩模图像转换为布尔型数组,然后使用布尔型数组来引用图像中被标记为缺陷的像素,再使用自定义函数plt_hist绘制缺陷区域像素的灰度直方图,如代码9-5所示。
    import matplotlib.pyplot as plt
    mask = cv2.imread(mask_path)
    img = cv2.imread(Rail_surface_image_path)
    img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) #转灰度图
    mask_gray = cv2.cvtColor(mask, cV2.COLOR BGR2GRAY)
    img_gray = img_gray.T
    mask_gray = mask_gray.T
    def plt hist(img):
      fig = plt.figure()
      ax = fig.add_subplot(1,1,1)
      ax.hist(img.ravel(), 256,[0,80])
      ax.set title('rail_' + str(picture label) + ' gray plot')
      fig.savefig('../tmp/' + str(picture_label) + 'gray.png',dpi=400)
    plt.show()
    mask_bool = np.where(mask_gray > 20, True, False)
    plt_hist(img_gray[mask_bool])
    img_gray2 = np.where(mask_bool, img_gray, 255)
    cv2.imshow('rail ' + str(picture label), img_gray2)
    cv2.waitKey(0)
    cv2.destroyAllwindows()
    
    
    • 根据数据集所提供的掩模,在原图中统计缺陷对应位置的像素灰度,所得灰度值直方图如图9-9所示。


      图9-9 rail-5缺陷处的灰度值直方图
    2、不同图像缺陷处的灰度值直方图
    • 进一步,在代码9-1中修改要读取的图像标签值再运行代码9-5所示代码,可得到不同图像缺陷处的灰度值直方图,如图9-10所示,以此得出普遍适用的缺陷区域灰度特征。


      图9-10 不同图像缺陷处的灰度值直方图
    3、统计归纳出表面缺陷的灰度值
    • 观察了几幅图像中不同缺陷区域的像素灰度值直方图后,可以发现疤痕类钢轨表面缺陷的灰度值直方图的峰值都集中在20左右,即缺陷内必定存在灰度值在25以下的像素点。
      由此可见I型RSDDs数据集的质量较高,很好地控制了采集装置中的光源强度和光线入射角度,避免疤痕类缺陷内部被光线直接照射,使得缺陷区域的像素灰度值稳定地保持在一个较小的区间内。
    4、寻找种子点
    • 得到缺陷区域中一定存在灰度值小于25的像素这个先验知识,就可以利用它在去除背景后得到的连通区域内部寻找满足条件的点,作为缺陷区域的种子点,如代码9-6所示。
      每一个连通区域中只寻找一个符合灰度阈值的种子点,而一幅图像可能包含多个不同的连通区域,代码9-6中使用字典结构存储对应的连通区域的种子点集合。
    # 寻我初始种于点集合
    # 先找到所有灰度值在25 以下的像素点,然后将在同一个连通区域的点去除
    # 每一个连通区域只保留一个种子
    zhongzi_dict = []
    zhongz_yuzhi = 25
    for i in range(len(img_gray)):
      for j in range(len(img_gray[0])):
        if img_gray4[i][j]< zhongzi_yuzhi:
        # 找到一个符合条件的点后,将该点添加至字典内,键值为所在连通区域的编号
          if str(img_flag[i][j]) not in zhongzi dict:
          # 判断该连通区域在字典内是否存在符合条件的点
            zhongzi_dict[str(img_flag[i][j])]= []
          zhongz_dict[str(img_flag[il[jl)].append([i, j])
        # 得到了连通区域与内部可用种子点的对应关系后,每个连通区域只保留1个种子点
    print('连通区域数量为: [0]'.format(len(zhongzi_dict.keys())))
    # 每个连通区域选择的种子点最好在连通区域中心
    zhongzi =[]
    # for i in range(Len(zhongzi dict.keys())):
    for i in zhongzi dict.keys():
      k = len(zhongzi dict[i]) // 2
      zhongzi.append(zhongzi_dict[il[k])
    print('选取的种子点为:',zhongzi)
    
    
    5、代码说明
    • 为了不重复在同一个连通区域内多次寻找种子点,代码9-6中使用代码9-4中去除微小连通区域时生成的数组img_flag,该数组标明了每个像素点所属的连通区域的编号。
    • 首先对所有像素点的灰度值进行判断,对于灰度值小于阈值25的点,将其连通区域编号保存在种子字典zhongzi_dict中。
    • 为了得到每个连通区域中心的种子,接下来计算字典zhongzi_dict中属于每个连通区域的种子数量。
    • 根据前面扫描种子的顺序,可以知道位于连通区域中心的种子加入字典zhongzi_dict的位置也大约在中间。
    • 在代码的最后,只为每个连通区域保留一个种子,这些种子保存在最终的列表zhongzi中。

    选取样本图像rail_2,如图9-11所示。经过代码9-5所示代码处理后保留了两个连通区域,都包含灰度值小于25的像素点,运行代码9-6所示代码将输出如下内容。


    相关文章

      网友评论

        本文标题:种子点的提取

        本文链接:https://www.haomeiwen.com/subject/btvgodtx.html