【秣厉科技】LabVIEW工具包——OpenCV 教程(19):拾遗 - imgproc 基础操作(上)

news2025/5/20 2:12:05

文章目录

  • 前言
  • imgproc 基础操作(上)
    • 1. 颜色空间
    • 2. 直方图
    • 3. 二值化
    • 4. 腐蚀、膨胀、开闭运算
    • 5. 梯度与轮廓
    • 6. 简易绘图
    • 7. 重映射
  • 总结


前言

  1. 需要下载安装OpenCV工具包的朋友,请前往 此处 ;
  2. 系统要求:Windows系统,LabVIEW>=2018,兼容32位和64位。

imgproc 基础操作(上)

本文对于之前教程中,未曾集中详细讲解的基础图像处理内容,进行必要的补充

这些功能基本都来源于 imgproc 模块,大概可以分为以下几个方面。

1. 颜色空间

此内容之前已有教程,详见:【秣厉科技】LabVIEW工具包——OpenCV 教程(4):颜色空间


2. 直方图

直方图是一种统计表示方法,用于展示图像中不同像素强度出现的频率分布。

OpenCV中,用 calcHist 函数计算直方图,简单用法如下:

  • 例2-1:灰度图的直方图统计,区间数为5,均匀分割 8U 范围(0~255)

  • 作为常用的一维直方图,其输出结果 Hist 是个列向量,每一个数值代表相应灰度区间内的像素数。
    在这里插入图片描述

  • calcHist 参数含义:

参数含义
ImageArrayMat 数组,存储一张或多张输入图像,尺寸必须一致
Hist一个 Mat 对象,直方图统计结果的输出容器,类型为 32F
channelsint 数组,指定需要做直方图统计的通道序号。当 ImageArray 包含多张图片时,通道序号依次递增,比如第一张包含3个通道,序号为0、1、2;第二张也包含3个通道,序号为3、4、5,以此类推。

channels 只包含一个通道序号时,代表最常用的一维直方图;当包含多个通道序号时,则是多维直方图。
histSizeint 数组,指定每个通道(维度)的直方图数量
rangesfloat 数组,指定每个通道中像素强度(灰度)值的统计范围。
当 uniform 为真,ranges 每通道只需两个数值,即(总下限,总上限),将自动平均分割成 histSize 指定的份数;
当 uniform 为假,ranges 每通道需手动分割,如(h0,h1,h2,h3)代表三个范围 h0-h1,h1-h2,h2-h3 ;

以上的每个范围都遵循 “包含左端,不包含右端” 的原则,即左闭右开。
uniform布尔值,均一化标志,其功能如上面 ranges 所述。
accumulate布尔值,累加标志。
当 accumulate 为假,函数左端传入的 Hist 将被清空后,再写入本次直方图统计结果;
当 accumulate 为真,函数左端传入的 Hist 不会被清空,而是直接累加上本次直方图统计结果。
MaskMat 类型的掩码,可选参数,不连接代表全图参与统计。
  • 例2-2:灰度图的直方图统计,自定义非均匀分割区间

在这里插入图片描述

  • 例2-3:将两张彩色图片的 R通道 直方图累加在一起
  • 通道顺序是BGR,所以两张图片R通道的序号分别是2和5;
  • 第一次 calcHist 的 accumulate 参数是真、假都可以,因为传入的 Hist 初始为空矩阵;
  • 但第二次 calcHist 的 accumulate 参数必须为真,才能实现累加。

在这里插入图片描述

  • 例2-4:二维直方图范例
  • channels 同时给定2个通道序号,histSize 和 ranges 指定两组分割区间,将进行二维直方图统计;
  • 假如两组区间数分别为 M 和 N,那么输出的二维直方图尺寸就是 M x N;
  • 每个元素 Hist (i,j) 代表 同时满足 “第1个通道强度值落在第1组的第 i 区间,第2个通道强度值落在第2组的第 j 区间” 的像素数;
  • 不难看出,将二维直方图 “行向累加” 成一列,就是第1个通道的一维直方图;“列向累加” 成一行,就是第2个通道的一维直方图。

在这里插入图片描述


3. 二值化

二值化的任务,是将一张灰度图,按照设定的阈值,转化成仅有黑白两种颜色的单通道图像。

OpenCV中,用 threshold 函数实现灰度图的二值化,简单用法如下:

  • 例3-1:灰度图二值化,阈值127,最大值255,反向模式(大于阈值时置0,小于等于阈值时置最大值)

在这里插入图片描述

  • threshold 参数含义:
