Zhang-Suen骨架提取算法

前言

本专栏针对的目标物体为物体裂缝量化,提取裂缝的骨架有助于裂缝长度的求解,故这一篇也是本专栏的开篇。

细化算法选择与分析

裂缝骨架的提取是十分有必要,如果我们能够得到裂缝的骨架图那么就很容易获得整条裂缝的长度。在当前经典的细化算法,比如Zhang并行细化算法、Hilditch细化算法,Rosenfeld细化算法等都有被广泛应用在骨架提取算法之中。

其中Zhang并行细化算法细化过程简单,也是应用最广的一种,且细化后骨架位于图像中心线上,但是其结果图像往往有较多突起点和毛刺产生。Hilditch是基于二值化图像的基础上进行的,利用串行与并行相结合的方式提取骨架,虽然其细化效果较好,但是该算法判定条件繁复而冗余,导致处理时间较长,考虑到这些因素,故不采用Hilditch。Rosenfeld是一种基于边界追踪的细化算法,与 Zhang-Suen 和 Hilditch 等算法相比,Rosenfeld算法也被广泛应用于骨架提取。它通常产生相对平滑的骨架,较少出现突起点和毛刺。

从效果上来说应当选择Rosenfeld算法,但手写实现与skimage集成的Zhang-Suen算法比较,Zhang-Suen更胜一筹。

环境搭建

从上到下依次安装即可,如果报错没有这个包,就进行安装即可。

安装skimage

pip install scikit-image -i https://pypi.tuna.tsinghua.edu.cn/simple

安装opencv

​pip install opencv-python -i https://pypi.tuna.tsinghua.edu.cn/simple 

​pip install opencv-contrib-python -i https://pypi.tuna.tsinghua.edu.cn/simple

安装matplotlib

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple matplotlib==3.5.2 

安装pyzjr

pip install pyzjr -i https://pypi.tuna.tsinghua.edu.cn/simple 

裂缝数据集

我们针对的是适用于voc数据集的8位png彩图,从网上可以找到开源数据集进行测试,我这里采用的是裂缝森林的数据集,你可以从Kaggle上找到crackforest | Kaggle。如果你下载的数据集是mat后缀的,可以使用下面这个脚本进行转换。

# Mat2png.pyfrom os.path import isdir
from scipy import io
import os, sys
import numpy as np
from PIL import Imageif __name__ == '__main__':file_path = './groundTruth/'png_img_dir = './groundTruthPngImg/'if not isdir(png_img_dir):os.makedirs(png_img_dir)image_path_lists = os.listdir(file_path)images_path = []for index in range(len(image_path_lists)):image_file = os.path.join(file_path, image_path_lists[index])# print(image_file)#./CrackForest-dataset-master/groundTruth/001.matimages_path.append(image_file)image_mat = io.loadmat(image_file)segmentation_image = image_mat['groundTruth']['Segmentation'][0]segmentation_image_array = np.array(segmentation_image[0])image = Image.fromarray((segmentation_image_array - 1) * 255)png_image_path = os.path.join(png_img_dir, "%s.png" % image_path_lists[index][0:3])image.save(png_image_path)

如果你下载的时候就是这样的标签图最好不过了:

但请注意,如果不是自己标注的数据集,就最好要检查它的像素是否正确。

 远看没有任何的问题,如果你使用图片查看器或ps放大查看就会看到下面的情况:

这种图片是有问题的,所以必须要进行二值化操作。

裂缝骨架提取

Zhang-Suen我曾经使用过手写版本的,不是超时就是运行报错,而在skimage里面的skeletionize函数就能轻易的实现骨架化,这里调用multifile模式,即可进行文件夹的遍历,将骨架化后的图像保存到另一个文件夹当中。

