C++视觉开发 三.缺陷检测
一.距离变换
1.概念和功能
距离变换是一种图像处理技术,用于计算图像中每个像素到最近的零像素(背景像素)的距离。它常用于图像分割、形态学操作和形状分析等领域。它计算图像中每个像素到最近的零像素(背景像素)的距离。这个距离可以是欧氏距离、曼哈顿距离等。距离变换后的图像中,前景像素的值代表它们到最近的背景像素的距离。
具体来说,距离变换在缺陷检测中有以下几个重要作用:
1.前景与背景的分离: 距离变换能够突出前景区域,使其与背景更明显地分离开。前景区域的像素值会表示其到最近背景像素的距离,这样可以更容易地识别和处理前景对象。
2.前景对象的中心检测: 距离变换的结果图像中,距离值最大的像素往往位于前景对象的中心位置。因此,通过距离变换,可以有效地检测出前景对象的中心点,为后续的形态学处理和轮廓检测提供可靠的信息。
3.分水岭算法的预处理: 距离变换常用于分水岭算法的预处理步骤,通过距离变换可以生成标记图像,这些标记可以帮助分水岭算法准确地分割图像中的各个对象。
4.形态学重建: 距离变换可以结合形态学操作进行形态学重建,用于去除图像中的小噪声和伪影,使前景对象更加清晰。
2.函数语法
示例:
// 距离变换
cv::Mat dist_transform;
cv::distanceTransform(op, dist_transform, cv::DIST_L2, 3);
cv::normalize(dist_transform, dist_transform, 0, 1.0, cv::NORM_MINMAX);// 阈值处理
cv::Mat fore;
cv::threshold(dist_transform, fore, 0.3, 1.0, cv::THRESH_BINARY);
fore.convertTo(fore, CV_8U);
1. cv::distanceTransform
功能:用于计算二值图像中每个前景像素到最近背景像素的距离。
函数语法:
void cv::distanceTransform(InputArray src, OutputArray dst, int distanceType, int maskSize, int dstType = CV_32F);
| src | 输入图像,通常是一个二值图像。 其中非零像素被视为前景,零像素被视为背景。 |
| dst | 输出图像,包含每个像素到最近背景像素的距离。 默认情况下,输出图像是一个32位浮点图像( |
| distanceType | 距离类型,指定距离的计算方式。常用的类型有:
|
| maskSize | 掩码大小,影响距离计算的精度。可以是3、5或cv::DIST_MASK_PRECISE(在精确距离变换中使用)。常用值为3。 |
| dstType | 输出图像的类型。默认值为 可以更改为其他类型,如 |
2.cv::normalize
功能:用于将数组的值归一化到指定的范围内。它可以应用于图像处理中的多种场景,例如将距离变换的结果归一化到 [0, 1] 或 [0, 255],从而便于可视化和后续处理。
函数语法:
void cv::normalize(
InputArray src,
OutputArray dst,
double alpha,
double beta,
int norm_type = cv::NORM_L2,
int dtype = -1,
InputArray mask = noArray()
);
| src | 输入数组或图像 |
| dst | 输出数组或图像,与输入数组具有相同的大小和类型,或者具有指定的类型。 |
| alpha | 归一化后数组中最小值的目标值。 如果 norm_type 是 cv::NORM_MINMAX,这个参数表示归一化后的最小值。 |
| beta | 归一化后数组中最大值的目标值。 如果 norm_type 是 cv::NORM_MINMAX,这个参数表示归一化后的最大值。 |
| norm_type | 归一化类型。可以是以下之一:
|
| dtype | (可选)输出数组的类型。如果为 -1,则输出数组的类型与输入数组相同。 |
| mask | (可选)可选的操作掩码。仅对掩码内的元素进行归一化处理。 |
只用前5个就够了
3.fore.convertTo
功能:将矩阵转换为另一种数据类型的函数。此函数通常用于图像处理中的数据类型转换,以确保图像处理操作使用正确的数据类型。
函数语法:
void cv::Mat::convertTo(OutputArray m, int rtype, double alpha , double beta)
| m | 输出矩阵,类型由 rtype 指定。 |
| rtype | 输出矩阵的类型。可以是 CV_8U(8 位无符号整数)、CV_32F(32 位浮点数)等。 |
| alpha | 可选的比例因子,默认值为 1。输出矩阵的每个元素是输入矩阵相应元素乘以 alpha。 |
| beta | 可选的加数,默认值为 0。输出矩阵的每个元素是输入矩阵相应元素乘以 alpha 再加上 beta。 |
二.缺陷检测
通过计算轮廓面积和最小外接圆的面积比值来判断是否存在缺陷
1.cv::minEnclosingCircle 最小外接圆
功能:找到一个最小的圆,使得圆能够完全包围给定的轮廓。
函数语法:
void cv::minEnclosingCircle(InputArray points, Point2f& center, float& radius);
points | 输入的点集,可以可以是一个点的向量或Mat。 |
center | 输出参数,存储最小外接圆的圆心坐标。 |
radius | 输出参数,存储最小外接圆的半径。 |
2.完整代码示例
#include <opencv2/opencv.hpp>
#include <iostream>int main() {// 读取图像cv::Mat o = cv::imread("pill3.jpg", cv::IMREAD_GRAYSCALE);if (o.empty()) {std::cerr << "Could not open or find the image!" << std::endl;return -1;}// 二值化处理cv::Mat binary;cv::threshold(o, binary, 0, 255, cv::THRESH_BINARY + cv::THRESH_OTSU);// 形态学开运算cv::Mat kernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(5, 5));cv::Mat op;cv::morphologyEx(binary, op, cv::MORPH_OPEN, kernel, cv::Point(-1, -1), 1);// 距离变换cv::Mat dist_transform;cv::distanceTransform(op, dist_transform, cv::DIST_L2, 3);cv::normalize(dist_transform, dist_transform, 0, 1.0, cv::NORM_MINMAX);// 阈值处理cv::Mat fore;cv::threshold(dist_transform, fore, 0.3, 1.0, cv::THRESH_BINARY);fore.convertTo(fore, CV_8U);// 形态学去噪cv::Mat kernel2 = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));cv::Mat op2;cv::morphologyEx(fore, op2, cv::MORPH_OPEN, kernel2, cv::Point(-1, -1), 1);// 提取轮廓std::vector<std::vector<cv::Point>> contours;cv::findContours(op2, contours, cv::RETR_TREE, cv::CHAIN_APPROX_SIMPLE);// 缺陷检测int count = 0;cv::Mat img = o.clone();for (size_t i = 0; i < contours.size(); i++) {cv::Point2f center;float radius;cv::minEnclosingCircle(contours[i], center, radius);double area = cv::contourArea(contours[i]);double area_circle = 3.14 * radius * radius;if (area / area_circle >= 0.5) {cv::putText(img, "OK", center, cv::FONT_HERSHEY_COMPLEX, 1, cv::Scalar(255, 255, 255), 2);}else {cv::putText(img, "bad", center, cv::FONT_HERSHEY_COMPLEX, 1, cv::Scalar(255, 255, 255), 2);}count++;}cv::putText(img, "sum=" + std::to_string(count), cv::Point(20, 30), cv::FONT_HERSHEY_COMPLEX, 1, cv::Scalar(255, 255, 255));// 显示结果cv::imshow("result", img);cv::waitKey(0);cv::destroyAllWindows();return 0;
}
结果如图:

