★★★ 本文源自AlStudio社区精品项目,【点击此处】查看更多精品内容 >>>

一、项目背景介绍

钢铁制品在生产过程中常常会出现各种缺陷,例如气泡、夹杂物、裂纹等,这些缺陷不仅会降低产品的质量,还可能导致安全事故。因此,对钢铁表面进行缺陷检测具有重要的意义。传统的钢铁表面缺陷检测方法通常需要大量的人力投入,效率低下且容易出错。而基于机器学习和人工智能技术的自动化检测方法可以显著提高检测效率和准确性。

二、数据处理

2.1、数据集介绍

该数据集是针对钢铁表面的缺陷进行的图像分类任务,由中科院自动化所、清华大学计算机系和视觉智能技术创新研究院联合推出。该数据集包含了1,800张带有缺陷标签的表面瑕疵图片,分为6类:
涂层缺陷气泡缺陷碰撞缺陷裂纹缺陷夹杂缺陷边界缺陷

下图为六种典型表面缺陷的示例,每幅图像的分辨率为200 * 200像素。

每个样本都有一个xml格式的标注文件,其中包含了缺陷类型、位置、大小等信息。该数据集的难点在于缺陷的大小和形状各不相同,有些缺陷非常小,需要细致地观察才能发现。

该数据集可用于训练和评估物体检测图像分类模型,也可以用于研究面向工业生产的图像质量检测问题。此外,该数据集也是CVPR 2019的一个竞赛项目,参与者需要使用该数据集来训练算法,并提交检测结果进行评估。

数据集下载链接:https://www.kaggle.com/c/severstal-steel-defect-detection/data

下图为缺陷检测结果示例。对于每个缺陷,黄色框代表位置的边界框,蓝色标签是类别分数。

解压数据集、下载PaddleDetection

!mkdir /home/aistudio/work/Dataset
!unzip -oq /home/aistudio/data/data169999/test.zip -d /home/aistudio/work/Dataset
!unzip -oq /home/aistudio/data/data169999/train.zip -d /home/aistudio/work/Dataset
!git clone https://gitee.com/paddlepaddle/PaddleDetection.git
%cd PaddleDetection
# 安装其他依赖
! pip install paddledet==2.0.1 -i https://mirror.baidu.com/pypi/simple
! pip install -r requirements.txt -- user

2.2、数据增强

经过对数据集的分析发现,钢铁缺陷数据集中图片的明暗程度各不相同,对于一组明暗程度不同的图片数据集,推荐使用以下几种图像增强方法来增强其质量和多样性:

1、直方图均衡化:直方图均衡化是一种调整图像亮度的方法,它可以增强图像的对比度和细节,使得暗部和亮部的分布更加均匀。这个方法可以用来处理亮度不均匀的图片,使得整个数据集的亮度均匀。

2、对比度增强:对比度增强是通过增加图像中的对比度来增强图像的亮度和清晰度。可以使用基于直方图的对比度增强方法或者基于变换函数的对比度增强方法来增强数据集中的图像。

import os
import numpy as np
import matplotlib.pyplot as plt
import cv2

img_path="/home/aistudio/work/Dataset/train/IMAGES/"
img_src = cv2.imread('/home/aistudio/work/Dataset/train/IMAGES/325.jpg',0) 
#普通直方图均衡
img_dst = cv2.equalizeHist(img_src)
#自适应直方图均衡 
clahe = cv2.createCLAHE(clipLimit=5.0, tileGridSize=(8,8))
img_dst_clahe = clahe.apply(img_src)
 
histSize = 256
histRange = (0, 256) 
hist_src = cv2.calcHist([img_src], [0], None, [histSize], histRange) 
hist_dst = cv2.calcHist([img_dst], [0], None, [histSize], histRange)  
hist_dst_clahe = cv2.calcHist([img_dst_clahe], [0], None, [histSize], histRange) 


