(一)开头

        在之前我们学过了图像读取、图像显示、图像预处理、了OpenCV 裂缝检测核心功能以及学习过自适应阈值和形态学操作优化。这些已经完成了检测的基本功能,今天我们将其包装成网页形式(gradio),使其可以通过链接进行可视化,从pycharm上移动到web,更加直观,也更加吸引人。

        在本文引入前,为了加深我的理解,我们先来介绍一下gradio。gradio是一款python轻量级web框架,并且他有俩种核心模式:(1)gradio.Block ,他是一种较复杂的方式,但是可以进行页面设计,也就是简单的排版(2)gradio.Interferce,他就是较为简单了,更容易上手,但是呢我并没有用到这个,目前也就不太了解,不过我相信一定比Block还要简单。gradio有几个常用的组件:(1)gradio.Markdown,顾名思义,笔记嘛,也就是标题了,在页面中可以看到你的这个标题(2)gradio.Textbox,这个呢,就是有俩个功能了,一个输入,一个输出,它主要是用来输出结果的,比如说检测报告(3)gradio.Row,这个是排版,按照横屏排放,主要是安插这些组件的,与with一起用(4)gradio.Column,这个是竖屏排放(5)gradio.Image,图片,输入输出图片都要用到(6)gradio.Button,按钮,操作按钮,这里不再过多解释。

(二)gradio环境安装

          安装命令:pip install gradio opencv-python numpy

           国内镜像安装加速器:pip install -i https://pypi.tuna.tsinghua.edu.cn/simple gradio opencv-python numpy

       

(三)gradio核心代码介绍

        那我们先来看一下这部分的关键代码吧。可以看到,我们开头使用到with gr.Blocks(title = ....) as demo 在这里呢,我们首先是选择了俩种核心模式的一种,Blocks,方便我们后续排版页面,title就是标题嘛,给他起的名字,demo是这个容器的名字。

  • with 语句:Python 的上下文管理器,自动处理打开/关闭。

                                            

紧接着我们可以看到 input_img = gr.Image(label = "...." , type = "numpy") ,这里主要介绍后半部分:

type="numpy" 上传后转成 NumPy 数组 因为OpenCV 处理需要 NumPy 格式

variant = "primary" :表示高亮颜色,这里我补充几种:

                           

最重要的一部分,被称之为灵魂:detect_btn.click():

                                   

# ============ 创建界面 ============
with gr.Blocks(title = "AI裂缝检测系统") as demo:
    gr.Markdown("AI裂缝检测系统")
    gr.Markdown("上传裂缝照片,自动检测裂并计算长度、宽度")

    with gr.Row():
        with gr.Column():
            input_img = gr.Image(label = "上传裂缝图片" , type = "numpy")
            detect_btn = gr.Button("开始检测" , variant = "primary")

        with gr.Column():
            output_img = gr.Image(label = "检测结果")
            output_text = gr.Textbox(label = "检测报告" , lines = 10)

    detect_btn.click(
        fn = detect_crack,
        inputs = input_img,
        outputs = [output_img , output_text]
    )

    gr.Markdown("====")
    gr.Markdown(
        "作者 : 棒 棒 | 学校 : 索菲亚大学 | Github : [crack-detector](https://github.com/12345678875/crack-detector)"
    )

这里呢是我让AI制作的一张整体代码流程图,方便大家理解。

                                                

(四)裂缝检测代码

        这里的内容已经在前俩章介绍过,不再过多解释。主要还是先检测图片,然后进行灰、高、边缘化、自适应、形态,得到图片裂缝轮廓图,进行计算以及展示。

# # ============ 裂缝检测函数 ============
def detect_crack(image):
    if image is None:
        return None,"wrong , can not read the picture"

#gray->blurred->adaptive->kernel->close

    gray = cv2.cvtColor(image , cv2.COLOR_BGR2GRAY)

    blurred = cv2.GaussianBlur(gray , (5 , 5) , 0)

    edges = cv2.Canny(blurred , 80 , 200)


    adaptive = cv2.adaptiveThreshold(
        edges , 255,
        cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
        cv2.THRESH_BINARY_INV,
        ADAPTIVE_BLOCK_SIZE,
        ADAPTIVE_C
    )

#=========形态学操作这里还是有点不太熟======
    kernel = np.ones((MORPH_KERNEL_SIZE , MORPH_KERNEL_SIZE ), np.uint8)
    closed = cv2.morphologyEx(adaptive , cv2.MORPH_CLOSE, kernel , iterations = MORPH_ITERATIONS)

    contours , _ = cv2.findContours(closed , cv2.RETR_EXTERNAL , cv2.CHAIN_APPROX_SIMPLE)