参数含义
srcImage源图像
dstImage目标图像,即二值化的结果
thresh阈值
maxval最大值,即二值中的较大值(最小值固定为0)
type转化类型,共 8 种,含义见下表
retValue(返回值)当 type 设为 OTSU 或 TRIANGLE 时,返回自适应的阈值;否则原样返回 thresh 参数值。
type类型含义
THRESH_BINARY阈值二值化模式,大于阈值时置 maxval ,小于等于阈值时置 0
THRESH_BINARY_INV反向阈值二值化模式,大于阈值时置 0 ,小于等于阈值时置 maxval
THRESH_TRUNC截断模式,大于阈值时置 thresh ,小于等于阈值时维持原值
THRESH_TOZERO取零模式,大于阈值时维持原值,小于等于阈值时置 0
THRESH_TOZERO_INV反向取零模式,大于阈值时置 0 ,小于等于阈值时维持原值
THRESH_MASK返回掩码(本类型已不支持,冗余残留)
THRESH_OTSUOTSU 自适应 阈值, 基于区分前景和背景。通常与其他模式叠加使用
THRESH_TRIANGLETRIANGLE 自适应 阈值, 基于寻找直方图双峰之间的谷底。 通常与其他模式叠加使用
  • 例3-2:灰度图二值化,采用OTSU自动确定阈值,再按 THRESH_BINARY_INV 模式转化

在这里插入图片描述


4. 腐蚀、膨胀、开闭运算

腐蚀、膨胀、开闭运算都属于形态学操作,这些通常在二值化图像上进行。通过特殊的滤波规则,实现二值图中白色区域的收缩、扩张、去噪、联通、边缘润滑等效果。先腐蚀后膨胀,称为开运算;先膨胀后腐蚀,称为闭运算。

相关函数如下表:

函数功能
erode腐蚀,白色区域收缩,孤立的小型白色区域(噪声点)甚至完全消失
dilate膨胀, 白色区域扩张,孤立的小型黑色区域(噪声点)甚至完全消失
morphology可实现多种形态学运算,包括腐蚀、膨胀、开运算 和 闭运算(取决于 op 参数)
getStructuringElement生成结构元素(一个小型二维Mat),作为上述运算的滤波 “核”
  • 例4-1:对同一个二值图,用 9x9 的矩形核,分别进行腐蚀、膨胀、开运算
  • 参考范例:examples/Molitec/OpenCV/imgproc/imgproc_3(binary).vi
  • 简单说明参数:
    anchor 是锚点,即 “核” 在图像上移动时的参考点,默认(-1,-1)代表中心点‌;
    iterations 是迭代次数;
    borderType 边界像素外推的方法,默认为 BORDER_CONSTANT ,即常量填充;
    borderValue 边界填充值,默认为 64F 的最大值 1.797693134862E+308 ;
    op 是 morphology 函数独有的参数,定义操作类型。开运算 MORPH_OPEN ,闭运算 MORPH_CLOSE;

在这里插入图片描述

在这里插入图片描述


5. 梯度与轮廓

图像梯度指的是像素强度(灰度)的变化率,可以用来确定图像的边缘轮廓。

OpenCV中,常用的边缘检测函数包括:Canny、Scharr、Sobel 和 Laplacian。

其中 Canny 是个多态VI,包含 image 输入 和 dxdy 输入 两种模式。

  • 例5-1:对同一个灰度图,分别用 Canny、Scharr、Sobel 和 Laplacian 进行梯度计算和边缘检测
  • 参考范例:examples/Molitec/OpenCV/imgproc/imgproc_4(gradient).vi

在这里插入图片描述
在这里插入图片描述

  • 各函数的 params 参数说明
Canny参数含义
threshold1低阈值,像素梯度低于这个阈值的,一定不是边缘。
threshold2高阈值,像素梯度高于这个阈值的,一定是边缘,且为 “强边缘”。
如果介于两个阈值之间,只有与强边缘相邻时,才被视为边缘的一部分。
apertureSizeSobel 算子尺寸,必须取1、3、5 或 7。 默认为3,代表使用 3x3 的卷积核计算梯度。
L2gradient布尔值,为真代表使用L2范数(欧几里得距离),为假代表使用L1范数(曼哈顿距离)
Scharr参数
ddepth目标图像深度(数据类型,如 CV_8U 等),默认为-1,代表与源图像深度相同。
dxx方向的求导阶数。0表示不计算x方向导数。
dyy方向的求导阶数。0表示不计算y方向导数。
scale计算导数时的缩放因子,默认为1。
delta增量值,加到计算出的导数上,默认值为0。
borderType边界类型,默认为 BORDER_DEFAULT,等同于 BORDER_REFLECT_101
Sobel参数
ddepth同上
dx同上
dy同上
ksizeSobel 算子尺寸,必须取1、3、5 或 7。
scale同上
delta同上
borderType同上
Laplacian参数
ddepth同上
ksizeLaplacian 算子尺寸,必须是奇数。
scale同上
delta同上
borderType同上
  • 例5-2:采用 spatialGradient 分别计算dx、dy,再用 Canny 的dxdy模式进行边缘检测
  • 这相当于把 例5-1 的 Canny 计算过程一分为二。

