opencv实战项目十五:钢材表面缺陷检测

news2024/11/15 19:49:11

文章目录

  • 前言
  • 一、算法实现流程:
  • 二,算法详解:
    • 2.1 二值化与去噪
    • 2.2 形态学处理
  • 三,整体代码实现:


前言

随着科技的不断进步,自动化和智能化在工业生产中的应用越来越广泛。在钢材生产过程中,钢材表面缺陷检测是一个重要的环节,直接关系到产品的质量和生产效率。传统的表面缺陷检测方法依赖于人工操作,不仅效率低下,而且容易受到主观因素的影响,导致检测结果的不准确性。因此,开发一种高效、准确的钢材表面缺陷检测系统具有重要的现实意义。

一、算法实现流程:

本次项目主要目的是帮助大家掌握构建不同的结构元进行形态学变换,钢材图片为:
在这里插入图片描述
经过特征分析,算法实现流程为,二值化获取痕迹前景,前景去噪,形态学让痕迹连续并去除更多无用噪声,霍夫直线读取图像中的直线并绘制。

二,算法详解:

2.1 二值化与去噪

本次算法二值化使用的是opencv内置自适应二值化,与传统二值化相比其更能适应光照等特征干扰,函数名为cv2.adaptiveThreshold,cv2.adaptiveThreshold 是OpenCV库中的一个函数,用于对图像进行自适应阈值处理。自适应阈值处理与全局阈值处理不同,它不是使用一个固定的全局阈值值来二值化图像,而是根据图像中每个像素点周围的局部区域亮度来计算一个阈值。这种方法对于光照不均匀的图像特别有效。

输入:
src:输入的灰度图像。
maxValue:二值化后像素值的上限,通常是255。
adaptiveMethod:确定自适应方法。可能的值包括:
ADAPTIVE_THRESH_MEAN_C:使用邻域像素的平均值来计算阈值。
ADAPTIVE_THRESH_GAUSSIAN_C:使用邻域像素的加权平均值来计算阈值,权重取决于邻域像素与中心像素的亮度差。
thresholdType:阈值类型。可能的值包括:
THRESH_BINARY:像素值大于阈值的设置为最大值,小于阈值的设置为0。
THRESH_BINARY_INV:像素值大于阈值的设置为0,小于阈值的设置为最大值。
blockSize:计算局部阈值的邻域大小,必须是奇数。
C:常数,从平均值或加权平均值中减去。这个参数可以帮助调整阈值,使其更加适合特定场景。
输出参数:
cv2.adaptiveThreshold 函数返回一个二值图像,其中像素点的值要么是0(黑色),要么是最大灰度值(白色)。

示例

thresh = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, -25)

效果:
在这里插入图片描述
图中的噪声很多,由于图像中的裂痕比较细,如果直接使用中值滤波会造成线段不连续,故采用高斯滤波并对滤波后的图像在进行二值化:

blurred = cv2.GaussianBlur(thresh, (15, 15), 0)
_, binary = cv2.threshold(blurred, 30, 255, cv2.THRESH_BINARY)

在这里插入图片描述

2.2 形态学处理

常态情况下,结构元的形状一般为宽高相等的多边形,但本次项目的特征为直线,故结构元的形状也定义为直线结构元,这样能在形态学变换中很好的保留本身形状:
代码实现:

# 定义结构元素
kernel = np.ones((1, 65), np.uint8)
kernel2 = np.ones((1, 15), np.uint8)
kernel3 = np.ones((1, 30), np.uint8)

# 应用形态学操作
morph = cv2.morphologyEx(binary, cv2.MORPH_CLOSE, kernel)  # 应用闭运算
morph2 = cv2.morphologyEx(binary, cv2.MORPH_OPEN, kernel2)  # 应用开运算
dia = cv2.dilate(morph2, kernel3)  # 应用膨胀运算

效果:
在这里插入图片描述
最后只需要识别蒙版中的直线即可

三,整体代码实现:

# 导入OpenCV库和NumPy库
import cv2
import numpy as np

# 读取图像
img = cv2.imread(r'D:\AI_tool\GFPGAN-master\1.png')  # 读取图片路径为D盘AI工具目录下的GFPGAN-master子目录中的1.png
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  # 将BGR格式的图像转换为灰度图像

