python基于DeeplabV3Plus开发构建手机屏幕表面缺陷图像分割识别系统

Deeplab是图像分割领域非常强大的模型,在前面的博文中我们也进行过很多相应项目的开发实践,感兴趣的话可以自行移步阅读即可:

《基于DeepLabv3Plus开发构建人脸人像分割系统》

《基于DeepLabV3实践路面、桥梁、基建裂缝裂痕分割》

《基于DeepLabV3Plus实现质检划痕图像分割识别系统》

《基于DeepLabV3Plus实现无人机航拍目标分割识别系统》

《python基于DeepLabv3+开发构建河道分割识别系统》

《基于DeepLabV3Plus实现焊缝分割识别系统》

《python基于DeeplabV3Plus开发构建裂缝分割识别系统,并实现裂缝宽度计算测量》

 《AI助力隧道等洞体类场景下水泥基建缺陷检测,基于DeeplabV3Plus开发构建洞体场景下壁体建筑缺陷分割系统》

本文的核心目的就是想要基于DeepLabV3Plus来开发构建手机屏幕表面缺陷图像智能分割识别系统,助力工业生产流程上的智能化,首先看下实例效果:

在图像分割领域中有不少优秀出色的网络,DeepLab系列就是其中非常经典的分支之一,在之前的很多项目中陆续都已经有接触到了,在处理图像分割中表现出色。

DeepLabV3Plus是一种用于语义分割任务的深度学习模型,它是DeepLab系列模型的一种改进版本。下面详细解释DeepLabV3Plus的原理:

引入空洞卷积(Dilated Convolution):DeepLabV3Plus利用空洞卷积来扩大感受野,以更好地捕捉图像中的上下文信息。传统的卷积操作只关注局部区域,而空洞卷积通过在卷积核中引入间隔(或称为膨胀率),使得卷积核能够跳过一些像素点,从而扩大感受野。

多尺度金字塔池化(Multi-scale Atrous Spatial Pyramid Pooling, ASPP):DeepLabV3Plus使用ASPP模块来处理不同尺度的信息。ASPP模块使用多个并行的空洞卷积分支,每个分支具有不同的膨胀率,以捕捉来自不同感受野的特征。最后,将这些特征进行汇总并进行融合,以生成更丰富的特征表示。

融合低级特征:为了结合低层次的细节特征,DeepLabV3Plus引入了一个编码器-解码器结构。在编码器部分,通过堆叠多个残差块和降采样操作,提取高层次的语义特征。然而,这会导致空间信息的丢失。因此,在解码器部分,使用反卷积(或上采样)操作来恢复特征图的分辨率,并与对应的低级特征进行融合。

融合注意力机制:为了进一步提升融合的效果,DeepLabV3Plus引入了注意力机制。该机制利用辅助监督信号和空间注意力模块,自适应地对不同的特征图进行加权融合。这样可以使网络更加关注重要的特征区域,提升语义分割的准确性。

DeepLabV3Plus通过引入空洞卷积、多尺度金字塔池化、融合低级特征和注意力机制等改进,提升了语义分割任务的性能。它能够准确地标记图像中每个像素的类别,从而在许多计算机视觉领域(如图像分割、自动驾驶等)中发挥着重要作用。

整体网络结构图如下所示:

接下来看下数据集:

共包含:油污、划痕和斑点这三种常见的手机屏幕缺损类型。

DeepLabV3Plus核心实现如下:

