裂缝检测day3(新增gradio)
本文介绍了基于Gradio框架实现的AI裂缝检测Web系统。系统通过OpenCV进行图像处理,包括灰度转换、高斯模糊、边缘检测、自适应阈值和形态学操作等步骤,最终输出裂缝轮廓图并计算裂缝长度和宽度。采用Gradio.Block模式构建交互界面,包含图片上传、检测按钮、结果显示和检测报告等功能模块。系统实现了从本地PyCharm环境到Web端的迁移,提供了更直观的可视化检测体验。文章详细介绍了Gra
(一)开头
在之前我们学过了图像读取、图像显示、图像预处理、了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)


更多推荐



所有评论(0)