2.12 滑动条事件

news2024/11/12 5:01:17

目录

实验原理

实验代码

运行结果


实验原理

在 OpenCV 中,滑动条设计的主要目的是在视频播放帧中选择特定帧,而在调节图像参数时也会经常用到。在使用滑动条前,需要给滑动条赋予一个名字(通常是一个字符串),接下来将直接通过这个名字进行引用。 

创建滑动条的函数是 createTrackbar,函数声明如下:

int createTrackbar(const string& trackbarname, 
    const string& winname, int* value, int count, 
    TrackbarCallback onChange=0, void* userdata=0)


其中参数
trackbarname 是滑动条的名称;
winname 是滑动条将要添加到父窗口的名称,一旦滑动条创建好,它将被添加到窗口的顶部或底部,滑动条不会挡住任何已经在窗口中的图像,只会让窗口变大,窗口的名称将作为一个窗口的标记,至于滑动条上滑动按钮的确切位置,由操作系统决定,一般都是在最左边;
value 是一个指向整数的指针,这个整数值会随着滑动按钮的移动自动变化;
count 是滑动条可以滑动的最大值;
onChange 是一个指向回调函数的指针,当滑动按钮移动时,回调函数就会自动调用;
userdata 可以是任何类型的指针,一旦回调函数执行,这个参数可以传递给回调函数的 userdata 参数,这样不创建全局变量也可以处理滑动条事件。

回调函数类型 TrackbarCallback 的定义如下:

typedef void(* cv::TrackbarCallback) (int pos, void *userdata);

其中参数 
pos表示滚动块的当前位置;
userdata是传给回调函数的可选参数。这个回调函数不是必需的,如果直接赋值为 NULL,就没有回调函数,移动滑动按钮的唯一响应就是 createTrackbar的参数 value 指向的变量值的变化。 

除了创建滑动条的函数外,OpenCV 还提供了函数 getTrackbarPos 用于获取滑动块的位置和函数 setTrackbarPos 用于设置滑动条的位置。函数 getTrackbarPos 声明如下: 

int getTrackbarPos(const string& trackbarname, const string& winname);

其中参数 
trackName 是滑动条的名称,
windowName 是滑动条将要添加到父窗口的名称。
函数返回滑动块的当前位置。 

函数 setTrackbarPos 声明如下:

void setTrackbarPos(const string& trackbarname, const string& winname, int pos);

其中参数 
trackName 表示滚动条的名称,
windowName 是滑动条将要添加到父窗口的名称,
pos表示要设置的滑动块位置。

erode() 函数用于执行图像的腐蚀操作。腐蚀是一种形态学变换,主要用于去除图像中的小斑点噪声、平滑边界、分离粘连的目标物体等。腐蚀操作的基本思想是使用一个结构元素(structuring element)来探测图像中的每个像素点及其周围区域,根据结构元素的位置和形状来决定是否保留中心像素点。

void erode(InputArray src, OutputArray dst, 
  InputArray kernel, Point anchor=Point(-1,-1),
  int iterations=1, int borderType=BORDER_CONSTANT,
  const Scalar& borderValue=Scalar());

参数说明
src: 输入图像。
dst: 输出图像,必须与输入图像具有相同的类型和尺寸。
kernel: 结构元素,定义了如何进行局部操作。可以通过getStructuringElement()函数创建。
anchor: 结构元素的锚点位置,默认为结构元素的中心。
iterations: 腐蚀操作的迭代次数,默认为1。更大的迭代次数会导致更强的腐蚀效果。
borderType: 边界类型,指定了图像边界外的像素如何处理,默认为BORDER_CONSTANT,即常数值。
borderValue: 当边界类型为BORDER_CONSTANT时,指定的常数值。

dilate()函数用于执行图像的膨胀操作。膨胀是另一种形态学变换,主要用于填充目标物体中的小孔洞、扩展边界、连接相邻的目标物体等。膨胀操作的基本思想是使用一个结构元素(structuring element)来探测图像中的每个像素点及其周围区域,根据结构元素的位置和形状来决定是否将中心像素点标记为前景。