import numpy as np
from skimage.filters import threshold_otsu,median
from skimage.morphology import skeletonize,dilation,disk
import os
import cv2
from skimage import io, morphologydef sketion(mode='multifile', input_folder='num', output_folder='output', single_pic='num/001.png'):""":param mode: 检测模式——single_pic检测单张图片并保存,multifile检测多张图片并保存:param input_folder: 目标文件夹:param output_folder: 输出文件夹:param single_pic: 用于检测单张图片的路径:return: 返回输出文件夹的路径的骨架图"""if mode == 'single':image = io.imread(single_pic, as_gray=True)# 使用Otsu阈值方法进行二值化处理thresh = threshold_otsu(image)binary = image > threshskeleton = skeletonize(binary)io.imshow(skeleton)io.imsave('output.png', skeleton)io.show()elif mode == 'multifile':if not os.path.exists(output_folder):os.makedirs(output_folder)  # 如果输出文件夹不存在,就创建它for filename in os.listdir(input_folder):if filename.endswith('.jpg') or filename.endswith('.png'):image = io.imread(os.path.join(input_folder, filename), as_gray=True)thresh = threshold_otsu(image)binary = image > threshbinary = dilation(binary, disk(3))binary = median(binary, selem=morphology.disk(5))# 效果不错binary = dilation(binary, disk(2))binary = median(binary, selem=morphology.disk(5))# 添加闭运算selem = morphology.disk(3)binary = morphology.closing(binary, selem)skeleton = skeletonize(binary)output_filename = os.path.join(output_folder, filename)io.imsave(output_filename, skeleton)return output_folder

这里先进行一个简单的测试。读取对应文件夹下的图片,看效果如下: 

import cv2
import pyzjr as pz
from matplotlib import pyplot as plt
img1=cv2.imread("./num/001.png")
img2=cv2.imread("./output/001.png")
stackedimg=pz.Stackedtorch([img1,img2],1,2,["原图","骨架图"])
plt.show()

注意 

这里的中值滤波median是我经过多种滤波测试后获得的较好的结果,你应当在自己的数据集上进行测试,包括膨胀与闭运算的操作,找到适用于自己的数据集上组合。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/79692.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

政府大数据资源中心建设总体方案[56页PPT]

导读:原文《政府大数据资源中心建设总体方案[56页PPT]》(获取来源见文尾),本文精选其中精华及架构部分,逻辑清晰、内容完整,为快速形成售前方案提供参考。 完整版领取方式 完整版领取方式: 如需…

decimal类型在MySQL中的正确使用 (长度和小数点)

1. MySQL(decimal) 对应 Java(BigDecimal) 2. decimal(16,2) MySQL中类型的设置, 长度16, 保留2位小数 3. 如果长度小于14, 则会出现没小数位的情况

数据采集的方法有哪些?

近年来,国家和各大企业都在部署大数据战略。“大数据”这个词也越来越频繁地出现在我们的生活中。当我们在进行网上冲浪时,页面总会跳出我们想要搜索的相关产品或关联事物。大数据,似乎总是能够“算”出我们“心中所想”。那么,大…

C++QT教程1——QT概述(下载与安装)

文章目录 1 Qt概述1.1 什么是Qt1.2 Qt的发展史1.3 Qt版本1.4 Qt的下载与安装下载地址:其实我是有点懵逼的,因为还有个qtcreator,我差点不知道下哪个。。。(qt框架比qtcreator功能更多更强大) 安装 1.5 Qt的优点1.6 QT成…

侯捷 C++面向对象编程笔记——9 复合 委托

9 复合 委托 9.1 Composition 复合 类似于c中结构里有结构——class里有class deque 是一个已经存在的功能很多的类(两头进出的队列);利用deque的功能来实现queue的多种操作 该例只是复合的一种情况——设计模式 Adapter 9.1.1 复合下的构造…

十四、ESP32播放音乐

1. 运行效果 2. 硬件电路 3. 代码 test.wav文件下载地址:

《向量数据库指南》——Rockset 为实时数据库添加向量嵌入支持(一)

2023年4月18日,数据库供应商 Rockset 公布了对向量嵌入的支持,此举旨在使用户能够实时搜索和操作任何类型的数据。 位于加利福尼亚州圣马特奥的 Rockset 以前支持结构化和半结构化数据,让用户可以使用 SQL 和 NoSQL 实时搜索和分析数据。 现在,通过增加对向量嵌入的支持…

网页版Java五子棋项目(一)websocket【服务器给用户端发信息】

网页版Java五子棋项目(一)websocket【服务器给用户端发信息】 一、为什么要用websocket二、websocket介绍原理解析 三、代码演示1. 创建后端api(TestAPI)新增知识点:extends TextWebSocketHandler重写各种方法 2. 建立…

【JVM】垃圾回收 ——自问自答2

