基于Segformer实现PCB缺陷检测(步骤 + 代码)

导  读

    本文主要介绍基于Segformer实现PCB缺陷检测 ,并给出步骤和代码。    

背景介绍

图片

    PCB缺陷检测是电子制造的一个重要方面。利用Segformer等先进模型不仅可以提高准确性,还可以大大减少检测时间。传统方法涉及手动检查,无法扩展且容易出错。利用机器学习,特别是 Segformer模型,提供自动化且精确的解决方案。

      

实现步骤

    下面是具体步骤: 

  【1】安装所需环境。首先,我们安装所需的库。其中,albumentations用于数据增强,transformers允许访问 Segformer等预训练模型,并xmltodict帮助解析数据集的XML注释。

pip install evaluate albumentations transformers accelerate xmltodict

  【2】数据集。这个项目中使用的数据集由Roboflow提供。可以从下面链接获取:

https://universe.roboflow.com/diplom-qz7q6/defects-2q87r/dataset/16

图片

该数据集分为测试文件夹和训练文件夹,由XML格式的图像及其相应注释组成。

# Create train and test setstrain_folder = "drive/..../train/images/"test_folder = "drive/.../validation/images/"
train_img_paths = sorted([train_folder + f for f in os.listdir(train_folder) if f.endswith("jpg")])test_img_paths = sorted([test_folder + f for f in os.listdir(test_folder) if f.endswith("jpg")])train_xml_paths = [f[:-3] + "xml" for f in train_img_paths]test_xml_paths = [f[:-3] + "xml" for f in test_img_paths]
train_ds = {"image_paths": train_img_paths, "xml_paths": train_xml_paths}test_ds = {"image_paths": test_img_paths, "xml_paths": test_xml_paths}

    XML文件包含多边形标注信息,指示PCB图像上缺陷的位置。该函数process_mask读取XML标注信息并将其转换为掩码(类似图像的数组)。该掩模对应于PCB图像上的缺陷区域,基本上将缺陷与电路板的其余部分分开。

    该函数首先使用OpenCV读取原始图像。在我们初始化与输入图像大小相同的蒙版之后。根据可视化标志,蒙版可以是3通道RGB蒙版(如彩色图像)或1通道灰度蒙版。最初,该掩码中的所有值都设置为零,这意味着没有缺陷。

  【3】缺陷标注解析。对于每个缺陷标注信息:识别缺陷类型,提取缺陷的多边形形状,该多边形被绘制到初始化的蒙版上。最后,该函数弥合了XML标注信息和适合训练的格式之间的差距。给定 PCB图像及其相应的XML 注释,它会生成一个分割掩模,突出显示有缺陷的区域。掩模可以是适合训练模型的数字格式,也可以是用于人工检查的视觉格式。​​​​​​​

def process_mask(img_path, xml_path, visualize=False):    img = cv2.imread(img_path)    num_dim = 3 if visualize else 1    mask = np.zeros((img.shape[0], img.shape[1], num_dim))
    # Read xml content from the file    with open(xml_path, "r") as file:      xml_content = file.read()
    data = xmltodict.parse(xml_content)
    # If has defect mask    if "object" in data["annotation"]:        objects = data["annotation"]["object"]
        # Single defects are annotated as a single dict, not a list        if not isinstance(objects, List):          objects = [objects]
        for obj in objects:          defect_type = obj["name"]          polygon = obj["polygon"]          poly_keys = list(polygon.keys())
          # Get number of (x, y) pairs - polygon coords          poly_keys = [int(k[1:]) for k in poly_keys]          num_poly_points = max(poly_keys)
          # Parse ordered polygon coordinates          poly_coords = []          for i in range(1, num_poly_points+1):              poly_coords.append([                  int(float(polygon[f"x{i}"])),                  int(float(polygon[f"y{i}"]))              ])          poly_coords = np.array(poly_coords)
          # Draw defect segment on mask          fill_color = color_map[defect_type] if visualize else id_cat_map[defect_type]          mask = cv2.fillPoly(mask, pts=[poly_coords], color=fill_color)
    #Optional    if visualize:        cv2.imwrite("output.jpg", mask)        mask = Image.open("output.jpg")
    return mask

  【4】探索性数据分析。在训练模型之前,最好先了解数据。在这里,我们检查缺陷类型的分布并在样本图像上可视化缺陷。

图片

图片

图片

图片

    缺陷热力图显示了常见的缺陷位置,箱线图显示了缺陷尺寸的分布。

图片

    该函数旨在通过读取边界框详细信息来计算 XML 注释中存在的每个缺陷的大小。