void dilate(InputArray src, OutputArray dst, 
        InputArray kernel, Point anchor=Point(-1,-1), 
        int iterations=1, int borderType=BORDER_CONSTANT, 
        const Scalar& borderValue=Scalar());

参数说明
src: 输入图像。
dst: 输出图像,必须与输入图像具有相同的类型和尺寸。
kernel: 结构元素,定义了如何进行局部操作。可以通过getStructuringElement()函数创建。
anchor: 结构元素的锚点位置,默认为结构元素的中心。
iterations: 膨胀操作的迭代次数,默认为1。更大的迭代次数会导致更强的膨胀效果。
borderType: 边界类型,指定了图像边界外的像素如何处理,默认为BORDER_CONSTANT,即常数值。
borderValue: 当边界类型为BORDER_CONSTANT时,指定的常数值。

getStructuringElement()函数用于生成一个结构元素(structuring element),这是进行形态学操作(如腐蚀、膨胀、开运算、闭运算等)时必需的一个组件。结构元素定义了如何对图像中的每个像素点及其邻居进行处理。

Mat getStructuringElement(int shape, Size ksize, Point anchor=Point(-1,-1))

参数说明
shape: 结构元素的形状,可以是以下几种之一:
    MORPH_RECT:矩形结构元素。
    MORPH_CROSS:十字形结构元素。
    MORPH_ELLIPSE:椭圆形结构元素。
    MORPH_RECT是最常用的形状,因为它简单且易于理解。
    MORPH_CROSS和MORPH_ELLIPSE则可能在某些情况下提供更好的性能或特定的应用效果。

ksize: 结构元素的大小,由一个Size对象定义,通常是一个奇数大小的正方形。例如,Size(3, 3)表示3x3大小的结构元素。

anchor: 结构元素的锚点位置,默认为结构元素的中心。锚点位置决定了结构元素相对于图像中的每个像素点的位置。如果设置了Point(-1, -1),则默认使用结构元素的中心作为锚点。


返回值
返回一个Mat对象,代表生成的结构元素。

实验代码

本例利用滑动块调节设置参数——利用滑动块控制腐蚀和膨胀。


#include "pch.h" // 预编译头文件
#include <opencv2/highgui/highgui_c.h> // 包含旧版的highgui模块
#include <opencv2\opencv.hpp> // 包含整个OpenCV库
//#pragma comment(lib, "opencv_world450d.lib")  //引用引入库 
using namespace cv;// 使用OpenCV命名空间
#include<iostream>// 输入输出流
using namespace std;// 使用标准命名空间

