直方图投影法判断裂缝走势(裂缝类型)

news2024/11/18 9:32:26

裂缝类型

裂缝类型有很多种,这里我们仅仅判断线性裂缝与网状裂缝,线性裂缝按照其走势有可分为横向裂缝、纵向裂缝和斜向裂缝。

我觉得大家应当有这样的意识,面对网状裂缝,它的二维参数是否有意义?答案是没有!如果检测到网状裂缝,我想大家的第一反应是比较严重了,需要修补了。如果是一条线性裂缝呢?我是不是还有考虑一下它的受损程度是否达到需要修补的地步。

所以按照我的想法,可以求网状裂缝的面积,评估其受损程度,求线性裂缝的面积、长度和宽度,评估其受损程度。

直方图投影法

网状裂缝的直方图投影 

横向裂缝的直方图投影 

纵向裂缝的直方图投影 

斜向裂缝的直方图投影 

上面四张图是四种裂缝对应的直方图,结合上面的一些特点,我们可以依照自己的数据集进行类型分类。

 获取最小外接矩形信息

接下来,get_minAreaRect_information函数会从二值化掩膜图像中提取最小外接矩形的相关信息,包括中心点坐标、宽高和旋转角度。inference_minAreaRect函数用于计算最小外接矩形框的宽、高和角度信息,并将角度转换为相对于图像水平方向的夹角。

def inference_minAreaRect(minAreaRect):
    w, h = minAreaRect[1]
    if w > h:
        angle = int(minAreaRect[2])
    else:
        angle = -(90 - int(minAreaRect[2]))
    return w, h, angle

def _get_minAreaRect_information(mask):
    mask = pz.BinaryImg(mask)
    contours, hierarchy = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    contour_merge = np.vstack(contours)
    minAreaRect = cv2.minAreaRect(contour_merge)
    return minAreaRect

pz.BinaryImg获取图像二值图,请确保读取时候为BGR的图片。 

初始化分类裂缝的参数

创建了一个ClassificationCrack类,并且对裂缝的分类参数进行初始化,有分类裂缝的阈值threshold,分类裂缝的高宽比阈值HWration,用于分类裂缝的直方图比例阈值Histration。

class CrackType():
    """直方图投影法推断裂缝类型"""
    def __init__(self, threshold=3, HWratio=10, Histratio=0.5):
        """
        初始化分类裂缝的参数
        :param threshold: 阈值,用于分类裂缝的阈值
        :param HWratio: 高宽比,用于分类裂缝的高宽比阈值
        :param Histratio: 直方图比例,用于分类裂缝的直方图比例阈值
        """
        self.threshold = threshold
        self.HWratio = HWratio
        self.Histratio = Histratio
        self.types = {0: 'Horizontal',
                      1: 'Vertical',
                      2: 'Oblique',
                      3: 'Mesh'}

这里我们使用字典self.types,这样就可以通过键值对判断裂缝的类型了。

骨骼点投影直方图

在ClassificationCrack类下,我们再定义了一个hist_judge的方法,less_than_T统计直方图中大于 0 且小于等于阈值 self.threshold 的像素数量,more_than_T统计直方图中大于阈值 self.threshold 的像素数量。通过more_than_T / (less_than_T + 1e-5)来比较是否超过了直方图比例阈值。

    def hist_judge(self, hist_v):
        less_than_T = np.count_nonzero((hist_v > 0) & (hist_v <= self.threshold))
        more_than_T = np.count_nonzero(hist_v > self.threshold)
        return more_than_T / (less_than_T + 1e-5) > self.Histratio

裂缝分类