在这里插入图片描述

在经过 Canny、Scharr、Sobel 和 Laplacian 计算之后,我们往往需要把其中的边缘轮廓提取出来,也就是把输出的二值图中 “连续的白色像素” 的坐标连接在一起,形成轮廓线条。

在OpenCV中,可以使用 findContours 提取梯度二值图中的轮廓线条。

  • 例5-3:使用 Canny + findContours 计算梯度并提取轮廓,最后用 drawContours 绘制轮廓
  • findContours 参数
  • mode 定义轮廓检索模式,默认 RETR_EXTERNAL 代表只检索最外层的轮廓;
  • method 定义轮廓近似方法,默认 CHAIN_APPROX_SIMPLE 代表简单近似法;
  • offset 是坐标偏移量,默认(0,0);
  • 输出 contours‌ 是轮廓结果,其中 pts 数组是全部点坐标序列,npts 代表每个轮廓包含的点数,ncontours 代表轮廓个数。这与之前教程(5)中 drawContours 的输入参数定义相同;
  • 输出 hierarchy 代表轮廓的层次结构,是1个(轮廓个数 x 4)的二维数组。每行4个整数,依次代表本行索引号轮廓的 “上一个、下一个、第一个、最后一个” 轮廓的索引号。-1 表示没有。

在这里插入图片描述

在这里插入图片描述

从上图 hierarchy 输出可以分析:
第0行(1,-1,-1,-1)代表0号轮廓的上一个是1号轮廓,下一个是 -1(没有);
第1行(2,0,-1,-1)代表1号轮廓的上一个是2号轮廓,下一个是0号轮廓;
第2行(3,1,-1,-1)代表2号轮廓的上一个是3号轮廓,下一个是1号轮廓;

最终得出,这6个轮廓的先后顺序为:5,4,3,2,1,0


6. 简易绘图

此内容之前已有教程,详见:【秣厉科技】LabVIEW工具包——OpenCV 教程(5):简易绘图


7. 重映射

图像重映射,指的是按照一定规则,重新排布源图像中的像素坐标位置,并渲染到目标图像中。

之前教程提到的 resize 就是一种重映射,用于实现图片的缩放。

  • 例7-1:使用 resize 将源图像尺寸缩小到原来的一半
  • resize 参数
  • dsize:目标图像尺寸。如果 dsize 不为0,输出图像尺寸以 dsize 为准;否则,将由下面的 fx、fy 计算决定;
  • fx:水平方向缩放因子;
  • fy:垂直方向缩放因子;
  • interpolation:插值方法,指的是当放大图像时,填补空缺的方法。默认 ‌INTER_LINEAR 双线性插值法。

在这里插入图片描述

下面,再介绍两种可以扭曲源图像形状的重映射:仿射变换(warpAffine)和 透视变换(warpPerspective)。

  • 例7-2:分别使用 warpAffine 和 warpPerspective,将图片中一块 “四边形” 区域重映射成 “矩形”
  • 参考范例:examples/Molitec/OpenCV/imgproc/imgproc_7(wrap).vi
  • 首先,锚定源图像四边形的4个顶点,再给定输出矩形的4个顶点,将这两组顶点分别输入到 getAffineTransform 和 getPerspectiveTransform 中,运行得到各自的变换矩阵 M;
  • 接着,使用 warpAffine 配合 getAffineTransform 输出的 M,完成仿射变换;
  • 使用 warpPerspective 配合 getPerspectiveTransform 输出的 M,完成透视变换;

在这里插入图片描述

在这里插入图片描述

