pin脚的缺陷检测

忍不住

  • 我才是最大的缺陷
    • 首先应该学好表达
    • 头脑风暴
    • 分割
    • paddledetection小目标检测也不行
    • 缺陷检测
      • 1.缺陷标注
      • 修改代码为自己的数据集
      • 训练
      • 训练结果
      • 结果图片
  • 结论
  • 再次出发

我才是最大的缺陷

真的,我真的被整无语了。测测测测,测个鬼。一天天的净整些没用的。
在这里插入图片描述

首先应该学好表达

客户有个需求(缺陷检测)+数据(4个图片)-BD需求(缺陷检测)+数据(4个图片)-技术??????????????
1.什么是缺陷?
2.4个图片你确定是给我做测试,而不是让我写ppt?

经过一周的反馈和交流后
客户有个需求(缺陷检测)+数据(2T数据)-BD需求(缺陷检测)+数据(2T数据)-技术??????????????

直到现在我还是一头雾水。

头脑风暴

1.目标检测
2.缺陷检测

前提都是要分割图片,因为客户提供的是2000万像素的图片。然后检测的缺陷大概是50个像素
如果类比到我们常用的512*512的图片,大概就是0.65536。 一个像素都不到。真棒。

分割

这里提一下,参考paddledetection的小目标检测。
使用了sahi,但是他们提供的代码,需要先使用labelme标注,然后转成coco格式。最后在分割。
但是: 没有分割后的图片???
修改代码 slicing.py 中的320行

image_pil.save(slice_file_path, quality=100)

如果我不想标注,我就想分割图片呢

import os

from sahi.slicing import slice_image


img_path=r'G:\sick\ic\NG\2_NG_G7P3900905EA'
output_images_dir=r'G:\sick\ic\NG\split'
image_names=os.listdir(img_path)
for image_name in image_names:
    image_dir=os.path.join(img_path,image_name)
    slice_image(image=image_dir,
                output_file_name=image_name,
                output_dir=output_images_dir,
                slice_height=640,
                slice_width=640,
                min_area_ratio=0.1,
                overlap_height_ratio=0.25,
                overlap_width_ratio=0.25,
                out_ext=".jpg",
                verbose=False,
            )

paddledetection小目标检测也不行

不管是yolov几都不行,目标太小了。而且缺陷不是固定形状的。本身标注就很难

缺陷检测

“Mixed supervision for surface-defect detection: from weakly to fully supervised learning”

因为之前有人给我推荐这个论文,缺陷检测效果很好。
所以就去训练了。
训练的图片大概就是这样
在这里插入图片描述
在这里插入图片描述

1.缺陷标注

还是使用labelme标注,标注好以后,需要转为一个mask图片

这个是吧有缺陷的图片转化一个mask作为标签

#!/usr/bin/env python

from __future__ import print_function

import argparse
import glob
import os
import os.path as osp

import imgviz
import numpy as np

import labelme