classify 方法是 ClassificationCrack 类中的另一个成员方法,它接收三个值,minAreaRect 是一个元组,表示最小外接矩形框的信息,包括中心点坐标、宽高和旋转角度;skeleton_pts是一个数组,表示骨骼点的坐标;HW是当前 patch 的高和宽。

    def classify(self, minAreaRect, skeleton_pts, HW):
        H, W = HW
        w, h, angle = inference_minAreaRect(minAreaRect)
        if w / h < self.HWratio or h / w < self.HWratio:
            pts_y, pts_x = skeleton_pts[:, 0], skeleton_pts[:, 1]
            hist_x = np.histogram(pts_x, W)
            hist_y = np.histogram(pts_y, H)
            if self.hist_judge(hist_x[0]) and self.hist_judge(hist_y[0]):
                return 3

        return self.angle2cls(angle)

    @staticmethod
    def angle2cls(angle):
        angle = abs(angle)
        assert 0 <= angle <= 90, "ERROR: The angle value exceeds the limit and should be between 0 and 90 degrees!"
        if angle < 35:
            return 0
        elif 35 <= angle <= 55:
            return 2
        elif angle > 55:
            return 1
        else:
            return None

利用 inference_minAreaRect 函数从 minAreaRect 中获取旋转矩形框的宽度 w、高度 h 和角度 angle。接下来,通过判断 w / h 和 h / w 是否小于 self.HWratio 来判断旋转矩形框的长宽比是否满足分类条件。

如果长宽比满足条件,则将 skeleton_pts 按照 x 和 y 方向投影到直方图 hist_x 和 hist_y,然后通过 self.hist_judge 方法判断这两个直方图是否满足分类条件。

以上条件均满足,则会认为是网状裂缝,否则就使用angle2cls来进行角度分类。

根据角度的大小将裂缝分为以下三类:

  • 如果角度小于 35 度,则返回 0,表示水平裂缝。
  • 如果角度在 35 到 55 度之间,则返回 2,表示倾斜裂缝。
  • 如果角度大于 55 度,则返回 1,表示垂直裂缝。
  • 如果角度不在上述范围内,则返回 None 。

测试文件main

"""
裂缝分类如何判断
横向、纵向、网状、斜裂缝
"""
import os
import matplotlib.pyplot as plt

import numpy as np
import cv2
import pyzjr as pz

from skimage.morphology import skeletonize
from skimage.filters import threshold_otsu
from skimage.color import rgb2gray

class CrackType():
    """直方图投影法推断裂缝类型"""
    def __init__(self, threshold=3, HWratio=10, Histratio=0.5):
        """
        初始化分类裂缝的参数
        :param threshold: 阈值,用于分类裂缝的阈值
        :param HWratio: 高宽比,用于分类裂缝的高宽比阈值
        :param Histratio: 直方图比例,用于分类裂缝的直方图比例阈值
        """
        self.threshold = threshold
        self.HWratio = HWratio
        self.Histratio = Histratio
        self.types = {0: 'Horizontal',
                      1: 'Vertical',
                      2: 'Oblique',
                      3: 'Mesh'}

    def inference_minAreaRect(self, minAreaRect):
        """
        旋转矩形框长边与x轴的夹角.
        旋转角度 angle 是相对于图像水平方向的夹角,范围是 -90 到 +90 度.
        然而,一般情况下,我们习惯将角度定义为相对于 x 轴正方向的夹角,范围是 -180 到 +180 度.
        """
        w, h = minAreaRect[1]
        if w > h:
            angle = int(minAreaRect[2])
        else:
            angle = -(90 - int(minAreaRect[2]))
        return w, h, angle

    def classify(self, minAreaRect, skeleton_pts, HW):
        """
        针对当前crack instance,对其进行分类;
        主要利用了骨骼点双向投影直方图、旋转矩形框宽高比/角度;
        :param minAreaRect: 最小外接矩形框,[(cx, cy), (w, h), angle];
        :param skeleton_pts: 骨骼点坐标;
        :param HW: 当前patch的高、宽;
        """
        H, W = HW
        w, h, angle = self.inference_minAreaRect(minAreaRect)
        if w / h < self.HWratio or h / w < self.HWratio:
            pts_y, pts_x = skeleton_pts[:, 0], skeleton_pts[:, 1]
            hist_x = np.histogram(pts_x, W)
            hist_y = np.histogram(pts_y, H)
            if self.hist_judge(hist_x[0]) and self.hist_judge(hist_y[0]):
                return 3

        return self.angle2cls(angle)

    def hist_judge(self, hist_v):
        less_than_T = np.count_nonzero((hist_v > 0) & (hist_v <= self.threshold))
        more_than_T = np.count_nonzero(hist_v > self.threshold)
        return more_than_T / (less_than_T + 1e-5) > self.Histratio

    @staticmethod
    def angle2cls(angle):
        angle = abs(angle)
        assert 0 <= angle <= 90, "ERROR: The angle value exceeds the limit and should be between 0 and 90 degrees!"
        if angle < 35:
            return 0
        elif 35 <= angle <= 55:
            return 2
        elif angle > 55:
            return 1
        else:
            return None