如果你想完全自定义一种映射关系,即手动给定每一个像素在新图像中的坐标位置,那么可以使用 remap 函数。

  • 例7-3:使用 remap 实现图片的水平翻转
  • remap 函数 VI 的上方需要输入两个 Mat 参数,名称分别为 map1 和 map2,用于逐像素指定映射后的新坐标;
  • 上述 map1 和 map2 有两种组织方式:
    其一,map1 和 map2 都是单通道矩阵,那么 map1 指定所有像素映射之后的X坐标,map2 指定Y坐标;
    其二,map1 是双通道矩阵,那么由 map1 独自指定(X,Y)坐标,而 map2 为空矩阵 即可。
  • 参考范例:examples/Molitec/OpenCV/imgproc/imgproc_6(remap).vi

在这里插入图片描述

顺便一提,如果只是需要进行图片翻转、旋转这样常规的操作,那完全没必要用到 remap。使用 core 模块下的 flip 和 rotate 等函数,就完全可以做到,而且更为简洁。

core 模块下也有不少重映射的方法,感兴趣的读者可以试一试。

在这里插入图片描述


总结

  1. 本系列博文作为LabVIEW工具包—OpenCV的教程,将以专栏的形式陆续发布和更新。
  2. 对工具包感兴趣的朋友,欢迎下载试用:秣厉科技 - LabVIEW工具包 - OpenCV
  3. 各位看官有什么想法、建议、吐槽、批评,或新奇的需求,也欢迎留言讨论。

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

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

相关文章

学习笔记:金融经济学 第3讲

