最大内切圆算法计算裂缝宽度

news2024/11/24 23:09:39

本文这里是对CSDN上另一位博主的代码进行了整理:

基于opencv的裂缝宽度检测算法(计算轮廓最大内切圆算法)

我觉得这位博主应该是上传了一个代码草稿,我对其进行了重新整理,并添加了详细的注释。

import cv2
import math
import random
import numpy as np
from numpy.ma import cos, sin
import pyzjr as pz

class Maximum_width:
    def findContous(self,img):
        kernel = np.ones((1, 5), np.uint8)
        thresh=pz.BinaryImg(img)
        thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel, anchor=(2, 0), iterations=5)
        contous, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
        return contous

    def Extract_repeat_points(self,contour,Bbox):
        """
        从给定多边形轮廓内提取位于矩形区域内的点。
        :param contour: 多边形轮廓点集
        :param Bbox: 矩形区域的边界坐标信息[left_x, up_y, right_x, down_y]
        :return: 位于多边形内且在矩形区域内的点数组
        """
        left_x, up_y, right_x, down_y=Bbox
        Nx = 2 ** 8
        Ny = 2 ** 8
        pixel_X = np.linspace(left_x, right_x, Nx)
        pixel_Y = np.linspace(up_y, down_y, Ny)
        xx, yy = np.meshgrid(pixel_X, pixel_Y)

        mask = np.zeros(xx.shape, dtype=bool)
        for i in range(xx.shape[0]):
            for j in range(xx.shape[1]):
                if cv2.pointPolygonTest(contour, (xx[i, j], yy[i, j]), False) > 0:
                    mask[i, j] = True

        in_point = np.column_stack((xx[mask], yy[mask]))
        return in_point

    def find_max_radius(self,contous, pixelx, pixely, small_r, big_r, precision):
        """
        在给定轮廓内查找最大半径。
        :param contours: 轮廓
        :param pixelx: 圆心的像素 x 坐标
        :param pixely: 圆心的像素 y 坐标
        :param small_r: 最小半径
        :param big_r: 最大半径
        :param precision: 精度
        :return: 最大半径
        """
        radius = small_r
        L = np.linspace(0, 2 * math.pi, 360)
        circle_X = pixelx + radius * cos(L)
        circle_Y = pixely + radius * sin(L)
        for i in range(len(circle_Y)):
            if cv2.pointPolygonTest(contous, (circle_X[i], circle_Y[i]), False) < 0:
                return 0
        while big_r - small_r >= precision:
            half_r = (small_r + big_r) / 2
            circle_X = pixelx + half_r * cos(L)
            circle_Y = pixely + half_r * sin(L)
            if_out = False
            for i in range(len(circle_Y)):
                if cv2.pointPolygonTest(contous, (circle_X[i], circle_Y[i]), False) < 0:  # 如果圆散集有在轮廓之外的点
                    big_r = half_r
                    if_out = True
            if not if_out:
                small_r = half_r
        radius = small_r
        return radius

    def find_optimal_information(self,in_point,big_r,precision,contous,sample_ratio=0.01):
        """
        从一组点中寻找具有最大内切圆半径的点。
        :param in_point: 点集合
        :param big_r: 内切圆最大半径
        :param precision: 精度
        :param contous: 多边形轮廓
        :param sample_ratio: 采样比例
        :return: 具有最大内切圆半径的点的坐标和半径
        """
        num_points = len(in_point)
        num_samples = max(1, int(num_points * sample_ratio))
        sampled_indices = random.sample(range(num_points), num_samples)
        sampled_indices.sort()
        best_radius = 0
        center = None
        for idx in sampled_indices:
            point = in_point[idx]
            max_radius_for_point = self.find_max_radius(contous, point[0], point[1], best_radius, big_r, precision)
            if max_radius_for_point > best_radius:
                best_radius = max_radius_for_point
                center = point

        remaining_indices = [i for i in range(num_points) if i not in sampled_indices]
        for idx in remaining_indices:
            point = in_point[idx]
            max_radius_for_point = self.find_max_radius(contous, point[0], point[1], best_radius, big_r, precision)
            if max_radius_for_point > best_radius:
                best_radius = max_radius_for_point
                center = point

        return best_radius, center

    def FindmaxIncircle(self, circle_list):
        """
        在裂缝最大内切圆信息中找到具有最大半径的内切圆的中心坐标和半径。
        :param circle_list: 裂缝最大内切圆信息列表,每个元素为 [radius, center]
        :return: 最大半径的内切圆的中心坐标和半径
        """
        max_radius = max(circle_list, key=lambda x: x[0])[0]
        max_center = next(item for item in circle_list if item[0] == max_radius)[1]
        return max_center, max_radius


    def draw_contous_circle(self,original_img, contours, circle_list, max_radius, max_center):
        """
        在原始图像上绘制轮廓及内切圆。
        :param original_img: 原始图像
        :param contours: 轮廓列表
        :param circle_list: 扩展圆信息列表
        :param max_radius: 最大内切圆半径
        :param max_center: 最大内切圆中心
        :return: 绘制了轮廓和内切圆的图像
        """
        cv2.drawContours(original_img, contours, -1, (0, 0, 255), -1)
        for circle_info in circle_list:
            radius, center = circle_info[:2]
            color = (255, 0, 0) if radius == max_radius else (255, 245, 0)
            if radius == max_radius:
                cv2.circle(original_img, (int(max_center[0]), int(max_center[1])), int(max_radius), color, 2)
            else:
                cv2.circle(original_img, (int(center[0]), int(center[1])), int(radius), color, 2)

        return original_img