def main():
    parser = argparse.ArgumentParser(
        formatter_class=argparse.ArgumentDefaultsHelpFormatter
    )
    parser.add_argument("--input_dir", default=r"G:\sick\ic\mixed-segdec-net-comind2021-master\cocome\dota_sliced\json", help="input annotated directory")
    parser.add_argument("--output_dir", default=r"G:\sick\ic\mixed-segdec-net-comind2021-master\cocome\dota_sliced", help="output dataset directory")
    parser.add_argument("--labels", default=r"G:\sick\ic\mixed-segdec-net-comind2021-master\zw\class_names.txt", help="labels file")
    args = parser.parse_args()
    args.noviz = False


    class_names = []
    class_name_to_id = {}
    for i, line in enumerate(open(args.labels).readlines()):
        class_id = i - 1  # starts with -1
        class_name = line.strip()
        class_name_to_id[class_name] = class_id
        if class_id == -1:
            assert class_name == "__ignore__"
            continue
        elif class_id == 0:
            assert class_name == "_background_"
        class_names.append(class_name)
    class_names = tuple(class_names)
    print("class_names:", class_names)
    out_class_names_file = osp.join(args.output_dir, "class_names.txt")
    with open(out_class_names_file, "w") as f:
        f.writelines("\n".join(class_names))
    print("Saved class_names:", out_class_names_file)

    for filename in glob.glob(osp.join(args.input_dir, "*.json")):
        print("Generating dataset from:", filename)

        label_file = labelme.LabelFile(filename=filename)

        base = osp.splitext(osp.basename(filename))[0]
        out_img_file = osp.join(args.output_dir, "JPEGImages", base + ".jpg")
        out_lbl_file = osp.join(
            args.output_dir, "SegmentationClass", base + ".npy"
        )
        out_png_file = osp.join(
            args.output_dir, "SegmentationClassPNG", base + ".png"
        )
        if not args.noviz:
            out_viz_file = osp.join(
                args.output_dir,
                "SegmentationClassVisualization",
                base + ".jpg",
            )

        with open(out_img_file, "wb") as f:
            f.write(label_file.imageData)
        img = labelme.utils.img_data_to_arr(label_file.imageData)

        lbl, _ = labelme.utils.shapes_to_label(
            img_shape=img.shape,
            shapes=label_file.shapes,
            label_name_to_value=class_name_to_id,
        )
        labelme.utils.lblsave(out_png_file, lbl)

        np.save(out_lbl_file, lbl)

        if not args.noviz:
            viz = imgviz.label2rgb(
                lbl,
                img,
                font_size=15,
                label_names=class_names,
                loc="rb",
            )
            imgviz.io.imsave(out_viz_file, viz)


if __name__ == "__main__":
    main()

在这里插入图片描述
如果是没有缺陷的图片呢

import cv2
import os
import numpy as np
import os.path as osp

file_path=r'G:\sick\ic\mixed-segdec-net-comind2021-master\datasets\tem'

file_name=os.listdir(file_path)

for name in file_name:
    if name.endswith('.png'):
        img_path=os.path.join(file_path,name)
        img=cv2.imread(img_path,0)
        mask=np.zeros_like(img)
        tem=osp.splitext(img_path)[0]+'_label.png'
        # print(1)
        cv2.imwrite(tem,mask)

在这里插入图片描述
最后把所有的图片放在一个文件夹下
在这里插入图片描述

修改代码为自己的数据集

在data中增加一个文件,叫做input_myself.py

import numpy as np
import os
from data.dataset import Dataset
from config import Config

class MyselfDataset(Dataset):
    def __init__(self, kind: str, cfg: Config):
        super(MyselfDataset, self).__init__(cfg.DATASET_PATH, cfg, kind)
        self.read_contents()

    def read_contents(self):
        pos_samples, neg_samples = [], []

        for sample in sorted(os.listdir(self.path)):
            if not sample.__contains__('label'):
                image_path = self.path +  sample
                seg_mask_path = f"{image_path[:-4]}_label.png"
                image = self.read_img_resize(image_path, self.grayscale, self.image_size)
                seg_mask, positive = self.read_label_resize(seg_mask_path, self.image_size, dilate=self.cfg.DILATE)
                sample_name = f"{sample}"[:-4]
                if positive:
                    image = self.to_tensor(image)
                    seg_loss_mask = self.distance_transform(seg_mask, self.cfg.WEIGHTED_SEG_LOSS_MAX, self.cfg.WEIGHTED_SEG_LOSS_P)
                    seg_loss_mask = self.to_tensor(self.downsize(seg_loss_mask))
                    seg_mask = self.to_tensor(self.downsize(seg_mask))
                    pos_samples.append((image, seg_mask, seg_loss_mask, True, image_path, seg_mask_path, sample_name))
                else:
                    image = self.to_tensor(image)
                    seg_loss_mask = self.to_tensor(self.downsize(np.ones_like(seg_mask)))
                    seg_mask = self.to_tensor(self.downsize(seg_mask))
                    neg_samples.append((image, seg_mask, seg_loss_mask, True, image_path, seg_mask_path, sample_name))

        self.pos_samples = pos_samples
        self.neg_samples = neg_samples

        self.num_pos = len(pos_samples)
        self.num_neg = len(neg_samples)
        self.len = 2 * len(pos_samples) if self.kind in ['TRAIN'] else len(pos_samples) + len(neg_samples)

        self.init_extra()