def _get_minAreaRect_information(mask):
    """
    从二值化掩膜图像中获取最小外接矩形的相关信息
    :param mask:二值化掩膜图像,包含目标区域的白色区域
    :return:最小外接矩形的信息,包括中心点坐标、宽高和旋转角度
    """
    mask = pz.BinaryImg(mask)
    contours, hierarchy = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    contour_merge = np.vstack(contours)
    minAreaRect = cv2.minAreaRect(contour_merge)
    return minAreaRect

def SkeletonMap(target):
    """
    获取骨架图的信息
    :param target: 目标图
    :return: 骨架图与一个数组,其中每一行表示一个非零元素的索引(y,x),包括行索引和列索引
    """
    gray = rgb2gray(target)
    thresh = threshold_otsu(gray)
    binary = gray > thresh
    skimage = skeletonize(binary)
    skepoints = np.argwhere(skimage)
    skimage = skimage.astype(np.uint8)
    return skimage, skepoints

if __name__ == '__main__':
    plt.switch_backend('TkAgg')
    masks_dir = r"D:\PythonProject\RoadCrack\dimension2_data\num"  # 这里改为存放上面图片的路径
    results_save_dir = "A_results"
    os.makedirs(results_save_dir, exist_ok=True)
    classifier = CrackType()
    imgfile,_ = pz.getPhotopath(masks_dir, debug=False)
    for path in imgfile:
        mask = cv2.imread(path)
        H, W = mask.shape[:2]
        mask_copy = mask.copy()
        skeimage, skepoints = SkeletonMap(mask_copy)

        minAreaRect=_get_minAreaRect_information(mask)

        pts_y, pts_x = skepoints[:, 0], skepoints[:, 1]
        hist_x = np.histogram(pts_x, W)
        hist_y = np.histogram(pts_y, H)

        result = classifier.classify(minAreaRect, skepoints, HW=(H, W))
        crack_type = classifier.types[result]
        print(crack_type)

        T = classifier.threshold


        plt.figure(figsize=(10, 5))

        plt.subplot(121)
        plt.plot(hist_x[1][:-1], [T] * len(hist_x[0]), 'r')
        plt.bar(hist_x[1][:-1], hist_x[0])
        plt.title("Histogram X")

        plt.subplot(122)
        plt.plot(hist_y[1][:-1], [T] * len(hist_y[0]), 'r')
        plt.bar(hist_y[1][:-1], hist_y[0])
        plt.title("Histogram Y")

        plt.tight_layout()  # 自动调整子图布局,防止重叠
        plt.show()

与我们实际图片进行对比,其检测效果均还不错,threshold,HWratio,Histratio这三个初始值均为经验所得,还是要依照自己的数据来设定。这里的SkeletionMap函数将会获得骨架图中的索引点,它并没有进行去消除毛刺的,实际并不影响,因为我们采用的这个方法,些许毛刺影响不了判断。

现在我们只需要写一个推动裂缝类型的函数,可以用于直接去判断我们设定的裂缝类型:

def infertype(mask):
    """推导裂缝类型"""
    crack = CrackType()
    H, W = mask.shape[:2]
    mask_copy = mask.copy()
    skeimage, skepoints = SkeletonMap(mask_copy)
    minAreaRect = _get_minAreaRect_information(mask)
    result = crack.classify(minAreaRect, skepoints, HW=(H, W))
    crack_type = crack.types[result]
    return result, crack_type

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

宝塔Node部署nuxt3