Mat src, erosion_dst, dilation_dst;// 定义三个Mat对象,分别存储源图像、腐蚀后的图像和膨胀后的图像
int erosion_elem = 0; // 腐蚀操作核类型,默认为0(矩形)
int erosion_size = 0; // 腐蚀操作核大小,默认为0
//假设你正在使用一个3x3的方形结构元素进行腐蚀操作,那么erosion_size就是3
int dilation_elem = 0;// 膨胀操作核类型,默认为0(矩形)
int dilation_size = 0;// 膨胀操作核大小,默认为0
int const max_elem = 2;// 最大的操作核类型数(矩形、十字形、椭圆)
int const max_kernel_size = 21;// 最大的操作核大小
void Erosion(int, void*);//腐蚀滑动条的回调函数
void Dilation(int, void*);//膨胀滑动条的回调函数
int main(int argc, char** argv)
{
	src = imread("0901.jpg", IMREAD_COLOR);// 读取图像文件
	if (src.empty())// 检查图像是否正确加载
	{
		cout << "Could not open or find the image!\n" << endl;
		//cout << "无法打开或找到图像!\n";
		cout << "Usage: " << argv[0] << " <Input image>" << endl;
		//cout << "用法: " << argv[0] << " <输入图像>\n";
		return -1;
	}
	namedWindow("Erosion Demo", WINDOW_NORMAL);//腐蚀演示窗口 WINDOW_AUTOSIZE
	namedWindow("Dilation Demo", WINDOW_NORMAL);//膨胀演示窗口 WINDOW_NORMAL
	//moveWindow("Dilation Demo", src.cols, 0);// 移动膨胀演示窗口到屏幕的适当位置
	//怕此处 腐蚀窗口与膨胀窗口重合

	/*createTrackbar("Element:\n 0: Rect \n 1: Cross \n 2: Ellipse", "Erosion Demo",
		&erosion_elem, max_elem,
		Erosion);*/
	createTrackbar("元素:\n 0: 矩形 \n 1: 十字形 \n 2: 椭圆", "Erosion Demo", &erosion_elem, max_elem, Erosion); 
    // 创建腐蚀操作核类型的滚动条
	/*createTrackbar("Kernel size:\n 2n +1", "Erosion Demo",
		&erosion_size, max_kernel_size,
		Erosion);*/
	createTrackbar("核大小:\n 2n +1", "Erosion Demo", &erosion_size, max_kernel_size, Erosion);  
	// 创建腐蚀操作核大小的滚动条
	
	/*createTrackbar("Element:\n 0: Rect \n 1: Cross \n 2: Ellipse", "Dilation Demo",
		&dilation_elem, max_elem,
		Dilation);*/
	createTrackbar("元素:\n 0: 矩形 \n 1: 十字形 \n 2: 椭圆", "Dilation Demo", &dilation_elem, max_elem, Dilation); 
	// 创建膨胀操作核类型的滚动条
	/*createTrackbar("Kernel size:\n 2n +1", "Dilation Demo",
		&dilation_size, max_kernel_size,
		Dilation);*/
	createTrackbar("核大小:\n 2n +1", "Dilation Demo", &dilation_size, max_kernel_size, Dilation); 
	// 创建膨胀操作核大小的滚动条
	Erosion(0, 0);// 初始化腐蚀操作
	Dilation(0, 0);// 初始化膨胀操作
	waitKey(0);// 等待按键事件
	return 0;
}

void Erosion(int, void*)
{
	int erosion_type = 0;// 初始化腐蚀类型为矩形
	if (erosion_elem == 0)
	{
		erosion_type = MORPH_RECT; // 初始化腐蚀类型为矩形
	}
	else if (erosion_elem == 1)
	{
		erosion_type = MORPH_CROSS;// 如果选择十字形
	}
	else if (erosion_elem == 2)
	{
		erosion_type = MORPH_ELLIPSE; // 如果选择椭圆
	}
	Mat element = getStructuringElement(erosion_type,
		Size(2 * erosion_size + 1, 2 * erosion_size + 1),
		Point(erosion_size, erosion_size));// 获取腐蚀操作核
	erode(src, erosion_dst, element);// 对图像进行腐蚀操作
	imshow("Erosion Demo", erosion_dst);// 显示腐蚀后的图像
}
void Dilation(int, void*)
{
	int dilation_type = 0;// 初始化膨胀类型为矩形
	if (dilation_elem == 0)
	{
		dilation_type = MORPH_RECT; // 初始化膨胀类型为矩形
	}
	else if (dilation_elem == 1) 
	{ 
		dilation_type = MORPH_CROSS;// 初始化膨胀类型为十字形
	}
	else if (dilation_elem == 2)
	{ 
		dilation_type = MORPH_ELLIPSE; // 初始化膨胀类型为椭圆
	}
	Mat element = getStructuringElement(dilation_type,
		Size(2 * dilation_size + 1, 2 * dilation_size + 1),
		Point(dilation_size, dilation_size));// 获取腐蚀操作核
	dilate(src, dilation_dst, element);// 对图像进行膨胀操作
	imshow("Dilation Demo", dilation_dst);// 显示膨胀后的图像
}  

在代码中,首先读取 0901.jpg,然后利用函数namedWindow 创建两个窗口。接着利用函数createTrackbar 创建 4 个滑动条,每个窗口上两个滑动条(核的类型 和 核的大小)。Erosion 和 Dilation 都是滑动条的回调函数,用于响应用户滑动按钮这个事件。 
函数 erode 和 dilate 分别是 OpenCV 中腐蚀和膨胀图像的函数,图像腐蚀和膨胀是图像学中的两个基本概念。 

运行结果

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

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