修改dataset_catalog.py

from .input_ksdd import KSDDDataset
from .input_dagm import DagmDataset
from .input_steel import SteelDataset
from .input_ksdd2 import KSDD2Dataset
from .input_myself import MyselfDataset
from config import Config
from torch.utils.data import DataLoader
from typing import Optional


def get_dataset(kind: str, cfg: Config) -> Optional[DataLoader]:
    if kind == "VAL" and not cfg.VALIDATE:
        return None
    if kind == "VAL" and cfg.VALIDATE_ON_TEST:
        kind = "TEST"
    if cfg.DATASET == "KSDD":
        ds = KSDDDataset(kind, cfg)
    elif cfg.DATASET == "DAGM":
        ds = DagmDataset(kind, cfg)
    elif cfg.DATASET == "STEEL":
        ds = SteelDataset(kind, cfg)
    elif cfg.DATASET == "KSDD2":
        ds = KSDD2Dataset(kind, cfg)
    elif cfg.DATASET == "myself":
        ds = MyselfDataset(kind, cfg)
    else:
        raise Exception(f"Unknown dataset {cfg.DATASET}")

    shuffle = kind == "TRAIN"
    batch_size = cfg.BATCH_SIZE if kind == "TRAIN" else 1
    num_workers = 0
    drop_last = kind == "TRAIN"
    pin_memory = False

    return DataLoader(dataset=ds, batch_size=batch_size, shuffle=shuffle, num_workers=num_workers, drop_last=drop_last, pin_memory=pin_memory)

训练

执行python train_net.py 增加参数如下

--GPU=0
--DATASET=myself
--RUN_NAME=RUN_NAME
--DATASET_PATH=datasets/yc/
--RESULTS_PATH=save/results
--SAVE_IMAGES=True
--DILATE=7
--EPOCHS=50
--LEARNING_RATE=1.0
--DELTA_CLS_LOSS=0.01
--BATCH_SIZE=1
--WEIGHTED_SEG_LOSS=True
--WEIGHTED_SEG_LOSS_P=2
--WEIGHTED_SEG_LOSS_MAX=1
--DYN_BALANCED_LOSS=True
--GRADIENT_ADJUSTMENT=True
--FREQUENCY_SAMPLING=True
--TRAIN_NUM=538
--NUM_SEGMENTED=538
--FOLD=0

训练结果

执行python join_folds_results.py 参数如下

--RUN_NAME=RUN_NAME
--RESULTS_PATH=save/results
--DATASET=myself
E:\miniconda\envs\hikvision\python.exe G:\sick\ic\mixed-segdec-net-comind2021-master\join_folds_results.py --RUN_NAME=RUN_NAME --RESULTS_PATH=save/results --DATASET=myself 
Running evaluation for RUN save/results\myself\RUN_NAME
RUN RUN_NAME: AP:1.00000, AUC:1.00000, FP=0, FN=0, FN@.5=1, FP@.5=0, FP@FN0=0

结果图片

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
效果是不是炸裂

结论

最后我又弄个新的图片去测试模型的泛化性
在这里插入图片描述
在这里插入图片描述
简直离谱他妈给离谱开门。这玩意怎么用啊

再次出发

https://github.com/openvinotoolkit/anomalib.git

在网上找了很久,发现有个现成的缺陷检测的库。不管咋样先拿来试一下

安装,数据准备,训练