# 应用自适应阈值处理
thresh = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, -25)  # 计算每个像素点的局部阈值,并二值化图像
blurred = cv2.GaussianBlur(thresh, (15, 15), 0)  # 对二值化图像进行高斯模糊处理
_, binary = cv2.threshold(blurred, 30, 255, cv2.THRESH_BINARY)  # 再次二值化图像
cv2.imshow("thresh", thresh)  # 显示第一次二值化后的图像
cv2.imshow("binary", binary)  # 显示第二次二值化后的图像

# 定义结构元素
kernel = np.ones((1, 65), np.uint8)
kernel2 = np.ones((1, 15), np.uint8)
kernel3 = np.ones((1, 30), np.uint8)

# 应用形态学操作
morph = cv2.morphologyEx(binary, cv2.MORPH_CLOSE, kernel)  # 应用闭运算
morph2 = cv2.morphologyEx(binary, cv2.MORPH_OPEN, kernel2)  # 应用开运算
dia = cv2.dilate(morph2, kernel3)  # 应用膨胀运算

# 设置HoughLinesP参数
threshold = 100
minLineLength = 15
maxLineGap = 20

# 应用HoughLinesP检测直线
lines = cv2.HoughLinesP(dia, 1, 30 * np.pi / 360, threshold, minLineLength, maxLineGap)

# 创建线性图像用于绘制检测到的直线
linear = img.copy()

# 遍历检测到的直线并绘制
for [line] in lines:
    x1, y1, x2, y2 = line  # 提取直线端点坐标
    cv2.line(linear, (x1, y1), (x2, y2), (0, 0, 255), 1)  # 在线性图像上绘制直线

# 显示原始图像和线性图像
cv2.imshow("ori", img)
cv2.imshow("linear", linear)
# 等待任意键按下
cv2.waitKey(0)

四:效果:
在这里插入图片描述

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

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

相关文章

认知杂谈33

今天分享 有人说的一段争议性的话 I I 《说话影响命运,得小心》 嘿,你想想看,咱平常不经意说的那些话,就像小种子一样。你可能没当回事,可说不定啥时候,这些话就会在生活里生根发芽,最后生活…

继承—构造函数—引用等

继承时,数据成员,函数成员全盘接收,如果碰见同名成员屏蔽基类成员。 1,无论采取什么继承方式,基类中所有数据成员都将继承到派生类 2,在类型的继承层次里,保护属性当作共有属性使用 3&#x…

Xv6驱动(一):PLIC

PLIC内存布局 #define PLIC 0x0c000000L #define PLIC_PRIORITY (PLIC 0x0) #define PLIC_PENDING (PLIC 0x1000) #define PLIC_SENABLE(hart) (PLIC 0x2080 (hart) * 0x100) #define PLIC_SPRIORITY(hart) (PLIC 0x201000 (hart) * 0x2000) #define PLIC_SCLAIM(hart) …

前端算法 ==== 栈的好戏还要继续!| 1047. 删除字符串中的所有相邻重复项

目录 解题 思路 题外话 给出由小写字母组成的字符串 S,重复项删除操作会选择两个相邻且相同的字母,并删除它们。 在 S 上反复执行重复项删除操作,直到无法继续删除。 在完成所有重复项删除操作后返回最终的字符串。答案保证唯一。 输入&a…

E-Prime2中同时识别大小写字母与中文支持设置

识别大小写 起因是在学习Eprime过程中发现,一开始只设置了键盘反应为q,然后当键盘为大写状态时,按Q不会响应,后来看到可以同时设置Qq,并且也能读取,简单试了一下,发现有必要在其他地方也这么设…

Multi-class Token Transformer for Weakly Supervised Semantic Segmentation

code:https://github.com/xulianuwa/MCTformer 摘要 本文提出了一种基于Transformer的新框架,用于学习类别特定的对象定位图,并将其作为弱监督语义分割(WSSS)的伪标签。受到标准视觉Transformer中单类别token的关注区…

SpringBoot天猫商城基于前后端分离+SpringBoot+BootStrap、Vue.js、JQuery+JPA+Redis

SpringBoot天猫商城整站 一、项目介绍和演示 SPRINGBOOT天猫整站,基于 前后端分离思想, 由于该商城高并发的特点,后端框架便使用了方便维护的 SpringM VC、SpringBoot框架,而前端框架则选择了主流的BootStrap、Vue.js,…