fig,ax = plt.subplots(2,3)
ax[0,0].set_title('hist_src')
ax[0,0].plot(hist_src) 
ax[0,1].set_title('hist_dst')
ax[0,1].plot(hist_dst)
ax[0,2].set_title('hist_dst_clahe')
ax[0,2].plot(hist_dst_clahe)
ax[1,0].set_title('img_src')
ax[1,0].imshow(cv2.cvtColor( img_src, cv2.COLOR_BGR2RGB),'gray')
ax[1,1].set_title('img_dst') 
ax[1,1].imshow(cv2.cvtColor(img_dst,cv2.COLOR_BGR2RGB),'gray')  
ax[1,2].set_title('img_dst_clahe') 
ax[1,2].imshow(cv2.cvtColor(img_dst_clahe,cv2.COLOR_BGR2RGB),'gray')  
#ax[0,0].axis('off');ax[0,1].axis('off');
ax[1,0].axis('off');ax[1,1].axis('off');ax[1,2].axis('off')#关闭坐标轴显示
plt.show()  

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AWdT1d8q-1682094126712)(main_files/main_5_0.png)]

普通的直方图均衡化是一种经典的图像增强方法,它可以增强图像的对比度和细节,使得暗部和亮部的分布更加均匀。然而,普通的直方图均衡化存在一些缺点。例如,当图像的局部区域灰度值分布不均匀时,直方图均衡化可能会导致图像出现过度增强和失真的情况。

自适应直方图均衡化(AHE)是一种改进的直方图均衡化方法,它通过将图像分成若干个小的局部区域,然后对每个局部区域进行直方图均衡化,以适应局部灰度值分布的变化。因此,AHE相比于普通的直方图均衡化具有以下优点:

AHE可以避免过度增强和失真的情况。由于AHE是在每个局部区域内进行直方图均衡化,所以可以更好地适应局部灰度值分布的变化,避免出现局部过度增强和失真的情况。

AHE可以增强图像的对比度和细节。与普通的直方图均衡化相比,AHE更能够提高图像的对比度和细节。

AHE适用于复杂场景下的图像增强。对于复杂场景下的图像,例如医学影像、红外图像等,AHE可以更好地适应图像的灰度分布,提高图像质量。

在观察处理过的图片效果后,采用自适应直方图均衡进行数据增强

!mkdir /home/aistudio/work/Dataset/train/New_image/
new_image_dir="/home/aistudio/work/Dataset/train/New_image/"
for image in (os.listdir(img_path)):
    if "_" in image :
        continue
    new_path=os.path.join(new_image_dir,image)
    image=os.path.join(img_path,image)
    print(image)
    img_src = cv2.imread(image,0) 
    img_dst = cv2.equalizeHist(img_src)
    clahe = cv2.createCLAHE(clipLimit=5.0, tileGridSize=(8,8))
    img_dst_clahe = clahe.apply(img_src)
    
    histSize = 256
    histRange = (0, 256) 
    hist_src = cv2.calcHist([img_src], [0], None, [histSize], histRange) 
    hist_dst = cv2.calcHist([img_dst], [0], None, [histSize], histRange)  
    hist_dst_clahe = cv2.calcHist([img_dst_clahe], [0], None, [histSize], histRange) 

    cv2.imwrite(new_path,img_dst_clahe)


2.3、数据集划分

下载Paddlex按train:val=7:3划分数据集,生成labels.txttrain_list.txtval_list.txt

import os 
os.rename("/home/aistudio/work/Dataset/train/ANNOTATIONS","/home/aistudio/work/Dataset/train/Annotations")
os.rename("/home/aistudio/work/Dataset/train/New_image","/home/aistudio/work/Dataset/train/JPEGImages")
!pip install --upgrade pip
!pip install paddlex
!paddlex --split_dataset --format VOC --dataset_dir /home/aistudio/work/Dataset/train --val_value 0.3
!mv /home/aistudio/work/Dataset/train /home/aistudio/PaddleDetection/dataset/voc

三、模型训练、推理

PaddleDetection 是一个基于 PaddlePaddle 框架的多目标物体检测工具包。它提供了丰富的模型库和数据集,支持多种经典的目标检测算法,并且可以方便地进行模型训练、评估和部署。

使用 PaddleDetection,您可以:

  • 快速、高效地搭建自己的目标检测系统;
  • 基于已有的模型和数据集进行二次开发;
  • 将模型部署到各种硬件平台,如 CPU、GPU、FPGA 等;