def dealwith_inCircle(img,imgoriginal,showCircle=True):
    """
    处理内切圆问题并显示结果。
    :param img: 输入处理的标签图像
    :param img_original: 对应的原始图像
    :param show_circle: 是否显示内切圆结果,默认为 True
    """
    mac = Maximum_width()
    contous = mac.findContous(img)
    expansion_circle_list = []
    for con in contous:
        left_x, right_x, down_y, up_y = np.min(con[:, 0, 0]), np.max(con[:, 0, 0]), np.max(con[:, 0, 1]), np.min(con[:, 0, 1])
        Bbox=[left_x, up_y, right_x, down_y]
        upper_r = min(right_x - left_x, down_y - up_y) / 2
        precision = math.sqrt((right_x - left_x) ** 2 + (down_y - up_y) ** 2) / (2 ** 13)      #获得二分精度
        in_point=mac.Extract_repeat_points(con, Bbox)
        radius,center=mac.find_optimal_information(in_point,upper_r,precision,con)
        expansion_circle_list.append([radius, center])
    max_center,max_radius=mac.FindmaxIncircle(expansion_circle_list)
    if showCircle:
        Circle=mac.draw_contous_circle(imgoriginal,contous,expansion_circle_list,max_radius,max_center)
        cv2.imshow("Maximum Inscribed Circle",Circle)
        cv2.waitKey(0)
    return round(max_radius*2,2)

if __name__=="__main__":
    from pyzjr.dlearn.tools import Runcodes
    with Runcodes("最大内切圆算法"):
        path = r"D:\PythonProject\RoadCrack\dimension2_data\num/024.png"  # 分割图
        path2 = r"D:\PythonProject\RoadCrack\dimension2_data\image/013.jpg"  # 对应的原图
        img = cv2.imread(path)
        img2 = cv2.imread(path2)
        width=dealwith_inCircle(img,img2,False)
        print(f'最大宽度:{round(width, 2)}')

最大宽度:13.84

将标签图放大,可以数一数确实还可以,大致在13左右。使用的方式是通过从给定的轮廓中提取点,并使用二分法来查找最大内切圆的半径。它通过在多个采样点上尝试不同的半径大小,验证这些半径是否有效来确定最大内切圆。最后,绘制了找到的最大内切圆以及相关的轮廓,这个博主实现的算法可以用,但这个算法加在ui里面还是稍微的比较卡,在我看来这里其实是不用这么多的,这个算法还有其他的方法去实现,后面我会单独出一篇,毕竟这个是一个新的创新点。

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

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