import tensorflow as tf
from keras import backend as K
from keras.layers import (Activation,BatchNormalization,Concatenate,Conv2D,DepthwiseConv2D,Dropout,GlobalAveragePooling2D,Input,Lambda,Softmax,ZeroPadding2D,
)
from keras.models import Model
from modules.mobilenet import mobilenetV2
from modules.Xception import Xceptiondef SepConv_BN(x,filters,prefix,stride=1,kernel_size=3,rate=1,depth_activation=False,epsilon=1e-3,
):if stride == 1:depth_padding = "same"else:kernel_size_effective = kernel_size + (kernel_size - 1) * (rate - 1)pad_total = kernel_size_effective - 1pad_beg = pad_total // 2pad_end = pad_total - pad_begx = ZeroPadding2D((pad_beg, pad_end))(x)depth_padding = "valid"if not depth_activation:x = Activation("relu")(x)x = DepthwiseConv2D((kernel_size, kernel_size),strides=(stride, stride),dilation_rate=(rate, rate),padding=depth_padding,use_bias=False,)(x)x = BatchNormalization(epsilon=epsilon)(x)if depth_activation:x = Activation("relu")(x)x = Conv2D(filters, (1, 1), padding="same", use_bias=False)(x)x = BatchNormalization(epsilon=epsilon)(x)if depth_activation:x = Activation("relu")(x)return xdef Deeplabv3(input_shape, num_classes, alpha=1.0, backbone="mobilenet", downsample_factor=16
):img_input = Input(shape=input_shape)x, atrous_rates, skip1 = MobileNet(img_input, alpha, downsample_factor=downsample_factor)size_before = tf.keras.backend.int_shape(x)b0 = Conv2D(256, (1, 1), padding="same", use_bias=False)(x)b0 = BatchNormalization(epsilon=1e-5)(b0)b0 = Activation("relu")(b0)b1 = SepConv_BN(x, 256, "A!", rate=atrous_rates[0], depth_activation=True, epsilon=1e-5)b2 = SepConv_BN(x, 256, "A2", rate=atrous_rates[1], depth_activation=True, epsilon=1e-5)b3 = SepConv_BN(x, 256, "A3", rate=atrous_rates[2], depth_activation=True, epsilon=1e-5)b4 = GlobalAveragePooling2D()(x)b4 = Lambda(lambda x: K.expand_dims(x, 1))(b4)b4 = Lambda(lambda x: K.expand_dims(x, 1))(b4)b4 = Conv2D(256, (1, 1), padding="same", use_bias=False)(b4)b4 = BatchNormalization(epsilon=1e-5)(b4)b4 = Activation("relu")(b4)b4 = Lambda(lambda x: tf.image.resize_images(x, size_before[1:3], align_corners=True))(b4)x = Concatenate()([b4, b0, b1, b2, b3])x = Conv2D(256, (1, 1), padding="same", use_bias=False)(x)x = BatchNormalization(epsilon=1e-5)(x)x = Activation("relu")(x)x = Dropout(0.1)(x)skip_size = tf.keras.backend.int_shape(skip1)x = Lambda(lambda xx: tf.image.resize_images(xx, skip_size[1:3], align_corners=True))(x)dec_skip1 = Conv2D(48, (1, 1), padding="same", use_bias=False)(skip1)dec_skip1 = BatchNormalization(epsilon=1e-5)(dec_skip1)dec_skip1 = Activation(tf.nn.relu)(dec_skip1)x = Concatenate()([x, dec_skip1])x = SepConv_BN(x, 256, "DC0", depth_activation=True, epsilon=1e-5)x = SepConv_BN(x, 256, "DC1", depth_activation=True, epsilon=1e-5)size_before3 = tf.keras.backend.int_shape(img_input)x = Conv2D(num_classes, (1, 1), padding="same")(x)x = Lambda(lambda xx: tf.image.resize_images(xx, size_before3[1:3], align_corners=True))(x)x = Softmax()(x)model = Model(img_input, x)return model

基于轻量级的MobileNet作为骨干网络来实现特征的提取,即使是在算力较弱的设备下也可以完成训练。在自己的项目中也可以直接整合集成使用。

训练完成后对整体进行可视化,核心实现如下:

from matplotlib import pyplot as pltwith open("train.txt") as f:train_list = [float(one) for one in f.readlines() if one.strip()]
with open("val.txt") as f:val_list = [float(one) for one in f.readlines() if one.strip()]
print("train_list_length: ", len(train_list))
print("val_list_length: ", len(val_list))plt.clf()
plt.figure(figsize=(8, 6))
plt.plot(train_list, label="Train Loss Cruve", c="g")
plt.plot(val_list, label="Val Loss Cruve", c="b")
plt.title("Model Loss Cruve")
plt.savefig("loss.png")