宝塔Node部署nuxt3 1、首先本地执行打包 yarn build2、然后把目录中的这个文件压缩成zip 3、在宝塔文件处添加一个网站的文件目录&#xff0c;并把文件解压到里面 4、点击左侧的网站&#xff0c;然后选择node项目&#xff0c;选择node版本安装 5、安装完后&#xff0c;点击新…

【C语言】快速排序

文章目录 一、hoare版本二、挖坑法三、前后指针法四、非递归快排五、快速排序优化1、三数取中选key值2、小区间优化 六、代码测试 一、hoare版本 快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法&#xff0c;其基本思想为&#xff1a;任取待排序元素序列中的某元素…

云中的网络Qos

在 Linux 下&#xff0c;可以通过 TC 控制网络的 QoS&#xff0c;主要就是通过队列的方式。 第一大类称为无类别排队规则&#xff08;Classless Queuing Disciplines&#xff09;。pfifo_fast 分为三个先入先出的队列&#xff0c;称为三个 Band。根据网络包里面 TOS&#xff0…

VScode调试复杂C/C++项目

以前都是用的VScode调试c/cpp的单个文件的编译和执行, 但是一遇到大型项目一般就用gdb了, gdb的调试效率和VScode差距还是比较大的, 但最近发现VScode其实也能调试复杂的cpp项目, 所以记录一下. 首先明确一下几点: 首先cpp文件需要经过编译, 生成可执行文件, 然后通过运行/调…

百度搜索逐步恢复优质网站权限

我是卢松松&#xff0c;点点上面的头像&#xff0c;欢迎关注我哦&#xff01; 从9月25日开始&#xff0c;有越来越多的站长和卢松松反馈&#xff0c;说他们的站可以正常入驻百度搜索资源平台了。我也试了试卢松松博客&#xff0c;果然&#xff0c;可以正常提交了。还是以前的…

iTOP-3568开发板Ubuntu下安装ADB工具

在虚拟机 Ubuntu 使用以下命令安装 ADB&#xff0c;如下图所示&#xff1a; sudo apt install adb 接下来进行测试&#xff0c;执行如下命令&#xff0c;确认 adb 安装是否成功。 adb version 如上图所示&#xff0c;执行命令能成功获取到 adb 版本信息&#xff0c;说明 adb …

防火墙网络接口下面多个外网地址,只有第一地址可以访问通其他不通

环境&#xff1a; 主备防火墙 8.0.75 AF-2000-FH2130B-SC 问题描述&#xff1a; 两台防火墙双击热备&#xff0c;高可用防火墙虚拟网络接口Eth4下面有多个外网地址&#xff0c;只有第一地址可以访问通其他不通 解决方案&#xff1a; 1.检查防火墙路由设置&#xff08;未解决…

3D WEB轻量化引擎HOOPS助力3D测量应用蓬勃发展:效率、精度显著提升

在3D开发工具领域&#xff0c;Tech Soft 3D打造的HOOPS SDK已经崭露头角&#xff0c;成为了全球领先的3D领域开发工具提供商。HOOPS SDK包括四种不同的3D软件开发工具&#xff0c;已成为行业的翘楚。 其中&#xff0c;HOOPS Exchange以其CAD数据转换的能力脱颖而出&#xff0c…

5.wifi开发【智能家居:上】,开发准备:智能开关灯,智能采集温湿,智能调彩灯

一。wifi智能家居项目开发 【开发准备1】&#xff1a;继电器控制开发 1.智能开关 器件准备&#xff1a;wifi&#xff08;esp8266&#xff0c;使用CP2102&#xff09;继电器 结果&#xff1a; 2.继电器工作原理 &#xff08;1&#xff09;继电器是一种自动电气开关 &#xff…

Multisim14.0仿真(二十六)基于LM555定时器的施密特触发器

一、仿真原理图&#xff1a; 二、仿真效果图&#xff1a;

01-工具篇-windows与linux文件共享

一般来说绝大部分PC上装的系统均是windows&#xff0c;为了开发linux程序&#xff0c;会在PC上安装一个Vmware的虚拟机&#xff0c;在虚拟机上安装ubuntu18.04&#xff0c;由于windows上的代码查看软件、浏览器&#xff0c;通信软件更全&#xff0c;我们想只用ubuntu进行编译&a…