学习笔记:金融经济学 第3讲 注:A本金,n时间(比如年),r利率一、 计算习惯1. 单息(新产生的利息不算进本金重新计算利息,收款额A(1nr) )2. 复利(新产生的利息算进本金重新计…

NVIDIA RTX™ GPU 低成本启动零售 AI 场景开发

零售行业正在探索应用 AI 升级客户体验,同时优化内部流程。面对多重应用场景以及成本优化压力,团队可采用成本相对可控的方案,来应对多重场景的前期项目预演和落地,避免短期内大规模投入造成的资源浪费。 客户体验 AI 场景的研究…

【网络】IP层的重要知识

目录 1.IP层的作用 2.主机和节点 3.网络层和数据链路层的关系 4.路由控制 4.1.路由控制的过程 4.2. IP地址与路由控制 4.3.路由控制表的聚合 4.4.静态路由和动态路由 4.5.动态路由的基础 5.数据链路的抽象化 5.1.数据链路不同,MTU则相异 5.2.路径MTU发…

OpenCV 模板匹配方法详解

文章目录 1. 什么是模板匹配?2. 模板匹配的原理2.1数学表达 3. OpenCV 实现模板匹配3.1基本步骤 4. 模板匹配的局限性5. 总结 1. 什么是模板匹配? 模板匹配(Template Matching)是计算机视觉中的一种基础技术,用于在目…

一键解锁Landsat 9地表温度计算!ENVI与ArcGIS Pro全流程详解(无需NASA大气校正)

为什么选择Landsat 9的L2SP数据? 之前:《ArcGIS与ENVI——基于landsat与Modis影像的遥感技术的生态环境质量评价》,基于Landsat前期的产品计算温度反演数据需要一系列复杂的步骤。 现在: Landsat 8-9的Collection 2 Level-2&…

RK3588的linux下实现HDMI输出分辨率及帧率的裁剪

bug反馈:客户现场反馈hdmi接显示屏出现概率性闪黑屏,排除线材,显示屏及GND等外部因素后,提出尝试降低hdmi的输出分辨率和帧率对比测试看看。 Step1:先直接在linux的sdk中找到板卡编译生成后的dts找到hdmi节点 然后找到…

XR技术赋能艺术展演|我的宇宙推动东方美学体验化

本次广州展览现场引入我的宇宙XR体验模块,通过空间计算与动作捕捉技术,让观众在潮玩艺术氛围中体验虚拟互动,打造“看得懂也玩得动”的展演新场景。 作为科技与文化融合的推动者,我的宇宙正在以“体验科技”为媒介,为潮…

多线程进阶知识篇(二)

文章目录 一、Synchronized 锁二、ReentrantLock 锁三、两阶段终止阶段一:通知终止阶段二:响应中断 四、线程池为什么要使用线程池?如何创建线程池?ExecutorsThreadPoolExecutor 线程池的基本参数 五、线程池处理任务的流程 一、S…

Python深度学习基础——深度神经网络(DNN)(PyTorch)

张量 数组与张量 PyTorch 作为当前首屈一指的深度学习库,其将 NumPy 数组的语法尽数吸收,作为自己处理张量的基本语法,且运算速度从使用 CPU 的数组进步到使用 GPU 的张量。 NumPy 和 PyTorch 的基础语法几乎一致,具体表现为&am…

简单实现单点登录

单点登录 单点登录(Single Sign-On, SSO) SSO是一种统一身份认证技术,用户只需在认证平台登录一次,即可访问所有关联的应用程序或网站,无需重复输入凭据。例如,企业员工登录内部系统后,可直接…

02、GPIO外设(一):基础知识

基础知识 1、ZET6的引脚分布2、引脚输出3、引脚输入4、最大输出速度 1、ZET6的引脚分布 下面使用C8T6的引脚来类比ZET6的引脚,ZET6中的特殊功能引脚和C8T6的特殊功能引脚是一样。而通用IO引脚比C8T6多而已。下面的C8T6的特殊功能引脚的介绍: STM32F103C8…

智能Todo协作系统开发日志(二):架构优化与安全增强

📅 2025年4月14日 | 作者:Aphelios380 🌟 今日优化目标 在原Todo单机版基础上进行三大核心升级: 组件化架构改造 - 提升代码可维护性 本地数据加密存储 - 增强隐私安全性 无障碍访问支持 - 践行W3C标准 一、组件化架构改造 …

【C++初阶】第14课—缝合怪deque和优先队列、仿函数

文章目录 1. 双端队列deque1.1 认识deque1.2 deque的迭代器1.3 deque的常用接口1.4 deque的优缺点 2. 优先队列priority_queue2.1 认识priority_queue2.2 模拟实现优先队列priority_queue 3. 仿函数 在学习deque之前,回顾一下vector和list各自的优缺点 数据结构优点…

方德桌面操作系统V5.0-G23安装Docker并配置DockerHub镜像加速器

为什么要使用debina的docker源,因为查询os-release和uname 显示是基于debina 11的操作系统 rootyuhua-virtualmachine:~# cat /etc/os-release NAME"方德桌面操作系统" NAME_EN"NFSDesktop" VERSION"5.0" VERSION_ID"5.0"…

紫光同创FPGA实现HSSTLP光口视频点对点传输,基于Aurora 8b/10b编解码架构,提供6套PDS工程源码和技术支持

目录 1、前言工程概述免责声明 2、相关方案推荐我已有的所有工程源码总目录----方便你快速找到自己喜欢的项目紫光同创FPGA相关方案推荐我这里已有的 GT 高速接口解决方案Xilinx系列FPGA实现GTP光口视频传输方案推荐Xilinx系列FPGA实现GTX光口视频传输方案推荐Xilinx系列FPGA实…

数字孪生城市技术应用典型实践案例汇编(22个典型案例)(附下载)

近年来,数字孪生技术在我国从战略框架逐步向系统性落地推进,成为推动数字中国建设的重要技术引擎。随着《数字中国建设整体布局规划》《"十四五"数字经济发展规划》《深化智慧城市发展推进城市全域数字化转型的指导意见》等政策的实施&#xf…

Hyperf (Swoole)的多进程 + 单线程协程、Gin (Go)Go的单进程 + 多 goroutine 解说

1. 核心概念解析 (1) Hyperf (Swoole): 多进程 单线程协程 Swoole 并发模型详解 Swoole 的并发模型基于多进程架构,每个进程是单线程的,线程内运行多个协程。以下是其结构的关键点: 多进程:Swoole 应用程序启动时,…

Intel(R) Wi-Fi 6 AX201 160MHz

本文来源 : 腾讯元宝 ​​Intel(R) Wi-Fi 6 AX201 160MHz​​ 是一款支持最新 Wi-Fi 6(802.11ax)标准的无线网卡,专为现代笔记本电脑和台式机设计。以下是其主要特点和规格: ​​主要特性:​​ ​​Wi-Fi …

Java 工厂设计模式详解:用统一入口打造灵活可扩展的登录系统----掌握 Spring 源码的基础第一步

一、前言 在实际开发中,我们经常面临以下场景: 系统支持多种登录方式(用户名密码、管理员登录、OAuth 登录、短信登录等) 每种登录方式的认证逻辑不同 我们希望对外提供一个统一的接口调用,而不暴露具体实现 这个…

Spring Boot管理Spring MVC

Spring Boot真正的核心功能是自动配置和快速整合,通常Spring Boot应用的前端MVC框架依然使用Spring MVC。Spring Boot提供的spring-boot-starter-web启动器嵌入了Spring MVC的依赖,并为Spring MVC提供了大量自动配置,可以适用于大多数Web开发…