3.1、模型比较选择:

1、Faster-RCNN:

Faster-RCNN 是一种基于区域提取的目标检测算法,它包括两个主要模块:Region Proposal Network (RPN) 和 Fast R-CNN。该算法在准确率上表现较好,但速度相对较慢。
准确率:在 PASCAL VOC 2012 数据集上,Faster-RCNN 在测试集上的 mAP 值可以达到 73.2% 左右。
FPS:在 NVIDIA Tesla V100 GPU 上,Faster-RCNN 的 FPS 可以达到 5-6。

2、PPYOLOE+:

PPYOLOE+ 是基于 PaddlePaddle 深度学习框架的目标检测算法,它采用了一些优化措施,如特征金字塔网络和多级融合等,以提高检测精度和速度。
准确率:在 COCO 数据集上,PPYOLOE+ 的 AP50 值可以达到 56.6%,mAP 值可以达到 43.8%。
FPS:在 NVIDIA Tesla V100 GPU 上,PPYOLOE+ 的 FPS 可以达到 25-30。

3、YOLOv8:

YOLOv8 是基于 Darknet 框架的目标检测算法,它采用了一些优化措施,如骨干网络的改进和注意力机制等,以提高检测精度和速度。
准确率:在 COCO 数据集上,YOLOv8 的 AP50 值可以达到 53.7%,mAP 值可以达到 37.2%。
FPS:在 NVIDIA Tesla V100 GPU 上,YOLOv8 的 FPS 可以达到 60-70。

综上所述,PPYOLOE+ 在准确率和 FPS 上都表现较好,而 YOLOv8 在速度上具有明显优势。在此,我们选择PPYOLOE+

3.2、PPYOLOE+介绍

PP-YOLOE是一款高精度推理速度快的检测模型,包含 骨干网络CSPRepResNet 、 特征融合CSPPAN 、 轻量级ET-Head 和改进的动态匹配算法TAL(Task Alignment Learning)等模块, 并且根据不同的应用场景设计了一系列模型,即s/m/l/x。

超强性能

训练收敛加速 :使用Objects365预训练模型,减少训练轮数,训练收敛速度提升3.75倍。
下游任务泛化性显著提升 :在农业、夜间安防、工业等不同场景数据集上验证,精度最高提升8.1%。
高性能部署能力:本次升级PP-YOLOE+支持多种部署方式,包括Python/C++、Serving、ONNX Runtime、ONNX-TRT、INT8量化等部署能力。

超强性能与超高泛化性使得PP-YOLOE+助力开发者在 最短时间 、 最少量数据 上能得到 最优效果 。

此外,PP-YOLOE还避免使用诸如可变形卷积或者Matrix NMS之类的特殊算子,使PP-YOLOE全系列模型能轻松地部署在 NVIDIA V100和T4这样的云端GPU架构、Jetson系列的移动端GPU和高性能的FPG A开发板 上 。
具体的结构包括以下三大部分:

1、可扩展的backbone和neck
2、TAL(Task Alignment Learning)
3、Efficient Task-aligned head

3.2 开始训练

配置训练模型
/home/aistudio/PaddleDetection/configs/ppyoloe/voc/ppyoloe_plus_crn_s_30e_voc.yml:pretrain_weights在经过一段时间训练后更换为output中的best_model、base_lr也逐步降低

按ppyoloe_plus_crn_s_30e_voc.yml的指引配置dataset,其他基本不变

%cd PaddleDetection
# !python setup.py install
!export CUDA_VISIBLE_DEVICES=0
# 训练,--eval 边训练边评估
!python tools/train.py -c configs/ppyoloe/voc/ppyoloe_plus_crn_s_30e_voc.yml --use_vdl=true --vdl_log_dir=vdl_dir/scalar --eval

通过VisualDL可以看到,mAP最后基本稳定在70%左右

3.3、推理,保存结果

先从tools/infer.py看起,从run这个函数可以看到调用了ppdet/engine文件夹里面的trainer.py里面Trainer类的predict方法将检测框画在原图上,保存在output文件夹下。