【VUE复习·5】插值语法(使用 计算属性 的插值语法)

总览 1.计算属性 2.使用 methods 的 插值语法 3.使用 computed 的 插值语法 一、计算属性 1.解释 首先&#xff0c;如果我们要写一个插值语法&#xff0c;而 {{ }} 内的内容&#xff0c;是一个经过计算的值&#xff0c;那么按照原本 JS 的写法&#xff0c;应该是这样的&…

目标检测YOLO实战应用案例100讲-区域卷积网络在阴影环境目标检测上的研究与应用(下)

目录 5.2 阴影检测模块与街景检测模块实验设置 5.2.1 实验环境与工具 5.2.3 损失函数 5.2.4 实验具体流程 5.3 实验评估与对比 5.3.1 两类实验的评估标准 5.3.2 两类实验结果对比 阴影环境下街景目标检测系统的实现 6.1 系统概述 6.2 系统软硬件环境 6.3 功能模块设计 6.4 系统…

嵌入式Linux应用开发-IMX6ULL板硬件资源及开发环境

嵌入式Linux应用开发-IMX6ULL板硬件资源及开发环境 第一章 硬件资源1.1 板上资源1.2 板外模块 第二章 准备开发环境2.1 IMX6ULL 开发板接线与启动1) 连接串口线和电源线2) 安装 USB 串口驱动3) 选择启动方式4) 设置串口工具&#xff0c;启动开发板 第一章 硬件资源 iMX6ULL板是…

vlc将本地文件推流成ts实时流

推流 打开vlc &#xff0c;打开 媒体----打开网络串流 选择文件选项卡&#xff0c;打开本地文件 点击添加&#xff0c;选择本地的mp3文件 选择串流 点击下拉框&#xff0c;选择udp&#xff0c;点击右边的【添加】按钮 输入媒体流输出地址&#xff0c;点击【下一个】 选择正确的…

《C++ Primer》第4章 表达式(一)

参考资料&#xff1a; 《C Primer》第5版《C Primer 习题集》第5版 4.1 基础&#xff08;P120&#xff09; 表达式由一个或多个运算对象组成&#xff0c;对表达式求值将得到一个结果。字面量和变量是最简单的表达式。 4.1.1 基本概念&#xff08;P120&#xff09; C 定义了…

淘宝拍立淘插件转链和商业化图片生成接口介绍,图片搜索商品接口,按图搜索接口,图片识别商品接口介绍

淘宝拍立淘是淘宝网推出的一种搜索方式&#xff0c;通过拍立淘&#xff0c;用户可以输入文字描述或上传图片来搜索商品。拍立淘通过与淘宝网进行数据接入和授权&#xff0c;使用淘宝提供的API获取商品信息和操作权限&#xff0c;拍立淘使用图像识别技术&#xff0c;通过深度学习…

【Java 进阶篇】深入理解SQL的数据操作语言(DML)

SQL&#xff08;Structured Query Language&#xff09;是一种用于管理和操作关系数据库的强大语言。SQL语言被分为多个子语言&#xff0c;其中之一是DML&#xff08;Data Manipulation Language&#xff09;&#xff0c;用于执行与数据的操作和管理相关的任务。在本文中&#…

Ci2451-2.4g无线MCU收发芯片

Ci2451 是一款集成无线收发器和8位RISC(精简指令集)MCU的SOC芯片。 无线MCU解决方案,集成丰富的MCU资源、更小尺寸,来满足设计中的各种内存、功率、尺寸要求,充分缩短2.4GHz无线产品设计周期并优化产品成本。 添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff…

聚观早报 | 智界S7正式亮相;ChatGPT重磅更新

【聚观365】9月27日消息 智界S7正式亮相 ChatGPT重磅更新 PICO应用数量已超530款 泡泡玛特上半年海外营收大增 亚马逊投资Anthropic40亿美元 智界S7正式亮相 在日前举行的华为秋季全场景新品发布会上&#xff0c;华为智选车业务首款轿车智界S7正式亮相&#xff0c;定位高…