相关文章

Java | Leetcode Java题解之第388题文件的最长绝对路径

题目&#xff1a; 题解&#xff1a; class Solution {public int lengthLongestPath(String input) {int n input.length();int pos 0;int ans 0;int[] level new int[n 1];while (pos < n) {/* 检测当前文件的深度 */int depth 1;while (pos < n && inpu…

Mamba:超越Transformer的新一代神经网络架构

在过去的七年里&#xff0c;Transformer一直在语言建模领域占据着主导地位。然而&#xff0c;现在有一个新兴的神经网络架构Mamba&#xff0c;正在挑战Transformer的霸主地位。虽然目前Mamba仅在规模较小的模型上进行了测试&#xff08;参数量达到数十亿&#xff09;&#xff0…

华为OD机试真题 - 构成正方形的数量(Java/Python/JS/C/C++ 2024 B卷 100分)

华为OD机试 2024E卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;E卷D卷A卷B卷C卷&#xff09;》。 刷的越多&#xff0c;抽中的概率越大&#xff0c;私信哪吒&#xff0c;备注华为OD&#xff0c;加…

MySQL密码策略更改(临时+永久)

目录 1、查看数据库当前密码策略 2、查看密码插件&#xff1a; 3、官方文档策略定义 4、更改密码策略 临时修改 &#xff08;1&#xff09;更改密码策略为LOW&#xff0c;改为LOW或0 &#xff08;2&#xff09;更改密码长度 &#xff08;3&#xff09;设置大小写、数字…

【操作系统】操作系统运行环境——中断与异常

中断与异常 导读一、中断机制1.1 中断机制的重要性 二、中断与异常的基本概念2.1 中断与异常的个人理解2.2 内中断与外中断 三、中断与异常的分类四、中断与异常的处理过程结语 导读 大家好&#xff0c;很高兴又和大家见面啦&#xff01;&#xff01;&#xff01; 在上一篇内…

【C++ | 设计模式】简单工厂模式的详解与实现

1.简单工厂模式概述 简单工厂模式&#xff08;Simple Factory Pattern&#xff09;是一种创建型设计模式&#xff0c;它定义了一个工厂类&#xff0c;由这个类根据提供的参数决定创建哪种具体的产品对象。简单工厂模式将对象的创建逻辑集中到一个工厂类中&#xff0c;从而将对…

认知杂谈32

今天分享 有人说的一段争议性的话 I I 《恋爱中的价值难题》 咱就认识个31岁的哥们&#xff0c;事业有成&#xff0c;一年能挣35 万。他现在正为找对象的事儿犯愁呢。他想找个年轻漂亮的小姑娘谈对象&#xff0c;可又不想在感情上投入太多&#xff0c;就想一边乐呵着&#x…

Linux(CentOS)同步服务器时间之~ntpd

NTP 是 Network Time Protocol&#xff08;网络时间协议&#xff09;的缩写&#xff0c;它是一种用于在计算机系统之间同步时间的协议。NTP 允许网络中的设备通过与一个或多个时间服务器进行通信&#xff0c;来校正自身的系统时钟&#xff0c;确保所有设备上的时间保持高度一致…

演示:基于WPF的DrawingVisual和谷歌地图瓦片开发的地图(完全独立不依赖第三方库)

一、目的&#xff1a;基于WPF的DrawingVisual和谷歌地图瓦片开发的地图 二、预览 三、环境 VS2022&#xff0c;Net7,DrawingVisual&#xff0c;谷歌地图瓦片 四、主要功能 地图缩放&#xff0c;平移&#xff0c;定位 真实经纬度 显示瓦片信息 显示真实经纬度和经纬线 省市县…

[环境配置]Pycharm手动安装汉化插件

在Pycharm-file-setting-Plugins中&#xff0c;搜索chinese&#xff0c;就会出现汉化包 点击install后&#xff0c;在安装时出现这种报错&#xff1a;Plugin "Chinese (Simplified) Language Pack / 中文语言包" was not installed: Invalid filename returned by a …

用 jsPDF 让 PDF 生成触手可及