相关文章

产业园区中工业厂房的能源综合配置

安科瑞 崔丽洁 园区工业地产中能源综合配置存在的问题 我国园区工业地产建设已历经近40年的发展, 园区在区域经济发展、产业集聚方面发挥了重要的载体和平台作用, 有力推动了我国社会经济的高质量发展。园区工业地产是国民经济的发展的重要载体, 但同时也是集中的环境污染源。…

大数据Doris(一):Doris概述篇

文章目录 Doris概述篇 一、前言 二、Doris简介

Norms and Inner Products

See https://ai.stanford.edu/~gwthomas/notes/norms-inner-products.pdf

Jenkins 权限管理

关于Role-based Authorization Strategy 使用Jenkins自身的权限管理过于粗糙&#xff0c;无法对单个、一类项目做管理&#xff0c;我们可以使用 Role-based Authorization Strategy插件来管理项目、角色。 首先安装该插件&#xff1a;在Jenkins查看该插件有无安装 在Jenkins-…

C++ 类和对象 (5) 析构函数

用构造函数创建对象后&#xff0c;程序负责跟踪该对象&#xff0c;直到对象过期为止。对象过期时&#xff0c;程序将自动调用一个特殊的成员函数&#xff0c;该函数的名称——析构函数。析构函数完成清理工作&#xff0c;实际上还是很有用的。例如&#xff0c;用new来分配一个构…

八、【漏洞复现】jupyter-notebook 命令执行(CVE-2019-9644)

8.0、基础知识 1、测试功能点 &#xff08;这种情况基本上很难遇到&#xff09; 8.1、漏洞原理 ​Jupyter Notebook是一套用于创建、共享代码和说明性文本文档的开源Web应用程序。 Jupyter Notebook可直接使用命令行执行任意命令。​ 8.2、影响范围 未授权开启终端权限的…

嵌入式Linux应用开发-基础知识-第七章 具体单板的 LED驱动程序

嵌入式Linux应用开发-基础知识-第七章 具体单板的 LED驱动程序 第七章 具体单板的 LED 驱动程序7.1 怎么写 LED 驱动程序&#xff1f;7.2 AM335X的 LED驱动程序7.2.1 原理图 XXXXXX_AM335X开发板结构为&#xff1a;7.2.2 所涉及的寄存器操作7.2.3 写程序7.2.4 配置内核去掉原有…

PyTorch meshgrid 生成网格坐标

