opencv入门四

news/2024/4/30 0:21:15/文章来源:https://blog.csdn.net/m0_53421868/article/details/126676665

目录

  • 鼠标操作与响应
  • 图像像素归一化
  • 类型转换
  • 图像放缩插值

鼠标操作与响应

static void on_draw(int event, int x, int y, int flags,  void* userobj)
{Mat image = *(Mat*)userobj;if (event == EVENT_LBUTTONDOWN) {//鼠标点击时	sp.x = x;sp.y = y;std::cout << "start:"  << sp << std::endl;}if (event == EVENT_LBUTTONUP) {//鼠标抬起后ap.x = x;ap.y = y;int dx = ap.x - sp.x;int dy = ap.y - sp.y;if (dx > 0 && dy > 0) {Rect box(sp.x, sp.y, dx, dy);//绘制矩形rectangle(image, box, Scalar(0,0,255), 1, 8, 0);imshow("绘制后", image);}std::cout << "end:"  << sp << std::endl;}}void QuickDemo::mouse_drawing_demo(Mat& image)
{namedWindow("绘制前", WINDOW_AUTOSIZE);imshow("绘制前", image);//设置回调机制setMouseCallback("绘制前",on_draw, (void*)(&image));
}

在这里插入图片描述

一个屏幕上只绘制一张图像,当鼠标移动的时候自动清空屏幕


Point sp(-1, -1);
Point ap(-1, -1);
Mat tmp;static void on_draw(int event, int x, int y,int flags, void* userobj)
{Mat image = *(Mat*)userobj;if (event == EVENT_LBUTTONDOWN) {sp.x = x;sp.y = y;std::cout << "start: " << sp << std::endl;}//鼠标松开时确定结尾位置,并绘制矩形else if (event == EVENT_LBUTTONUP) {ap.x = x;ap.y = y;int dx = ap.x - sp.x;int dy = ap.y - sp.y;if (sp.x > 0 && sp.y > 0) {Rect box(sp.x, sp.y, dx, dy);rectangle(image, box, Scalar(0, 0, 255), 2, 8, 0);imshow("绘制前", image);//绘制完清空sp.x = -1;sp.y = -1;}std::cout << "end: " << ap << std::endl;}//当鼠标移动的时候会清空屏幕else if (event == EVENT_MOUSEMOVE) {tmp.copyTo(image);	//清除屏幕}
}void QuickDemo::mouse_drawing_demo(Mat& image)
{namedWindow("绘制前", WINDOW_AUTOSIZE);imshow("绘制前", image);//设置回调机制setMouseCallback("绘制前",on_draw,(void *)(&image));tmp = image.clone();
}

在这里插入图片描述

提取图像框选中部分

Point sp(-1, -1);
Point ap(-1, -1);
Mat tmp;static void on_draw(int event, int x, int y,int flags, void* userobj)
{Mat image = *(Mat*)userobj;if (event == EVENT_LBUTTONDOWN) {sp.x = x;sp.y = y;std::cout << "start: " << sp << std::endl;}//鼠标松开时确定结尾位置,并绘制矩形else if (event == EVENT_LBUTTONUP) {ap.x = x;ap.y = y;int dx = ap.x - sp.x;int dy = ap.y - sp.y;if (sp.x > 0 && sp.y > 0) {	//防止越界访问Rect box(sp.x, sp.y, dx, dy);rectangle(image, box, Scalar(0, 0, 255), 2, 8, 0);imshow("绘制前", image);if (dx > 0 && dy > 0) {  //防止越界访问tmp.copyTo(image);	//清楚红边框imshow("ROT截取", image(box));}sp.x = -1;sp.y = -1;std::cout << "end: " << ap << std::endl;}}//当鼠标移动的时候会清空屏幕else if (event == EVENT_MOUSEMOVE) {tmp.copyTo(image);	//清除屏幕}
}void QuickDemo::mouse_drawing_demo(Mat& image)
{namedWindow("绘制前", WINDOW_AUTOSIZE);imshow("绘制前", image);//设置回调机制setMouseCallback("绘制前",on_draw,(void *)(&image));tmp = image.clone();
}

展示效果:

在这里插入图片描述

绘制圆形

Point p(-1, -1);
Mat tmp;
static void on_draw(int event, int x, int y ,int flags, void *userobj) 
{Mat image = *(Mat*)userobj;if (event == EVENT_LBUTTONDOWN) {p.x = x;p.y = y;std::cout << "start: " << p << std::endl;}else if (event == EVENT_LBUTTONUP) {circle(image, p, 80,  Scalar(0,0,255), -1);imshow("绘制前", image);}else if(event == EVENT_MOUSEMOVE){tmp.copyTo(image);	//清空屏幕}
}void QuickDemo::mouse_drawing_demo(Mat& image)
{namedWindow("绘制前", WINDOW_AUTOSIZE);imshow("绘制前", image);//设置回调机制setMouseCallback("绘制前",on_draw,(void *)(&image));tmp = image.clone();
}

鼠标点击某一个点会自动画一个圆形

在这里插入图片描述

图像像素归一化

  • opencv中提供了四种归一化的方式
  • NORM_MINMAX
  • NORM_INF
  • NORM_L1
  • NORM_L2

注:最常用的是NORM_MINMAX归一化方法

 void normalize(InputArray src,	//输入图像OutputArray dst,   //输出图像 double alpha = 1,  //NORM_MINMAX时候最低值double beta = 0,   //NORM_MINMAX时候最高值 int norm_type = NORM_L2,  //只有alphaint dtype = -1, 	//默认类型与src一致InputArray mask = noArray() //mask默认值为空)

类型转换

  • CV_8UC3:3通道每个通道都是RGB 通道 ,每个通道的取值范围是[0, 255],每个通道是8位无符号字节数据类型。
  • CV_32F3:3通道每个通道都是RGB 通道 ,每个通道的取值范围是[0, 4294967295],每个通道是32位浮点数数据类型。
void QuickDemo::norm_demo(Mat& image) 
{Mat dst;  //存储转换后的结果std::cout << image.type() << std::endl;  //CV_8UC3image.convertTo(dst, CV_32FC3);std::cout << dst.type() << std::endl;    //CV_32FC3
}

使用normalize函数做归一化处理需要先将CV_8UC3字节类型的图像像素转换为浮点型处理, 因为归一化处理之后的数据范围都在[0, 1]之间,需要用到浮点数保存

void QuickDemo::norm_demo(Mat& image) 
{Mat dst;  //存储转换后的结果std::cout << image.type() << std::endl;  //CV_8UC3image.convertTo(image, CV_32FC3);std::cout << image.type() << std::endl;    //CV_32FC3normalize(image, dst, 1.0, 0,NORM_MINMAX);  //做归一化处理std::cout << dst.type() << std::endl;imshow("类型转换CV_32FC3之后", image);imshow("归一化处理之后", dst);
}

将CV_8UC3类型的数据转换成CV_32FC3数据类型后,可以看出图像的像素类型变了之后,与之前的差异比较大,可是做完归一化处理之后在肉眼观察基本上跟原图没有啥区别。

在这里插入图片描述

图像放缩插值

void QuickDemo::resize_demo(Mat& image) 
{Mat zoomin, zoomout;  //放大缩小对象int h = image.rows;  //行int w = image.cols;	 //列//按照宽高进行缩小resize(image, zoomout, Size(h / 2, w / 2));imshow("缩小", zoomout);//按照宽高进行放大resize(image, zoomin, Size(h * 1.5, w * 1.5));imshow("放大", zoomin);
}

鼠标滚动事件缩小和放大窗口

原理

  • 其中scale可以在外部定义为全局变量,通过响应CV_EVENT_MOUSEWHEEL滑轮事件获取Scale的具体值。

  • 获取Scale值需要关注两个问题,滑轮滑动的方向和滑动量的大小。滑动方向通过getMouseWheelDelta(flags)获取,

  • 当返回值>0时,表示向前滑动;

  • 当返回值<0时,表示向后滑动。滑动量根据滑动方向自行设置相应的滑动步长即可。

void call_back(int event, int x, int y, int flags, void*userobj) 
{Mat src = *(Mat*)userobj;Mat zoominout;int h = src.rows;int w = src.cols;//获取滚动事件if (event == cv::EVENT_MOUSEWHEEL) {//获取鼠标上下滚动时的值int Scale = getMouseWheelDelta(flags);if (Scale > 0) {Scale = Scale / 120 + 1.5;  //放大1.5倍resize(src, zoominout, Size(h * Scale, w * Scale), INTER_LINEAR);}if (Scale < 0) {Scale = abs(Scale / 120) + 1;  //缩小2倍resize(src, zoominout, Size(h / Scale, w / Scale), INTER_LINEAR);}imshow("触发后", zoominout);}
}void QuickDemo::mouse_resize_demo(Mat& image)
{namedWindow("鼠标触发事件", WINDOW_AUTOSIZE);setMouseCallback("鼠标触发事件", call_back, (void *)(&image));imshow("鼠标触发事件", image);
}

将鼠标悬浮在鼠标触发事件窗口上,可以使用鼠标的滚轮进行放大和缩小

在这里插入图片描述

createTrackbar 创建滚动条的方式调整图片大小

Mat dst, m, src;
void on_track1(int val, void *userobj)
{int h = src.rows;int w = src.cols;resize(src, dst, Size(h + val, w + val), INTER_LINEAR);imshow("调整后", dst);
}void QuickDemo::mycreateTrackbar(Mat& image) {int val = 50;dst = Mat::zeros(image.size(), image.type());m = Mat::zeros(image.size(), image.type());src = image.clone();	//深拷贝namedWindow("调整", WINDOW_AUTOSIZE);//当滚动按钮被拖动的时候,on_track函数会去调整光的亮度createTrackbar("调整", "调整", &val,200, on_track1, (void *)&image);on_track1(50, 0);		//固定写法imshow("调整", image);
}

在这里插入图片描述

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

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

相关文章

预科知识1-MarkDown语法

MarkDown语法的基本操作markdown 标题 方法:#(几个)+空格+内容 三级标题 四级标题 字体 方法:加粗(2个星号 内容 2个星号) 斜体(1个星号 内容 1个星号) 加粗斜体(3个星号 内容 3个星号) 删除线(2个波浪 内容 2个波浪) hello world hello world …

在线教育项目【前端路由和Ajax实现分析与后端连接分析】

目录 1&#xff0c;前端路由实现分析 1.1&#xff1a;入口文件中调用路由 1.2&#xff1a;定义路由模块 1.3&#xff1a;编写路由模块文件 1.3.1&#xff1a;配置一个或者多个子路由 1.3.2&#xff1a;编写教师路由对应的文件 2&#xff0c;后端接口分析&#xff08;与后…

查询数字的最邻近

这道题目要用二分+桶排的方式解决 函数: l~r找v c:靠左/右(‘l’/‘r’) 靠左和靠右用STL函数二分就行,这里讲一下思路,二分出最靠左/右的v值(but二维,在but[v][0~len]区间二分)再判断是否在区间内在区间内输出but[v][a](a为二分的答案)否则输出-1。 最后再考虑一下需要…

注解Annotation

注解是一种引用数据类型,重点掌握Deprecated(表示已过时),Override(表示重写)。 元注解是用来标注注解类型的注解如Target(用来标注注解可以出现在哪些位置)、Retention(用来标注最终保存到哪里)。 package com.javastudy.example13;import java.lang.annotation.Ann…

计算机毕业设计php+vue基于微信小程序的员工宿舍报修系统

项目介绍 随着信息技术和网络技术的飞速发展&#xff0c;人类已进入全新信息化时代&#xff0c;传统管理技术已无法高效&#xff0c;便捷地管理信息。为了迎合时代需求&#xff0c;优化管理效率&#xff0c;各种各样的管理系统应运而生&#xff0c;各行各业相继进入信息管理时…

神奇的卡尔曼滤波,目标追踪的福音

前言 卡尔曼滤波算法由匈牙利数学家Kalman提出&#xff0c;主要基于线性系统提出。这里我们将其用于汽车跟踪&#xff0c;并对其基本原理进行介绍。 神奇的卡尔曼滤波&#xff0c;目标追踪的福音 1. 背景知识 1.1 时间序列模型 1.2. 滤波 1.3. 线性动态系统 2. 卡尔曼滤波…

python生成PDF报告

如何使用Python制作pdf文档&#xff1f; PDF报告生成软件开发&#xff08;学习记录&#xff09; Python生成图文并茂的PDF报告 官方用户手册 字体下载注册问题 在windows找到字体文件&#xff1a;C:\Windows\Fonts 在你的python环境引入字体 D:\devementtool\Anaconda3-202…

Java并发 JUC工具类:Semaphore详解

文章目录Semaphore源码分析类的继承关系类的内部类类的内部类 - Sync类类的内部类 - NonfairSync类类的内部类 - FairSync类类的属性类的构造函数核心函数分析 - acquire函数核心函数分析 - release函数Semaphore 示例更深入理解单独使用Semaphore是不会使用到AQS的条件队列的场…

USB4 V2.0即将发布,速度高达80Gbps

关注星标公众号&#xff0c;不错过精彩内容作者 | strongerHuang微信公众号 | strongerHuang2019年3月初&#xff0c;USB-IF组织官方宣布了下一代 USB4.2019年9月3日&#xff0c;USB-IF组织正式发布 USB4(现在称USB4 V1.0)规范。最近&#xff0c;也就是2022年9月1日&#xff0c…

推荐系统中的特征工程

摘要&#xff1a;深度学习时期&#xff0c;与CV、语音、NLP领域不同&#xff0c;搜推广场景下特征工程仍然对业务效果具有很大的影响&#xff0c;并且占据了算法工程师的很多精力。数据决定了效果的上限&#xff0c;算法只能决定逼近上限的程度&#xff0c;而特征工程则是数据与…

uniapp 之 获取底部安全距离,状态栏高度等

特定样式注意点固定底部按钮自定义顶部导航栏其他工作中我们常常需要设置一些特定样式&#xff1a; 固定底部按钮自定义顶部导航栏…… 固定底部按钮 这里需要注意的是&#xff0c;真机运行时底部时IOS是存在安全距离的&#xff0c;这个时候就需要我们处理一下 .u-fixed-b …

Echarts y轴相关配置

目录1 简介2 y轴配置2.1 y轴主要属性2.2 y轴刻度设置3.总结1 简介 本篇介绍我们在使用Echarts画图时常用的一些y轴坐标设置&#xff0c;如y轴位置&#xff0c;y轴偏移量、y轴刻度、y轴最大最小值等&#xff1b; 2 y轴配置 2.1 y轴主要属性 只有一个纵坐标的情况下&#xff0…

TLM通信总结1

事务级建模 (TLM) 用于模块之间的通信。 TLM 是实现基于事务的方法的概念,这些方法可用于模块之间的通信。 UVM TLM UVM 为 TLM 库提供事务级接口,ports,exports,imp ports,and analysis ports。所有这些 TLM 元素都需要发送事务、接收事务以及从一个组件传输到另一个组件…

STM32物联网项目-程序框架思想

程序框架思想 一、程序框架的构想 1、STM32cubeMX生成的代码与添加的应用代码分离; 2、利用STM32cubeMX重新生成代码&#xff0c;不影响应用代码; 3、应用代码的添加&#xff0c;移除与修改&#xff0c;不影响cube生成的代码; 4、代码架构方便阅读&#xff0c;编辑&#x…

领域最全!多传感器融合方法综述!(Camera/Lidar/Radar等多源异构数据)

点击进入→自动驾驶之心技术交流群 后台回复【ECCV2022】获取ECCV2022所有自动驾驶方向论文! 自动驾驶中的多传感器融合 原文:Multi-Sensor Fusion in Automated Driving: A Survey 自动驾驶正成为影响未来行业的关键技术,传感器是自动驾驶系统中感知外部世界的关键,其协作…

Java 开发中的 Lombok 是什么?

一. 血案 今天有个学生告诉我&#xff0c;他在项目中使用Mybatis框架查询时报错&#xff0c;提示无法创建对象。但自己仔细地检查了代码都没有发现错误&#xff0c;于是他就半夜拼命地给我发消息求救。 我起床拿手机&#xff0c;还差点摔倒闪了我的老腰&#xff0c;我老婆看我…

猿创征文|工作中遇到技术盲区后的自我成长

猿创征文&#xff5c;工作中遇到技术盲区后的自我成长 1、立场 我是一名python后端开发程序员&#xff0c;在一家创业公司中兢兢业业工作快两年了&#xff0c;从软件架构、开发、测试、部署、运维一手经办&#xff0c;到开发文档、API接口、开发周期、设备交付、安装完成全程…

面向对象编程原则(03)——单一职责原则

版权声明 本文原创作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl 参考资料 《大话设计模式》 作者&#xff1a;程杰《Java设计模式》 作者&#xff1a;刘伟《图解设计模式》 作者&#xff1a;结城浩《重学Java设计模式》 作者&#xff1a;…

[论文阅读] HairGAN: Spatial-Aware Palette GAN for Hair Color Transfer

[论文地址] [代码] [ICME 22] Abstract 头发颜色转移的目的是将头发颜色从参考图像转移到原始图像&#xff0c;同时保持原始图像的头发结构。然而&#xff0c;由于复杂的头发结构以及原始图像和参考图像之间头发区域的错位&#xff0c;现有的方法不能很好地完成这一任务。为了…

CTFshow_MISC入门_图片篇(基础操作信息附加)wp

文章目录前言Tipsmisc1misc2misc3misc4misc5misc6misc7misc8misc9misc10misc11后记前言 挺长时间没有打CTF了&#xff0c;感觉技术从之前就一直没有提升多少&#xff0c;摸了段时间的渗透&护网&#xff0c;感觉CTF的基础还是比较重要&#xff0c;温故而知新&#xff0c;就…