虚拟机扩展分区

1、删除快照后 先扩展 虚拟机空间 2、 创建分区 rootlocalhost /]# lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 0 200G 0 disk ├─sda1 8:1 0 500M 0 part /boot └─sda2 8:2 0 99.5G 0 part ├─VolGroup-lv_root (dm-0) 249:0 0 50G 0 lvm / ├─VolGroup-lv…

网络防火墙的主要功能及其弊端

防火墙(Firewall),也称防护墙,是由Check Point 创立者Gil Shwed于1993 年发明并引入国际互联网。 它是一种位于内部网络与外部网络之间的网络安全系统。是一项信息安全的防护系统,依照特定的规则,允许或是限…

【python】时间序列模型(ARIMA)

文章目录 前言一、示例二、代码实现----python全部数据的平稳性检验划分训练集平稳性检验确定 p,q结果分析和模型检验模型预测 前言 接上一篇博客,用python完成代码编写。 【学习笔记】时间序列模型(ARIMA) 一、示例 已知一个上市公司一段时期的开盘价…

leetcode 数组+哈希+双指针+子串+滑动窗口

——————双指针 283. 移动零 给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。 请注意 ,必须在不复制数组的情况下原地对数组进行操作。 示例 1: 输入: nums [0,1,0,3,12] 输出: [1,3,12,0,0] …

AI大模型日报#0820:DeepMind创始人访谈、阿里多模态mPLUG-Owl3、抱抱脸SOTA小模型

导读:AI大模型日报,爬虫LLM自动生成,一文览尽每日AI大模型要点资讯!目前采用“文心一言”(ERNIE-4.0-8K-latest)、“智谱AI”(glm-4-0520)生成了今日要点以及每条资讯的摘要。欢迎阅…

linux文件——文件系统——学习硬件:磁盘

前言:本节将带领友友们认识计算机外设中的——磁盘。 目的是为后面学习文件系统打好基础。认识磁盘我们将从——磁盘的组成、磁盘的逻辑结构两个方面进行讲解。 下面开始我们的学习吧。 ps:本节适合所有阶段的友友们学习哦, 友友们可以在本篇…

推荐几款论文初稿ai工具,一键生成!

开题报告-科研加速秘籍:AI论文写作工具推荐! 在科研的世界里,论文写作是不可或缺的一部分。 然而,很多时候我们在开题报告的编写上就遇到了巨大的挑战。 别担心,今天我要分享这个工具来帮助你轻松应对这个问题。 通过…

(java)动态代理

1.思想分析 不能修改原有的代码: 代理:相当于中介公司 代理:转移职责 代理:做准备工作 调用对象中的方法 代理:通过接口--接口中的方法就是要代理的方法

JVM类加载机制—类加载器和双亲委派机制详解

一、概述 上篇我们介绍了JVM类加载机制—JVM类加载过程,类加载过程是类加载机制第一阶段,这一阶段主要做将类的字节码(class文件)加载JVM内存模型中,并转换为JVM内部的数据结构(如java.lang.Class实例&…

Java常用工具类之Date类和Calender类

1、 Date类中常用方法 1. Date类的常用方法 Date类的常用方法 方法 含义 new Date() 实例化Date对象,常见于获得系统当前时间 new Date(long time) 实例化Date对象,并根据具体的时间偏移量time设置时…

C语言 | Leetcode C语言题解之第371题两整数之和

题目&#xff1a; 题解&#xff1a; int getSum(int a, int b){ int c; while(b) {c(unsigned int)(a&b)<<1;a^b;bc; }return a; }

静态网页的制作步骤

静态网页是由HTML、CSS和JavaScript等前端技术构建而成的&#xff0c;它们通常用于展示静态内容&#xff0c;不涉及动态数据的处理。制作静态网页的过程涉及多个步骤&#xff0c;包括规划、设计、编码和测试等。下面是一个详细的制作静态网页的步骤&#xff0c;希望对你有帮助。…

Apache Flink内存模型

Flink 内存模型 大数据中所有开源的框架都会使用到JVM&#xff0c;不如&#xff0c;MapReduce&#xff0c;Storm&#xff0c;Spark等&#xff0c;这些计算框架处理数据过程中涉及到将大量数据存储到内存中&#xff0c;此时如果内存管理过渡依赖JVM&#xff0c;会出现java对象存…