##========计算+画图========
    img_copy = image.copy()
    crack_count = 0
    report_lines = []

    for i , contour in enumerate(contours):
        area = cv2.contourArea(contour)

        if area > MIN_AREA:
            length = cv2.arcLength(contour , True)
            length_mm = length / PIXELS_PER_MM
            width = area / (length / 2)
            width_mm = width / PIXELS_PER_MM

            report_lines.append(f"裂缝{crack_count}: 长度={length_mm:.2f}mm, 宽度={width_mm:.2f}mm")
            #画轮廓
            cv2.drawContours(img_copy , [contour] , -1 ,(0 , 255 , 0) , 2)

            crack_count += 1

    if crack_count == 0:
        report = "未检测到有效裂缝(面积 < 100 像素²)"
    else:
        report = f"共检测到 {crack_count} 条裂缝"


        report += " ".join(report_lines)

        report += f"\n检测时间:{datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"
        report += f"标定参数:{PIXELS_PER_MM}像素 / mm(需根据实际标定调整)"
        return img_copy,report

(五)总体代码

import gradio as gr
import cv2
import numpy as np
import datetime
import os

# # ============ 配置参数 ============
PIXELS_PER_MM = 12
MIN_AREA = 100
ADAPTIVE_BLOCK_SIZE = 11
ADAPTIVE_C = 2
MORPH_KERNEL_SIZE = 3
MORPH_ITERATIONS = 5


# # ============ 裂缝检测函数 ============
def detect_crack(image):
    if image is None:
        return None,"wrong , can not read the picture"

#gray->blurred->adaptive->kernel->close

    gray = cv2.cvtColor(image , cv2.COLOR_BGR2GRAY)

    blurred = cv2.GaussianBlur(gray , (5 , 5) , 0)

    edges = cv2.Canny(blurred , 80 , 200)


    adaptive = cv2.adaptiveThreshold(
        edges , 255,
        cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
        cv2.THRESH_BINARY_INV,
        ADAPTIVE_BLOCK_SIZE,
        ADAPTIVE_C
    )

#=========形态学操作这里还是有点不太熟======
    kernel = np.ones((MORPH_KERNEL_SIZE , MORPH_KERNEL_SIZE ), np.uint8)
    closed = cv2.morphologyEx(adaptive , cv2.MORPH_CLOSE, kernel , iterations = MORPH_ITERATIONS)

    contours , _ = cv2.findContours(closed , cv2.RETR_EXTERNAL , cv2.CHAIN_APPROX_SIMPLE)

##========计算+画图========
    img_copy = image.copy()
    crack_count = 0
    report_lines = []

    for i , contour in enumerate(contours):
        area = cv2.contourArea(contour)

        if area > MIN_AREA:
            length = cv2.arcLength(contour , True)
            length_mm = length / PIXELS_PER_MM
            width = area / (length / 2)
            width_mm = width / PIXELS_PER_MM

            report_lines.append(f"裂缝{crack_count}: 长度={length_mm:.2f}mm, 宽度={width_mm:.2f}mm")
            #画轮廓
            cv2.drawContours(img_copy , [contour] , -1 ,(0 , 255 , 0) , 2)

            crack_count += 1

    if crack_count == 0:
        report = "未检测到有效裂缝(面积 < 100 像素²)"
    else:
        report = f"共检测到 {crack_count} 条裂缝"


        report += " ".join(report_lines)

        report += f"\n检测时间:{datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"
        report += f"标定参数:{PIXELS_PER_MM}像素 / mm(需根据实际标定调整)"
        return img_copy,report

# ============ 创建界面 ============
with gr.Blocks(title = "AI裂缝检测系统") as demo:
    gr.Markdown("AI裂缝检测系统")
    gr.Markdown("上传裂缝照片,自动检测裂并计算长度、宽度")

    with gr.Row():
        with gr.Column():
            input_img = gr.Image(label = "上传裂缝图片" , type = "numpy")
            detect_btn = gr.Button("开始检测" , variant = "primary")

        with gr.Column():
            output_img = gr.Image(label = "检测结果")
            output_text = gr.Textbox(label = "检测报告" , lines = 10)

    detect_btn.click(
        fn = detect_crack,
        inputs = input_img,
        outputs = [output_img , output_text]
    )

    gr.Markdown("====")
    gr.Markdown(
        "作者 : 棒 棒 | 学校 : 索菲亚大学 | Github : [crack-detector](https://github.com/12345678875/crack-detector)"
    )

# ============ 启动应用 ============
if __name__ == "__main__":
    demo.launch()

(六)运行结果展示(http://127.0.0.1:7860

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