# Import the required modules
from anomalib.data import Myself
from anomalib.models import Patchcore
from anomalib.engine import Engine

# Initialize the datamodule, model and engine
datamodule = Myself(num_workers=0)
model = Patchcore()
engine = Engine(image_metrics=["AUROC"],
    accelerator="auto",
    check_val_every_n_epoch=1,
    devices=1,
    max_epochs=1,
    num_sanity_val_steps=0,
    val_check_interval=1.0,
)
# Train the model
engine.fit(datamodule=datamodule, model=model)

在这里插入图片描述
好像不能直接训练啊。还是需要去研究一下。。。。。
难受!!!!!!!!!!!!!

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

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

相关文章

国内ip地址推荐,畅享网络新体验!

在数字化时代,IP地址不仅是网络连接的基石,也是互联网产业发展的重要标志。国内作为全球互联网市场的重要参与者,拥有众多IP地址资源。虎观代理小二旨在探索并推荐一些国内IP地址,分析它们的价值所在,并探讨如何更好地…

数据结构和算法:搜索

二分查找 二分查找(binary search) 是一种基于分治策略的高效搜索算法。它利用数据的有序性,每轮缩小一半搜索范围,直至找到目标元素或搜索区间为空为止。 给定一个长度为 𝑛 的数组 nums ,元素按从小到大…

PTA L2-036 网红点打卡攻略

一个旅游景点,如果被带火了的话,就被称为“网红点”。大家来网红点游玩,俗称“打卡”。在各个网红点打卡的快(省)乐(钱)方法称为“攻略”。你的任务就是从一大堆攻略中,找出那个能在…

精品凉拌菜系列热卤系列课程

这一系列课程涵盖精美凉拌菜和美味热卤菜的制作技巧。学员将学习如何选材、调味和烹饪,打造口感丰富、色香俱佳的菜肴。通过实践训练,掌握独特的烹饪技能,为家庭聚餐或职业厨艺提升增添亮点。 课程大小:6.6G 课程下载&#xff1…

【C语言进阶篇】编译和链接

【C语言进阶篇】编译和链接 🥕个人主页:开敲🍉 🔥所属专栏:C语言🍓 🌼文章目录🌼 编译环境与运行环境 1. 翻译环境 2. 编译环境:预编译(预处理)编…

docker关闭全部运行容器命令是什么?

环境: docker v22.1 问题描述: docker关闭全部运行容器命令是什么? 解决方案: 要关闭所有正在运行的Docker容器,可以使用如下命令: docker stop $(docker ps -a -q)这条命令首先执行 docker ps -a -q…

C语言从入门到实战----数据在内存中的存储

1. 整数在内存中的存储 在讲解操作符的时候,我们就讲过了下⾯的内容: 整数的2进制表⽰⽅法有三种,即 原码、反码和补码 有符号的整数,三种表⽰⽅法均有符号位和数值位两部分,符号位都是⽤0表⽰“正”,⽤…

LeetCode:547. 省份数量(并查集 Java)

目录 547. 省份数量 题目描述: 实现代码与解析: 原理思路: 547. 省份数量 题目描述: 有 n 个城市,其中一些彼此相连,另一些没有相连。如果城市 a 与城市 b 直接相连,且城市 b 与城市 c 直接…

MySQL 高级语句(二)

一、子查询 1.1 相同表子查询 1.2 不同表/多表子查询 1.3 子查询的应用 1.3.1 语法 1.3.2 insert 子查询 1.3.3 update 子查询 1.3.4 delete 子查询 1.4 exists 关键字 1.4.1 true 1.4.2 false 1.5 as别名 二、视图 2.1 视图和表的区别和联系 2.1.1 区别 2.1.2 …

详细描述红黑树如何左旋、右旋(图文结合)

红黑树 首先要理解二叉查找树 二叉查找树(BST)具备什么特性呢? 左子树上所有结点的值均小于或等于它的根结点的值。 右子树上所有结点的值均大于或等于它的根结点的值。 左、右子树也分别为二叉排序树。 二叉查找树是二分查找的思想&…