结果如下所示:

这里分为两个阶段进行训练,首先是冷冻训练,主要是基于预训练权重来进行训练,如下:

这一阶段大部分参数被冻结,模型的整体损失比较高,完成预热之后解冻模型参数开启全量训练,如下所示:

这里为了方便使用模型,开发了专用的可视化系统界面,实例推理计算效果如下所示:

直观来看效果还是不错的,有兴趣的话都是可以自己动手实践一下的。

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

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

相关文章

【链表Linked List】力扣-203 移除链表元素

目录 题目描述 解题过程 题目描述 给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val val 的节点,并返回 新的头节点 。 示例 1: 输入:head [1,2,6,3,4,5,6], val 6 输出:[1,2,3,4,5…

快速学会绘制Pyqt5中的所有图(下)

Pyqt5相关文章: 快速掌握Pyqt5的三种主窗口 快速掌握Pyqt5的2种弹簧 快速掌握Pyqt5的5种布局 快速弄懂Pyqt5的5种项目视图(Item View) 快速弄懂Pyqt5的4种项目部件(Item Widget) 快速掌握Pyqt5的6种按钮 快速掌握Pyqt5的10种容器&…

鸿蒙原生应用开发——分布式数据对象

01、什么是分布式数据对象 在可信组网环境下,多个相互组网认证的设备将各自创建的对象加入同一个 sessionId,使得加入的多个数据对象之间可以同步数据,也就是说,当某一数据对象属性发生变更时,其他数据对象会检测到这…

让聪明的车连接智慧的路,C-V2X开启智慧出行生活

“聪明的车 智慧的路”形容的便是车路协同的智慧交通系统,从具备无钥匙启动,智能辅助驾驶和丰富娱乐影音功能的智能网联汽车,到园区的无人快递配送车,和开放的城市道路上自动驾驶的公交车、出租车,越来越多的车联网应用…

thinkphp lists todo

来由: 数据库的这个字段我想返回成: 新奇的写法如下: 逻辑层的代码: public function goodsDetail($goodId){$detail $this->good->where(id, $goodId)->hidden([type_params,user_id])->find();if (!$detail) {ret…

如何使用PostMan进行并发测试?

如何使用PostMan进行并发测试? 👀(Postman 的 runner 实际上是串行执行的,因此不能作为并发测试, 只是批量测试,本文如下称为并发的是错误的) 文章目录 如何使用PostMan进行并发测试?POST篇流程Pre-req 脚…

Conda常用命令总结

使用conda或anaconda的小伙伴们都知道,图形界面时不靠谱的,而在命令行下,所有的操作就会稳定很多,且极少出现问题。因此,熟记conda的命令行就变得十分有用。但对于我这样近50岁依旧奋斗在代码第一线的大龄程序员而已&a…

拦截 open调用 (进程白名单,文件白名单)

拦截 open 文章目录 拦截 open第一个需求文件结构进程白名单文件白名单 测试代码第一个版本版本二代码演示 增加一个日志记录代码解释 gcc -shared -fPIC -o libintercept.so intercept.c -ldlLD_PRELOAD./libintercept.so ./processA在Linux中,我们可以使用LD_PREL…

12.Mysql 多表数据横向合并和纵向合并

Mysql 函数参考和扩展&#xff1a;Mysql 常用函数和基础查询、 Mysql 官网 Mysql 语法执行顺序如下&#xff0c;一定要清楚&#xff01;&#xff01;&#xff01;运算符相关&#xff0c;可前往 Mysql 基础语法和执行顺序扩展。 (8) select (9) distinct (11)<columns_name…

【力扣热题100】287. 寻找重复数(弗洛伊德的乌龟和兔子方法)

【力扣热题100】287. 寻找重复数 写在最前面理解解决 "寻找重复数" 问题的算法问题描述弗洛伊德的乌龟和兔子方法为什么这个方法有效&#xff1f; 代码复杂度 总结回顾 写在最前面 刷一道力扣热题100吧 难度中等 https://leetcode.cn/problems/find-the-duplicate-…

Java Web应用小案例 - 实现用户登录功能

文章目录 一、使用纯JSP方式实现用户登录功能&#xff08;一&#xff09;项目概述&#xff08;二&#xff09;实现步骤1、创建Web项目2、创建登录页面 二、使用JSPServlet方式实现用户登录功能三、使用JSPServletDB方式实现用户登录功能 一、使用纯JSP方式实现用户登录功能 &a…

ubuntu22.04安装 nvidia-cudnn

nvidia-cudnn 是 NVIDIA CUDA 深度神经网络库&#xff08;CUDA Deep Neural Network library&#xff09;的缩写。这是一个由 NVIDIA 提供的库&#xff0c;用于加速深度学习应用程序。它包含了针对深度神经网络中常用操作&#xff08;如卷积、池化、归一化、激活层等&#xff0…

【Linux】如何清空某个文件的内容

cat /dev/null > file1 清空某个文件的内容使用cat /dev/null > file1&#xff0c;它将 /dev/null 的内容&#xff08;空内容&#xff09;重定向到 file1。 如下所示&#xff0c;file1文件里的内容被清空。 错误写法 错误写法是&#xff1a;cat file1 > /dev/null&…

持续集成交付CICD:CentOS 7 安装 Nexus 3.63

目录 一、实验 1.CentOS 7 安装Nexus3.63 二、问题 1.安装Nexus报错 2.Nexus启动停止相关命令 一、实验 1.CentOS 7 安装Nexus3.63 &#xff08;1&#xff09;当前操作系统版本&JDK版本 cat /etc/redhat-releasejava -version&#xff08;2&#xff09;下载Nexus新…

int 和 Integer 有什么区别,还有 Integer 缓存的实现

✨前言✨   Java本文主要介绍Java int 和 Integer的区别以及Integer 缓存的实现 &#x1f352;欢迎点赞 &#x1f44d; 收藏 ⭐留言评论 &#x1f4dd;私信必回哟&#x1f601; &#x1f352;博主将持续更新学习记录收获&#xff0c;友友们有任何问题可以在评论区留言 文章目…

用C++实现队列顺序结构的基本操作

//队列顺序结构的基本操作&#xff1a; #include"stdio.h" #include"String" #define QueueSize 100 typedef char ElemType; typedef struct { ElemType data[QueueSize]; /*保存队中元素*/int front,rear; /*队头和队尾指针*/ } SqQueue; void Init…

使用STM32定时器实现精确的时间测量和延时

✅作者简介&#xff1a;热爱科研的嵌入式开发者&#xff0c;修心和技术同步精进&#xff0c; 代码获取、问题探讨及文章转载可私信。 ☁ 愿你的生命中有够多的云翳,来造就一个美丽的黄昏。 &#x1f34e;获取更多嵌入式资料可点击链接进群领取&#xff0c;谢谢支持&#xff01;…

大数据技术4:Lambda和Kappa架构区别

前言&#xff1a;在大数据处理领域&#xff0c;两种突出的数据架构已成为处理大量数据的流行选择&#xff1a;Lambda 架构和 Kappa 架构。这些架构为实时处理和批处理提供了强大的技术解决方案&#xff0c;使组织能够从其数据中获得有价值的见解。随着互联网时代来临&#xff0…

Python VSCode 配置固定的脚本入口

Python VSCode 配置固定的脚本入口 打开或者新建一个启动配置 选择 .vscode目录下 launch.json文件 将 “program”: “${file}” 替换成 “program”: “mian.py”, //完成你自己的入口.py文件名即可 json启动配置文件 {// Use IntelliSense to learn about possible attrib…

面向对象中的单例模式

1、什么是设计模式 设计模式就是前人根据实际的问题提出的问题解决方案&#xff0c;我们把这种就称之为设计模式。 2、单例模式 单例模式是一种常见的设计模式&#xff01; 所谓的设计模式&#xff0c;不是一种新的语法&#xff0c;而是人们在实际的应用中&#xff0c;面对…