编程语言
首页 > 编程语言> > 2021广东工业智造创新大赛—智能算法赛总结

2021广东工业智造创新大赛—智能算法赛总结

作者:互联网

赛题

一、赛题背景

佛山作为国内最大的瓷砖生产制造基地之一,拥有众多瓷砖厂家和品牌。经前期调研,瓷砖生产环节一般(不同类型砖工艺不一样,这里以抛釉砖为例)经过原材料混合研磨、脱水、压胚、喷墨印花、淋釉、烧制、抛光,最后进行质量检测和包装。得益于产业自动化的发展,目前生产环节已基本实现无人化。而质量检测环节仍大量依赖人工完成。一般来说,一条产线需要配2~6名质检工,长时间在高光下观察瓷砖表面寻找瑕疵。这样导致质检效率低下、质检质量层次不齐且成本居高不下。瓷砖表检是瓷砖行业生产和质量管理的重要环节,也是困扰行业多年的技术瓶颈。

本赛场聚焦瓷砖表面瑕疵智能检测,要求选手开发出高效可靠的计算机视觉算法,提升瓷砖表面瑕疵质检的效果和效率,降低对大量人工的依赖。要求算法尽可能快与准确的给出瓷砖疵点具体的位置和类别,主要考察疵点的定位和分类能力。

二、赛题数据说明

大赛深入到佛山瓷砖知名企业,在产线上架设专业拍摄设备,实地采集生产过程真实数据,解决企业真实的痛点需求。大赛数据覆盖到了瓷砖产线所有常见瑕疵,包括粉团、角裂、滴釉、断墨、滴墨、B孔、落脏、边裂、缺角、砖渣、白边等。实拍图示例如下:

 

针对某些缺陷在特定视角下的才能拍摄到,每块砖拍摄了三张图,包括低角度光照黑白图、高角度光照黑白图、彩色图,示例如下:

 

数据主要分为两种:

  1. 白板瓷砖。花色简单,数量总共约12000张,包含训练集和测试集,用于初赛。
  2. 复杂瓷砖。花色相对复杂,并提供相应的模板图片(同花色且无瑕疵图片),数量总共约12000张,包含训练集和测试集,用于复赛。

初赛数据示例

白板数据包含有瑕疵图片、无瑕疵图片和标注数据。标注数据标注瑕疵位置和类别信息。图片示例如下:

初赛数据提供

  1. 初赛训练集于1月4日提供。
  2. 初赛一阶段测试集于1月4日提供下载,初赛二阶段测试集1月28号提供下载。

 

训练数据文件结构

└── dataset
    ├── Readme.md
    ├── train_annos.json
    ├── train_imgs

train_imgs:训练图片数据,jpg格式
train_annos.json:训练标注数据,json格式
Readme.md:说明文件

标注说明

训练标注是train_annos.json,内容如下:

[
    {
        "name": "226_46_t20201125133518273_CAM1.jpg",
        "image_height": 6000,
        "image_width": 8192,
        "category": 4,
        "bbox": [
            1587,
            4900,
            1594,
            4909
        ]
    },
    '''
    '''
]

具体说明如下:
name是图片名,"226_46"代表砖的唯一id,"CAM1"代表相机1拍照所得,一般来说每块砖会有三张样本,分别是CAM1,CAM2,CAM3。image_heightimage_width是图片高宽,category"是类别id,bbox是目标框信息xyrb格式,分别指[左上角x坐标,左上角y坐标,右下角x坐标,右下角y坐标]

类别说明

id和瑕疵名的对应关系如下:

{ "0": "背景", "1": "边异常", "2": "角异常", "3": "白色点瑕疵", "4": "浅色块瑕疵", "5": "深色点块瑕疵", "6": "光圈瑕疵", "7": "记号笔", "8": "划伤" }

其中,记号笔划伤是复赛新增。

三、提交说明

评测结果提交

参赛者需要提供一份json文件包含所有预测结果,文件内容如下:

[
    {
        "name": "226_46_t20201125133518273_CAM1.jpg",
        "category": 4,
        "bbox": [
            5662,
            2489,
            5671,
            2497
        ],
        "score": 0.130577
    },
    {
        "name": "226_46_t20201125133518273_CAM1.jpg",
        "category": 2,
        "bbox": [
            6643,
            5416,
            6713,
            5444
        ],
        "score": 0.120612
    },
    ...
    ...
    {
        "name": "230_118_t20201126144204721_CAM2.jpg",
        "category": 5,
        "bbox": [
            3543,
            3875,
            3554,
            3889
        ],
        "score": 0.160216
    }
]

具体说明如下:
1.提交的json文件中包含多个疵点样本,每个疵点样本都包含namecategorybboxscore四个字段。
2.name字段为图片名称;category字段为类别标签;bboxxyrb格式坐标框,分别指[左上角x坐标,左上角y坐标,右下角x坐标,右下角y坐标],小数点后保留2位;score为置信度概率,范围0-1;
3.对于单张图片存在多个疵点样本时,依次列出即可;对于不存在疵点的无疵点图片,不能出现在json列表中。
4.name字段不允许出现非测试集中的图片名。

python示例代码

result=[]
result.append({'name': image_name(str),'category': defect_label(int),'bbox':bbox(xyxy,float),'score': score(float)})
import json
with open('result.json', 'w') as fp:
     json.dump(result, fp, indent=4, ensure_ascii=False)