torch.meshgrid(*tensors, indexingNone) 使用输入的 1-D 张量创建网格坐标 示例 indexing‘xy’ import torcha torch.arange(3) b torch.arange(3, 6)x, y torch.meshgrid(a, b, indexingxy) print(x , x, sep\n) print(y , y, sep\n)输出: x tensor([[0, 1, 2],[0, …

麒麟信安组织开展国产操作系统技术赋能专题培训

近日&#xff0c;为学习国产操作系统基本概念、使用与运维知识&#xff0c;应对用户单位内部信息系统国产化需求&#xff0c;来自国营洛阳丹城无线电厂的运维工程师们走进麒麟信安&#xff0c;进行了为期一周的操作系统课程学习。 针对客户此次培训需求&#xff0c;结合学员实…

uni-app:canvas-图形实现1

效果 代码 <template><view><!-- 创建了一个宽度为300像素&#xff0c;高度为200像素的canvas元素。canvas-id属性被设置为"firstCanvas"&#xff0c;可以用来在JavaScript中获取该canvas元素的上下文对象。 --><canvas style"width:200p…

nodejs+vue电影网站elementui

第3章 系统分析 5 3.1 需求分析 5 3.2 系统可行性分析 5 3.2.1技术可行性&#xff1a;技术背景 5 3.2.2经济可行性 6 3.2.3操作可行性&#xff1a; 6 3.3 项目设计目标与原则 6 3.4系统流程分析 7 3.4.1操作流程 7 3.4.2添加信息流程 8 3.4.3删除信息流程 9 第4章 系统设计 11 …

助力古彝文保护,AI文字识别技术推动文化传承

文章目录 一、写在前面古彝文为何物&#xff1f;古彝文的保护背景 二、古彝文识别有何难点&#xff1f;如何解决&#xff1f;三、合合信息的强劲技术四、古文识别的重要意义 一、写在前面 古彝文为何物&#xff1f; 彝文指的是云南、贵州、四川等地的彝族人使用的文字&#x…

【Java 进阶篇】MySQL外键约束详解

在数据库设计和管理中&#xff0c;外键约束是一项重要的功能&#xff0c;它用于维护表与表之间的关联关系&#xff0c;保证数据的完整性和一致性。本文将详细介绍MySQL外键约束的概念、用法以及一些最佳实践&#xff0c;以帮助您更好地理解和应用外键约束。 1. 什么是外键约束…

使用领域引导图卷积神经网络GCNN增强基于脑电图EEG的神经疾病诊断完整代码

一种基于图卷积神经网络&#xff08;GCNN&#xff09;的新方法&#xff0c;用于改进使用头皮脑电图&#xff08;EEG&#xff09;进行神经系统疾病诊断。尽管脑电图是神经系统疾病诊断中主要使用的检测方法之一&#xff0c;但基于EEG的专家视觉诊断的敏感性仍然只有约50&#xf…

ubuntu18.04 OpenGL开发(显示YUV)

源码参考&#xff1a;https://download.csdn.net/download/weixin_55163060/88382816 安装opengl库 sudo apt install libglu1-mesa-dev freeglut3-dev mesa-common-dev 安装opengl工具包 sudo apt install mesa-utils 检查opengl版本信息&#xff08;桌面终端执行&#xff09…

JVM机制理解与调优方案

作者&#xff1a;逍遥Sean 简介&#xff1a;一个主修Java的Web网站\游戏服务器后端开发者 主页&#xff1a;https://blog.csdn.net/Ureliable 觉得博主文章不错的话&#xff0c;可以三连支持一下~ 如有需要我的支持&#xff0c;请私信或评论留言&#xff01; 前言 很多Java开发…

更直观地学习 Git 命令

theme: condensed-night-purple 前言 本文参考于 Learn Git Branching 这个有趣的 Git 学习网站。 在该网站&#xff0c;可以使用 show command 命令展示所有可用命令。 你也可以直接访问网站的sandbox&#xff0c;自由发挥。 本地篇 基础篇 git commit git commit将暂…

Matlab随机数的产生

1、常见分布随机数的产生 1.1 二项分布 在贝努力试验中&#xff0c;某事件A发生的概率为p&#xff0c;重复该实验n次&#xff0c;X表示这n次实验中A发生的次数&#xff0c;则随机变量X服从的概率分布律&#xff08;概率密度&#xff09;为 记为 binopdf(x,n,p) p…

BiMPM实战文本匹配【下】

引言 这是BiMPM实战文本匹配的第二篇文章。 注意力匹配 如上图所示&#xff0c;首先计算每个正向(或反向)上下文嵌入 h i p → \overset{\rightarrow}{\pmb h_i^p} hip​→​(或 h i p ← \overset{\leftarrow}{\pmb h_i^p} hip​←​)与另一句的每个正向(或反向)上下文嵌入 …

MQTT协议是什么?快速了解MQTT协议在物联网中的应用

随着工业互联网的迅猛发展&#xff0c;工业设备数据采集和实时监控成为制造业提高生产效率和质量的重要手段。在物联网应用中&#xff0c;通信技术包括Wi-Fi、RFID、NFC、RS232、RS485、USB等&#xff0c;其中在物联网技术框架体系中所使用到的通讯协议主要有&#xff1a;AMQP、…