使用IDEA的反编译插件 反编译jar包

反编译插件介绍 安装IDEA后, 一般自带反编译插件, Java Bytecode Decompiler 如果没有可以自己安装下 1.首先找到插件的jar包, 在IDEA安装目录的plugins文件夹下 D:\IntelliJ IDEA 2021.2.2\plugins\java-decompiler\lib 2.运行java命令, 指定插件的jar包目录和你要反编译的ja…

【Hexo + Github 搭建自己的专属博客】

目录 一、前提环境配置 1. 安装Git和NodeJS 2. 安装Hexo 3. 加载主题 4. 修改主题配置 二、搭建博客 1. 将博客部署在GitHub上 2. 写文章并上传 3. 配置一些特效 三、最终成果 ​编辑 一、前提环境配置 1. 安装Git和NodeJS 在 Windows 上使用 Git ,可以…

OpenCV模块熟悉:点云处理相关

1. 显示--VIZ 曾经基于PCL 做过不少点云相关的开发,采样VTK进行有点云显示。后来基于OpenCV做了不少三维重建工作,总是将点云保存下来,然后借助CloudCompare等查看结果。如果能够将VIZ编译进来,预计会提升开发速度。 …

一文搞懂大疆机场kmz航线和图新地球导出的kmz的区别

0序: 近期有用户问“ 把KML文件放到图新后,想转出来KMZ(大疆的机场用的格式)但是转出来的KMZ显示格式不对 ” 之前只是知道大疆的航线规划采用的是kml规范,但具体是什么样并不清楚。就这这个问题把这个事情给弄明白。…

【问题处理】蓝鲸监控-数据断点解决

本文来自腾讯蓝鲸智云社区用户:fadewalk 在问答社区看到有小伙伴在落地蓝鲸的过程中出现监控平台的grafana面板数据断点问题,往往出现这种问题,都比较的头疼。 如果将CMDB(配置管理数据库)比作运维的基石,…

【Leetcode】2580. 统计将重叠区间合并成组的方案数

文章目录 题目思路代码复杂度分析时间复杂度空间复杂度 结果总结 题目 题目链接🔗 给你一个二维整数数组 ranges ,其中 ranges[i] [starti, endi] 表示 starti 到 endi 之间(包括二者)的所有整数都包含在第 i 个区间中。 你需要…

文献阅读笔记(Transformer)

文献阅读笔记(Transformer) 摘要Abstract1、文献阅读1.1 文献题目1.2 文献摘要1.3 研究背景1.4 模型架构1.4.1 Encoder-Decoder1.4.2 注意力机制1.4.3 多头注意力1.4.4 Position-wise Feed-Forward Networks1.4.5 Embeddings and Softmax1.4.6 Positiona…

应对Locked勒索病毒威胁:你的数据安全准备好了吗?

导言: .Locked勒索病毒,作为一种新型的恶意软件,已经在全球范围内引起了广泛的关注。这种病毒通过加密受害者的文件,并要求支付赎金以获取解密密钥,从而实现对受害者的勒索。本文旨在深入解析.Locked勒索病毒的特点、…

Linux逻辑卷管理

一.前言 Linux系统在使用的过程中,数据只会越来越多。如果在硬盘的标准分区创建了文件系统,那么向已有的文件系统增添额外的存储空间是一件头疼的事情。我们只能在同一块物理硬盘上的可用空间范围内调整分区大小。此外硬盘没有存储空间了,就需…

【tingsboard开源平台】环境准备和安装

文章目录 环境准备:1.安装JAVA2.安装maven环境3.安装nodeJS(16.15.1)4.安装git环境5.安装npm依赖关系6.放入文件fetched7.安装IDEA 环境准备: 1.安装JAVA 以安装java11为例,安装tingsboard需要的jdk 下载地址:https://www.oracle.com/java/technologi…