四、评估指标

初赛

赛题分数计算方式: 0.2ACC+0.8mAP

ACC:是有瑕疵或无瑕疵的分类指标,考察瑕疵检出能力。
其中提交结果name字段中出现过的测试图片均认为有瑕疵,未出现的测试图片认为是无瑕疵。

mAP:参照PASCALVOC的评估标准计算瑕疵的mAP值。
参考链接:https://github.com/rafaelpadilla/Object-Detection-Metrics 具体逻辑见evaluator文件。

需要指出,本次大赛评分计算过程中,分别在检测框和真实框的交并比(IoU)在阈值0.10.30.5下计算mAP,最终mAP取三个值的平均值。

复赛

复赛新增算法效率要求:用于复赛的线上环境配置为V100,要求每张图片平均耗时不得超过4s。以测试集1000张为例,总耗时不得超过4000s。

数据分析

首先查看下载来的数据,随意打开一张图片,查看图片的属性。

 

从上图可以看出图像是8192×6000大小的彩色图片,图片尺寸和COCO数据的图片相比大了很多。然后在数据集转为Labelme的标注数据。转化代码如下:

import sys
import os.path as osp
import io
from labelme.logger import logger
from labelme import PY2
from labelme import QT4
import PIL.Image
import base64
from labelme import utils
import os
import cv2
import xml.etree.ElementTree as ET
from PIL import ImageFile
ImageFile.LOAD_TRUNCATED_IMAGES = True
module_path = os.path.abspath(os.path.join('..'))
if module_path not in sys.path:
    sys.path.append(module_path)
import json
from PIL import Image

Image.MAX_IMAGE_PIXELS = None

class_name_dic = {
    "0": "背景",
    "1": "边异常",
    "2": "角异常",
    "3": "白色点瑕疵",
    "4": "浅色块瑕疵",
    "5": "深色点块瑕疵",
    "6": "光圈瑕疵"
}
rawImgDir = '../tile_round1_train_20201231/train_imgs/'
rawLabelDir = '../tile_round1_train_20201231/train_annos.json'
with open(rawLabelDir) as f:
    annos = json.load(f)

#
image_ann = {}
for i in range(len(annos)):
    anno = annos[i]
    name = anno['name']
    if name not in image_ann:
        image_ann[name] = []
    image_ann[name].append(i)


def load_image_file(filename):
    try:
        image_pil = PIL.Image.open(filename)
    except IOError:
        logger.error('Failed opening image file: {}'.format(filename))
        return

    # apply orientation to image according to exif
    image_pil = utils.apply_exif_orientation(image_pil)

    with io.BytesIO() as f:
        ext = osp.splitext(filename)[1].lower()
        if PY2 and QT4:
            format = 'PNG'
        elif ext in ['.jpg', '.jpeg']:
            format = 'JPEG'
        else:
            format = 'PNG'
        image_pil.save(f, format=format)
        f.seek(0)
        return f.read()


def dict_json(flags, imageData, shapes, imagePath, fillColor=None, lineColor=None, imageHeight=100, imageWidth=100):
    '''
    :param imageData: str
    :param shapes: list
    :param imagePath: str
    :param fillColor: list
    :param lineColor: list
    :return: dict
    '''
    return {"version": "3.16.4", "flags": flags, "shapes": shapes, 'lineColor': lineColor, "fillColor": fillColor,
            'imagePath': imagePath.split('/')[-1], "imageData": imageData, 'imageHeight': imageHeight,
            'imageWidth': imageWidth}


data = json.load(open('1.json'))
for name in image_ann.keys():
    indexs = image_ann[name]
    height, width = annos[indexs[0]]["image_height"], annos[indexs[0]]["image_width"]
    imagePath=rawImgDir+name
    print(imagePath)
    if not os.path.exists(imagePath): # True/False
        continue
    image = cv2.imread(imagePath)
    shapes = data["shapes"]
    version = data["version"]
    flags = data["flags"]
    lineColor = data["lineColor"]
    fillColor = data['fillColor']
    newshapes = []
    for inx in indexs:
        obj = annos[inx]
        assert name == obj['name']
        bbox = obj['bbox']
        category = obj['category']
        xmin, ymin, xmax, ymax = bbox
        class_name = class_name_dic[str(category)]
        newPoints = [[float(xmin), float(ymin)], [float(xmax), float(ymax)]]
        line_color = None
        fill_color = None
        shape_type = 'rectangle'
        flags = flags
        newshapes.append(
            {"label": class_name, "line_color": line_color, "fill_color": fill_color, "points": newPoints,
             "shape_type": shape_type, "flags": flags})
    imageData_90 = load_image_file(imagePath)
    imageData_90 = base64.b64encode(imageData_90).decode('utf-8')
    imageHeight = image.shape[0]
    imageWidth = image.shape[1]
    data_90 = dict_json(flags, imageData_90, newshapes, imagePath, fillColor, lineColor, imageHeight, imageWidth)
    json_file = imagePath[:-4] + '.json'
    print(json_file)
    json.dump(data_90, open(json_file, 'w'))

 

 

 

标签:name,瑕疵,image,智造,json,2021,import,智能算法,bbox
来源: https://blog.csdn.net/hhhhhhhhhhwwwwwwwwww/article/details/113437181