def get_defect_sizes(xml_paths):    sizes = []    for xml_path in xml_paths:        with open(xml_path) as f:            data = xmltodict.parse(f.read())            objects = []            if 'object' in data['annotation']:                objects = data['annotation']['object']            if not isinstance(objects, list):                objects = [objects]            for obj in objects:                bndbox = obj['bndbox']                width = int(bndbox['xmax']) - int(bndbox['xmin'])                height = int(bndbox['ymax']) - int(bndbox['ymin'])                sizes.append(width * height)    return sizes

    最后,群图重点关注缺陷尺寸在整个数据集中的分布和扩散。

图片

  【5】数据增强。该albumentations库用于人为扩展训练数据集,有助于提高模型的泛化能力。唯一指定的增强是水平翻转,它将以 50% 的概率水平翻转图像。​​​​​​​

transform = A.Compose([    A.HorizontalFlip(p=0.5)])

图片

 【6】图像预处理。将图像及其掩模预处理为适合Segformer模型的格式。

preprocessor = SegformerImageProcessor()

    我们将定义一个继承自PyTorchDataset类的自定义数据集类。这个自定义数据集允许我加载和预处理 PCB 图像及其相应的缺陷掩模。

    使用 OpenCV 加载图像。使用前面讨论的函数生成缺陷掩模process_mask。使用之前初始化的图像预处理图像及其掩模SegformerImageProcessor。此步骤将图像转换为张量格式,并确保它们具有适合 Segformer 模型的大小和标准化。返回预处理的图像和掩模张量。​​​​​​​

class DefectSegmentationDataset(Dataset):  def __init__(self, dataset, mode):    self.image_paths = dataset["image_paths"]    self.xml_paths = dataset["xml_paths"]
  def __len__(self):    return len(self.image_paths)
  def __getitem__(self, idx):    # Read image    image = cv2.imread(self.image_paths[idx])
    # Get mask    mask = process_mask(self.image_paths[idx], self.xml_paths[idx])    mask = mask.squeeze()    mask = Image.fromarray(mask.astype("uint8"), "L")
    # Return preprocessed inputs    inputs = preprocessor(image, mask, ignore_index=None, return_tensors="pt")    inputs["pixel_values"] = inputs["pixel_values"].squeeze(0)    inputs["labels"] = inputs["labels"].squeeze(0)    return inputs

图片

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

k8s---声明式资源管理(yml文件)

在k8s当中支持两种声明资源的方式: 1、 yaml格式:主要用于和管理资源对象 2、 json格式:主要用于在API接口之间进行消息传递 声明式管理方法(yaml)文件 1、 适合对资源的修改操作 2、 声明式管理依赖于yaml文件,所有的内容都在y…

webapp下没有蓝点解决

解决方法: File->Project Structure 现在就是一个JavaWeb项目了。

WMS仓储管理系统如何优化急料处理流程

在当今快速发展的商业环境中,企业的运营效率和供应链管理面临着前所未有的挑战。尤其在面对急料处理这一环节时,许多企业都感到力不从心。为了满足生产线的连续运作、确保客户订单的及时交付,WMS仓储管理系统的急料处理流程优化成为了关键。本…

(17)Linux的进程阻塞进程程序替换 exec 函数簇

前言:本章我们讲解它的 options 参数。在讲解之前我们需要理解进程阻塞,然后我们重点讲解二进程程序替换,这是本章的重点,然后介绍一个进程替换函数 execl,通过介绍这个函数来打开突破口,引入进程创建的知识…

【解决复杂链式任务,打造全能助手】LangChain 大模型 打造 钢铁侠的全能助理 Jarvis

LangChain 大模型 结合 做 AutoGPT、ChatPDF 思维链 CoTLangChain模型IO:和大模型交互、提示词模版数据连接:从数据的接入、分割,到向量的构建、存储、搜索链:串联和组织,多个语言模型、组件记忆:灵魂伴侣&…

C#中使用 async await TaskCompletionSource<T>实现异步逻辑同步写

Task、async 和 await 是 C# 中用于处理异步编程的关键概念。它们一起构成了异步编程的基础。 Task Task 是表示异步操作的抽象,它属于 System.Threading.Tasks 命名空间。Task 可以表示已经完成的任务、正在运行的任务或者尚未开始的任务。通过 Task,…

算法导论复习——CHP16 贪心算法

定义 每一步都做出当前看来最优的操作。 问题引入——活动选择问题 问题描述 活动选择问题就是对给定的包含n个活动的集合S,在已知每个活动开始时间和结束时间的条件下,从中选出最多可兼容活动的子集合,称为最大兼容活动集合。 不失一般性&a…