相关文章:
C++视觉开发 三.缺陷检测
一.距离变换 1.概念和功能 距离变换是一种图像处理技术,用于计算图像中每个像素到最近的零像素(背景像素)的距离。它常用于图像分割、形态学操作和形状分析等领域。它计算图像中每个像素到最近的零像素(背景像素)的距…...
使用 Amazon Bedrock Converse API 简化大语言模型交互
本文将介绍如何使用 Amazon Bedrock 最新推出的 Converse API,来简化与各种大型语言模型的交互。该 API 提供了一致的接口,可以无缝调用各种大型模型,从而消除了需要自己编写复杂辅助功能函数的重复性工作。文中示例将展示它相比于以前针对每…...
第二十一章 函数(Python)
文章目录 前言一、定义函数二、函数参数三、参数类型四、函数返回值五、函数类型1、无参数,无返回值2、无参数,有返回值3、有参数,无返回值4、有参数,有返回值 六、函数的嵌套七、全局变量和局部变量1、局部变量2、全局变量 前言 …...
使用pyqt5编写一个七彩时钟
使用pyqt5编写一个七彩时钟 效果代码解析定义 RainbowClockWindow 类初始化用户界面显示时间方法 完整代码 在这篇博客中,我们将使用 PyQt5 创建一个简单的七彩数字时钟。 效果 代码解析 定义 RainbowClockWindow 类 class RainbowClockWindow(QMainWindow):def _…...
【Linux】:命令行参数
朋友们、伙计们,我们又见面了,本期来给大家解读一下有关Linux命令行参数的相关知识点,如果看完之后对你有一定的启发,那么请留下你的三连,祝大家心想事成! C 语 言 专 栏:C语言:从入…...
高考假期预习指南,送给迷茫的你
高考结束,离别了熟悉的地方,踏上远方。 你,,迷茫吗? 大学是什么?到了大学我该怎样学习?真像网上说的毕业即失业吗? 大学是一个让你学会一技之长的地方,到了大学找到自…...
独孤思维:负债了,还可以翻身吗
01 其实独孤早年也负债。 负债并不可怕。 可怕的是因为负债而催生的想要快速赚钱的心态。 越是有这种心态,越是不可能赚到钱。 相反,可能会让你陷入恶性循环中。 盲目付费,盲目寄希望于某个项目或者某个人。 当成唯一的救命稻草。 这…...
SwiftUI八与UIKIT交互
代码下载 SwiftUI可以在苹果全平台上无缝兼容现有的UI框架。例如,可以在SwiftUI视图中嵌入UIKit视图或UIKit视图控制器,反过来在UIKit视图或UIKit视图控制器中也可以嵌入SwiftUI视图。 本文展示如何把landmark应用的主页混合使用UIPageViewController和…...
RedHat9 | 内部YUM本地源服务器搭建
服务器参数 标识公司内部YUM服务器主机名yum-server网络信息192.168.37.1/24网络属性静态地址主要操作用户root 一、基础环境信息配置 修改主机名 [rootyum-server ~]# hostnamectl hostname yum-server添加网络信息 [rootyum-server ~]# nmcli connection modify ens160 …...
无偏归一化自适应心电ECG信号降噪方法(MATLAB)
心电信号作为一种生物信号,含有大量的临床应用价值的信息,在现代生命医学研究中占有重要的地位。但心电信号低频、低幅值的特点,使其在采集和传输的过程中经常受到噪声的干扰,使心电波形严重失真,从而影响后续的病情分…...
AI基本概念(人工智能、机器学习、深度学习)
人工智能 、 机器学习、 深度学习的概念和关系 人工智能 (Artificial Intelligence)AI- 机器展现出人类智慧机器学习 (Machine Learning) ML, 达到人工智能的方法深度学习 (Deep Learning)DL,执行机器学习的技术 从范围…...
LabVIEW幅频特性测试系统
使用LabVIEW软件开发的幅频特性测试系统。该系统整合了Agilent 83732B信号源与Agilent 8563EC频谱仪,通过LabVIEW编程实现自动控制和数据处理,提供了成本效益高、操作简便的解决方案,有效替代了昂贵的专用仪器,提高了测试效率和设…...
校园卡手机卡怎么注销?
校园手机卡的注销流程可以根据不同的运营商和具体情况有所不同,但一般来说,以下是注销校园手机卡的几种常见方式,我将以分点的方式详细解释: 一、线上注销(通过手机APP或官方网站) 下载并打开对应运营商的…...
logback自定义规则脱敏
自定义规则conversionRule public class LogabckMessageConverter extends MessageConverter {Overridepublic String convert(ILoggingEvent event) {String msg event.getMessage();if ("INFO".equals(event.getLevel().toString())) {msg .....脱敏实现}return …...
高效批量复制与覆盖:一键实现文件管理,轻松应对同名文件,简化工作流程
在数字时代,我们每天都在与海量的文件和数据打交道。你是否曾经遇到过这样的情况:需要批量复制文件到指定文件夹,但一遇到同名文件就头疼不已,要么手动一个个确认覆盖,要么冒着数据丢失的风险直接操作?别担…...
vue3中使用Antv G6渲染树形结构并支持节点增删改
写在前面 在一些管理系统中,会对组织架构、级联数据等做一些管理,你会怎么实现呢?在经过调研很多插件之后决定使用 Antv G6 实现,文档也比较清晰,看看怎么实现吧,先来看看效果图。点击在线体验 实现的功能…...
【PB案例学习笔记】-26制作一个带浮动图标的工具栏
写在前面 这是PB案例学习笔记系列文章的第26篇,该系列文章适合具有一定PB基础的读者。 通过一个个由浅入深的编程实战案例学习,提高编程技巧,以保证小伙伴们能应付公司的各种开发需求。 文章中设计到的源码,小凡都上传到了gite…...
反向沙箱技术:安全隔离上网
在信息化建设不断深化的今天,业务系统的安全性和稳定性成为各公司和相关部门关注的焦点。面对日益复杂的网络威胁,传统的安全防护手段已难以满足需求。深信达反向沙箱技术,以其独特的设计和强大的功能,成为保障政务系统信息安全的…...
前端在for循环中使用Element-plus el-select中的@click.native动态传参
<el-table ref"table" :data"editTableVariables" cell-dblclick"handleRowDblClick" style"width: 100%" > <!-- el-table-column: 表格列组件,定义每列的展示内容和属性 --><el-table-column prop&q…...
Oracle SQL - CONNECT BY语句Where条件中不能使用OR?[已解决]
数据 SQL> SELECT * FROM demo_a;CUSTOMER TOTAL ---------- ---------- A 100200SQL> SELECT * FROM demo_b;CUSTOMER RN QTY ---------- ---------- ---------- A 1 30 A 2 …...
浅谈 React Hooks
React Hooks 是 React 16.8 引入的一组 API,用于在函数组件中使用 state 和其他 React 特性(例如生命周期方法、context 等)。Hooks 通过简洁的函数接口,解决了状态与 UI 的高度解耦,通过函数式编程范式实现更灵活 Rea…...
linux之kylin系统nginx的安装
一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源(HTML/CSS/图片等),响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址,提高安全性 3.负载均衡服务器 支持多种策略分发流量…...
【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...
微信小程序 - 手机震动
一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注:文档 https://developers.weixin.qq…...
数据库分批入库
今天在工作中,遇到一个问题,就是分批查询的时候,由于批次过大导致出现了一些问题,一下是问题描述和解决方案: 示例: // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...
分布式增量爬虫实现方案
之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面,避免重复抓取,以节省资源和时间。 在分布式环境下,增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路:将增量判…...
android13 app的触摸问题定位分析流程
一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...
C语言中提供的第三方库之哈希表实现
一. 简介 前面一篇文章简单学习了C语言中第三方库(uthash库)提供对哈希表的操作,文章如下: C语言中提供的第三方库uthash常用接口-CSDN博客 本文简单学习一下第三方库 uthash库对哈希表的操作。 二. uthash库哈希表操作示例 u…...
CVPR2025重磅突破:AnomalyAny框架实现单样本生成逼真异常数据,破解视觉检测瓶颈!
本文介绍了一种名为AnomalyAny的创新框架,该方法利用Stable Diffusion的强大生成能力,仅需单个正常样本和文本描述,即可生成逼真且多样化的异常样本,有效解决了视觉异常检测中异常样本稀缺的难题,为工业质检、医疗影像…...
Vue 模板语句的数据来源
🧩 Vue 模板语句的数据来源:全方位解析 Vue 模板(<template> 部分)中的表达式、指令绑定(如 v-bind, v-on)和插值({{ }})都在一个特定的作用域内求值。这个作用域由当前 组件…...