Q: System.gc() 的理解 System.gc()底层调用的是 Runtime.getRuntime.gc(),会现实出发FullGC。 但是,它的调用附带一个免责声明,无法保证对垃圾收集器的调用。 Q: 内存溢出和内存泄漏? 内存溢出: 简而言之&#xf…

windows为nginx添加定时任务(开机延迟启动)

windows开机启动任务 调用定时任务管理器选中windows创建基本任务设置名称和描述设置触发器 并且添加个延迟触发设置操作设置条件配置设置 调用定时任务管理器 winr 输入 taskschd.msc回车 选中windows创建基本任务 设置名称和描述 设置触发器 并且添加个延迟触发 设置操作 …

Aligning Large Language Models with Human: A Survey

本文也是LLM相关的综述文章,针对《Aligning Large Language Models with Human: A Survey》的翻译。 对齐人类与大语言模型:综述 摘要1 引言2 对齐数据收集2.1 来自人类的指令2.1.1 NLP基准2.1.2 人工构造指令 2.2 来自强大LLM的指令2.2.1 自指令2.2.2 …

离散 Hopfield 神经网络的分类与matlab实现

1 案例背景 1.1离散 Hopfield 神经网络学习规则 离散型 Hopfield神经网络的结构、工作方式,稳定性等问题在第9章中已经进行了详细的介绍,此处不再赘述。本节将详细介绍离散Hopfield神经网络权系数矩阵的设计方法。设计权系数矩阵的目的是: ①保证系统在异步工作时的稳…

6.s081/6.1810(Fall 2022)Lab5: Copy-on-Write Fork for xv6

前言 本来往年这里还有个Lazy Allocation的,今年不知道为啥直接给跳过去了。. 其他篇章 环境搭建 Lab1: Utilities Lab2: System calls Lab3: Page tables Lab4: Traps Lab5: Copy-on-Write Fork for xv6 参考链接 官网链接 xv6手册链接,这个挺重要…

开发运营监控

DevOps 监控使管理员能够实时了解生产环境中的元素,并有助于确保应用程序平稳运行,同时提供最高的业务价值,对于采用 DevOps 文化和方法的公司来说,这一点至关重要。 什么是开发运营监控 DevOps 通过持续开发、集成、测试、监控…

vscode 第一个文件夹在上一层文件夹同行,怎么处理

我的是这样的 打开终端特别麻烦 解决方法就是 打开vscode里边的首选项 进入设置 把Compact Folders下边对勾给勾掉

Java Set集合:HashSet和TreeSet类

Set 集合类似于一个罐子,程序可以依次把多个对象“丢进”Set 集合,而 Set 集合通常不能记住元素的添加顺序。也就是说 Set 集合中的对象不按特定的方式排序,只是简单地把对象加入集合。Set 集合中不能包含重复的对象,并且最多只允…

谈谈DNS是什么?它的作用以及工作流程

作者:Insist-- 个人主页:insist--个人主页 作者会持续更新网络知识和python基础知识,期待你的关注 目录 一、DNS是什么? 二、DNS的作用 三、DNS查询流程 1、查看浏览器缓存 2、查看系统缓存 3、查看路由器缓存 4、查看ISP …

【JavaEE】深入了解Spring中Bean的可见范围(作用域)以及前世今生(生命周期)

【JavaEE】Spring的开发要点总结(4) 文章目录 【JavaEE】Spring的开发要点总结(4)1. Bean的作用域1.1 一个例子感受作用域的存在1.2 通过例子说明作用域的定义1.3 六种不同的作用域1.3.1 singleton单例模式(默认作用域…

【C++】C++11 新特性总结 | C++ 常见设计模式总结(秋招篇)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言介绍几种C11新特性介绍一下自动类型推导auto和decltype关键字的用法举例讲一下范围基于的for循环介绍一下列表初始化讲一下右值引用,和左值引用的区…

51单片机(普中HC6800-EM3 V3.0)实验例程软件分析 实验三 LED流水灯

目录 前言 一、原理图及知识点介绍 二、代码分析 知识点五:#include 中的库函数解析 _crol_,_irol_,_lrol_ _cror_,_iror_,_lror_ _nop_ _testbit_ 前言 第一个实验:51单片机(普中HC6800-EM3 V3.0…