【C++入门】C++内存管理

目录 前言 C/C内存分布 C内存管理方式 1. new和delete操作内置类型 快速了解与使用 2. new和delete操作自定义类型 3. operator new与operator delete 4. operator new [ ] *5.定位new 6. malloc/free和new/delete的区别 总结 前言 C作为一种面向对象的编程语言&#xff…

AI:110-基于深度学习的药物分子结构生成与预测

🚀点击这里跳转到本专栏,可查阅专栏顶置最新的指南宝典~ 🎉🎊🎉 你的技术旅程将在这里启航! 从基础到实践,深入学习。无论你是初学者还是经验丰富的老手,对于本专栏案例和项目实践都有参考学习意义。 ✨✨✨ 每一个案例都附带有在本地跑过的关键代码,详细讲解供…

Unity ab包如何加密

「ab包」全称为 AssetBundle ,是Unity提供的一种资源存储压缩包。其中储存了游戏的资源,如图片、模型、纹理、音视频、代码等文件。 由于ab包具有灵活储存、支持热更、包体较小且便于管理等优势,已经成为了市面上主流的游戏资源压缩方式。 …

Jmeter(七) - 从入门到精通 - 建立数据库测试计划实战<MySQL数据库>(详解教程)

1.简介 在实际工作中,我们经常会听到数据库的性能和稳定性等等,这些有时候也需要测试工程师去评估和测试,上一篇文章宏哥主要介绍了jmeter连接和创建数据库测试计划的过程,宏哥在文中通过示例和代码非常详细地介绍给大家,希望对各…

【中小型企业网络实战案例 七】配置限速

相关学习文章: 【中小型企业网络实战案例 一】规划、需求和基本配置 【中小型企业网络实战案例 二】配置网络互连互通【中小型企业网络实战案例 三】配置DHCP动态分配地址 【中小型企业网络实战案例 四】配置OSPF动态路由协议【中小型企业网络实战案例 五】配置可…

51单片机(STC8)-- GPIO输入输出

文章目录 I/O口相关寄存器端口数据寄存器端口模式配置寄存器(PxM0,PxM1)端口上拉电阻控制寄存器(PxPU)关于I/O的注意事项 配置I/O口I/O设置demoI/O端口模式LED控制(I/O输出)按键检测(I/O输入) S…

【模拟量采集1.2】电阻信号采集

【模拟量采集1.2】电阻信号采集 1 怎么测?2 测输入电阻电压即转为测模拟电压值,这里需要考虑选用怎样的辅助电阻?3 实际电路分析3.1 在不考虑 VCC-5V 电压的纹波等情况时(理想化此时输入的 VCC 就是稳定的 5V)3.2 若考…

拖拽式工作流好用吗?有何特点?

大家都知道,随着行业的进步和发展,低代码技术平台也迎来了蓬勃发展期。很多企业喜欢使用低代码实现提质增效的办公效果,拖拽式工作流是其中一个功能,是助力企业实现流程化办公的得力助手。那么,拖拽式工作流好用吗&…

robots.txt

####什么是robots.txt? ​ robots.txt是一个协议,我们可以把它理解为一个网站的"管家",它会告诉搜索引擎哪些页面可以访问,哪些页面不能访问。也可以规定哪些搜索引擎可以访问我们的网站而哪些搜索引擎不能爬取我们网站的信息等等,是网站管理者指定的"君子协议…

FMQL BOOT.bin固化文件生成及固化流程记录

FMQL BOOT.bin固化文件生成及固化流程记录 一、概述 此篇记录上海复旦微JFMQL15T开发板 烧录固化文件BOOT.bin生成及固化操作流程。 以上一篇文章FQML_AXI_GPIO工程构建调试记录 中的工程为基础,做更改。 二、vivado工程配置 2.1新建工程 打开FQML_AXI_GPIO工程…

Unity | Shader基础知识番外(向量数学知识速成)

目录 一、向量定义 二、计算向量 三、向量的加法(连续行走) 四、向量的长度 五、单位向量 六、向量的点积 1 计算 2 作用 七、向量的叉乘 1 承上启下 2 叉乘结论 3 叉乘的计算(这里看不懂就百度叉乘计算) 八、欢迎收…

视频号小店全新赛道,新手如何入驻?

我是电商珠珠 视频号小店为视频号团队所研发。距今为止也才发展了一年时间,在23年下半年掀起了不小的浪花。 我做视频号小店也有一年时间了,在他刚开始三个月的时候,就开始带着团队一起做。到现在也拥有了自己的视频号小店运营团队&#xf…