打开trainer.py,搜索找到predict方法,将save_results改为True,即可在output中找到bbox.json

注意,这个ppdet是在PaddleDetection下的ppdet

%cd /home/aistudio/PaddleDetection/
!mkdir /home/aistudio/work/result
!python tools/infer.py -c configs/ppyoloe/voc/ppyoloe_plus_crn_s_30e_voc.yml \
                    --infer_dir=/home/aistudio/work/Dataset/test/IMAGES \
                    --output_dir=/home/aistudio/work/result/ \
                    --draw_threshold=0.4 \
                    -o weights=output/ppyoloe_plus_crn_s_30e_voc/best_model.pdparams \
                    --use_vdl=True \
					--save_results=True

可视化部分图片推理效果

import glob
import os
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
from tqdm import tqdm
out_path="/home/aistudio/work/result/"
img_1_path=os.path.join(out_path,"1424.jpg")
img_2_path=os.path.join(out_path,"1462.jpg")
img_3_path=os.path.join(out_path,"1505.jpg")

img_1=plt.imread(img_1_path)
img_2=plt.imread(img_2_path)
img_3=plt.imread(img_3_path)

plt.figure()
plt.subplot(1,3,1)
plt.title("output")
plt.imshow(img_1)
plt.figure()
plt.subplot(1,3,2)
plt.title("output")
plt.imshow(img_2)
plt.figure()
plt.subplot(1,3,3)
plt.title("output")
plt.imshow(img_3)



    
<matplotlib.image.AxesImage at 0x7f8db2c9f490>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gDvp18hj-1682094126714)(main_files/main_17_1.png)]

在这里插入图片描述

在这里插入图片描述

四、生成提交文件

import glob
import os
import json
import pandas as pd
class Result(object):
    def __init__(self):
        self.imagesPath = '/home/aistudio/work/Dataset/test/IMAGES/'
        self.bboxPath = '/home/aistudio/work/result/bbox.json'
        self.submissionPath = '/home/aistudio/work/submission.csv'

    def run(self):
        images = self.get_image_ids()
        bbox = self.get_bbox()
        results = []
        for i in range(len(images)):
            image_id = images[i]
            for j in range(len(bbox['bbox'][i])):
                bbox_  = [int(i) for i in bbox['bbox'][i][j]]
                item = [
                    image_id,
                    bbox_,
                    int(bbox['label'][i][j]),
                    round(bbox['score'][i][j],2)
                    ]
                results.append(item)
        
        submit = pd.DataFrame(results, columns=['image_id', 'bbox','category_id','confidence'])
        submit[['image_id', 'bbox','category_id','confidence']].to_csv(self.submissionPath, index=False)

    def get_image_ids(self):
        images = set()
        exts = ['jpg']
        for ext in exts:
            images.update(glob.glob('{}/*.{}'.format(self.imagesPath, ext)))
        images = list(images)
        lists = []
        for item in images:
            # print(item)
            item = item.replace(self.imagesPath,'')
            # print(item)
            lists.append(item)
        lists.sort(key=lambda x:int(x.split('.')[0]))
        ids = []
        for fname in lists:
            ids.append(fname.replace('.jpg',''))
        return ids

    def get_bbox(self):
        with open(self.bboxPath, 'r', encoding='utf-8') as bbox:
            bbox = json.load(bbox)
        return bbox

resultObj = Result()
resultObj.run()

六、项目总结

数据增强方面

在做数据增强的时候我用普通直方均衡和自适应直方均衡两种方法,以边训练边验证的模式走了10个epoch,发现自适应直方均衡效果更好那么一丢丢,推理效果也更好,可能就是因为上文所提到的自适应直方均衡可以避免过度增强和失真的情况

模型方面

在你们看不见的地方我用了Fast-RCNN做了一套一模一样的历程,很明显的发现 PPYOLE+ 蒸的很强,FPS、mAP都有明显的提高
下图可以明显看出差距

此文章为搬运
原项目链接

Logo

学大模型,用大模型上飞桨星河社区!每天8点V100G算力免费领!免费领取ERNIE 4.0 100w Token >>>

更多推荐