jsPDF &#xff1a;在浏览器中生成 PDF&#xff0c;从未如此简单- 精选真开源&#xff0c;释放新价值。 概览 jsPDF 是一个开源的 JavaScript 库&#xff0c;专为在浏览器端生成 PDF 文档而设计。它通过提供一个直观且易于使用的 API&#xff0c;使得开发者能够快速地将 PDF 生…

【Kubernetes】持久卷 PV

持久卷 PV 1.什么是持久卷2.创建一个持久卷3.持久卷的访问模式4.持久卷的回收策略 数据卷是在创建 Pod 时通过 挂载目录 来实现数据的共享和持久化的。但是在一个大型系统中&#xff0c;这种方式是非常不利于管理的&#xff0c;因为数据卷把数据的 持久存储 和 供应使用 封装在…

短时傅里叶变换(Short-Time Fourier Transform, STFT),语音识别

高能预警&#xff01;&#xff01;&#xff01; .wav文件为笔者亲自一展歌喉录制的噪声&#xff0c;在家中播放&#xff0c;可驱赶耗子&#xff0c;蟑螂 介绍 短时傅里叶变换&#xff08;Short-Time Fourier Transform, STFT&#xff09;是一种时频分析方法&#xff0c;用于…

智能分拣投递机器人

产品介绍 自研智能分拣投递机器人&#xff0c;专注于物流行业“NC小件”的分拣与投递&#xff0c;机器人运行稳定、分拣效率高&#xff0c;搭配智能分拣投递系统单台机器人最大作业效率可达400件/H&#xff0c;投递效率相较于传统“小黄人“提升了30%-50%&#xff0c;可替代“…

生成艺术,作品鉴赏:物似主人形

2001年&#xff0c;当21岁的我&#xff0c;还在恒基伟业当高级工程师时。我有一个女同事&#xff0c;她有个特别大的杯子用来喝水&#xff0c;不夸张的说&#xff0c;是那种我从来没见过的大杯子&#xff0c;由于她是很大只的那种&#xff0c;她便自嘲说&#xff1a;「物似主人…

RAG增强的视觉问答开发框架

检索增强生成 (RAG) 是一种强大的技术&#xff0c;可以提高大型语言模型 (LLM) 生成的答案的准确性和可靠性。它还提供了检查模型在特定生成过程中使用的源的可能性&#xff0c;从而使人类用户更容易进行事实核查。此外&#xff0c;RAG 可以使模型知识保持最新状态并整合特定主…

前端进阶| 深入学习面向对象设计原则

引言 面向对象编程&#xff08;Object-Oriented Programming&#xff0c;OOP&#xff09;是一种常用的编程范式&#xff0c;它通过将数据和与之相关的操作封装在一起&#xff0c;提供了一种更有组织和易于理解的方式来构建应用程序。在JavaScript中&#xff0c;我们可以使用面…

【持续更新】【Google Play版】淘宝最新国际版10.36.10.20启动更快

功能和国内比基本是差不多的&#xff0c;只不过没有应用内乱七八糟的弹窗&#xff0c;用起来比较舒服&#xff0c;启动也比较快。 像这种软件如何保证是 官方 的呢&#xff1f;毕竟涉及到财产&#xff0c;还是要小心些的。 很简单&#xff0c;修改过的 app 会提示“签名不一致…

Unity本地化id查找器,luaparser函数参数查找

前言&#xff1a; 适用范围&#xff1a;Unity 中需要查找所有预制体里面的某一个脚本的属性值&#xff0c;或者Lua脚本里面的某一个属性值 本文介绍如何查找预制体和Lua脚本里面调用的本地化id 下面首先介绍改插件的功能以及使用方法&#xff0c;然后对该插件的原理进行说明 使…

SOMEIP_ETS_075: Wrong_Message_Type

测试目的&#xff1a; 验证当设备&#xff08;DUT&#xff09;接收到一个包含错误消息类型的SOME/IP请求时&#xff0c;是否能够返回错误消息或忽略该请求。 描述 本测试用例旨在检查DUT在处理一个echoUINT8方法的SOME/IP消息时&#xff0c;如果消息中包含的消息类型不正确&…