当前位置: 首页 > news >正文

OPENCV C++(九)鼠标响应+dft+idft

鼠标响应回调函数(固定格式)

 

void on_mouse(int EVENT, int x, int y, int flags, void* userdata)
{Mat hh;hh = *(Mat*)userdata;Point p(x, y);switch (EVENT){case EVENT_LBUTTONDOWN:{points.x = x;points.y = y;mousePoints.push_back(points);circle(hh, points, 4, cvScalar(255, 255, 255), -1);imshow("mouseCallback", hh);}break;}}

 这个鼠标响应函数 就是鼠标左键按下后,会标记一个点,画一个白色点,并将这个点存储到points当中

鼠标响应函数

setMouseCallback("mouseCallback", on_mouse, &selectMat);

 mousecallback就是窗口名称,后面是图像,中间是函数名

选取多边形roi区域函数(结合鼠标响应)

int selectPolygon(cv::Mat srcMat, cv::Mat& dstMat)
{vector<vector<Point>> contours;cv::Mat selectMat;cv::Mat m = cv::Mat::zeros(srcMat.size(), CV_32F);m = 1;if (!srcMat.empty()) {srcMat.copyTo(selectMat);srcMat.copyTo(dstMat);}else {std::cout << "failed to read image!:" << std::endl;return -1;}namedWindow("mouseCallback");imshow("mouseCallback", selectMat);setMouseCallback("mouseCallback", on_mouse, &selectMat);waitKey(0);destroyAllWindows();//计算roicontours.push_back(mousePoints);if (contours[0].size() < 3) {std::cout << "failed to read image!:" << std::endl;return -1;}drawContours(m, contours, 0, Scalar(0), -1);m.copyTo(dstMat);return 0;
}

 建立一个全白色的mat,用鼠标响应选取白色点连接构成roi,然后通过drawcontous把roi在全白色mat里面画出,选中区域为黑色,没有选中区域为白色。

也可以将其改成选中的区域为白色 没有选中为黑色 只需要将

m=0;scalar(255,255,255)即可

查看一张图片的幅度频谱(输入灰度)

预处理

Mat padMat;//当图像的尺寸是2,3,5的整数倍时,离散傅里叶变换的计算速度最快。	//获得输入图像的最佳变换尺寸int m = getOptimalDFTSize(srcMat.rows);int n = getOptimalDFTSize(srcMat.cols);

 

copyMakeBorder(srcMat, padMat, 0, m - srcMat.rows, 0, n - srcMat.cols, BORDER_CONSTANT, Scalar::all(0));
//对边界进行填充,刚才得到的m,n

 //把灰度图像放在左上角,在右边和下边扩展图像,扩展部分填充为0;

//定义一个数组,存储频域转换成float类型的对象,再存储一个和它一样大小空间的对象来存储复数部分Mat planes[] = { Mat_<float>(padMat), Mat::zeros(padMat.size(), CV_32F) };
Mat complexMat;
merge(planes, 2, complexMat);
//将2个单通道的图像合成一幅多通道图像,将实部和虚部组合成一个

正片开始,进行傅里叶变换

dft(complexMat, complexMat);
//输入输出图像
split(complexMat, planes);
//求相位,保存在planes[0]
magnitude(planes[0], planes[1], planes[0]);
//0代表实部,1代表虚部 保存在0中 相位

为了显示方便,而作后续处理

Mat magMat = planes[0];
magMat += Scalar::all(1);
log(magMat, magMat);
//值都很大,取个对数显示出来

把四个角(高频)移到中间来 

//确保对称magMat = magMat(Rect(0, 0, magMat.cols & -2, magMat.rows & -2));int cx = magMat.cols / 2;int cy = magMat.rows / 2;//将图像移相/*0 | 1         3 | 2-------  ===> -------2 | 3         1 | 0*/Mat q0(magMat, Rect(0, 0, cx, cy));Mat q1(magMat, Rect(cx, 0, cx, cy));Mat q2(magMat, Rect(0, cy, cx, cy));Mat q3(magMat, Rect(cx, cy, cx, cy));Mat tmp;q0.copyTo(tmp);q3.copyTo(q0);tmp.copyTo(q3);q1.copyTo(tmp);q2.copyTo(q1);tmp.copyTo(q2);

要一个中间变量temp不然会损失图像,保证对称是怕/2除不整,//修剪频谱,如果图像的行或者列是奇数的话,那其频谱是不对称的,因此要修剪

将图像归一化到0-255 也就是0-1之间可以显示出来

normalize(magMat, magMat, 0, 1, NORM_MINMAX);magMat = magMat * 255;magMat.copyTo(dstMat);return 0;

这样就得到了频谱

求相位谱

phase(planes[0], planes[1], ph);//相位谱ph

用鼠标响应处理频谱,再ifft转换回来

前面的一样直到

mag = mag / 255;

 先倒回去

鼠标响应

cv::Mat mask;
Mat proceMag;selectPolygon(mag,mask);mag= mag.mul(mask);
proceMag = mag * 255;
imwrite("处理后频谱.jpg", proceMag);

倒过来干 ifft

//前述步骤反着来一遍,目的是为了逆变换回原图Mat q00(mag, Rect(0, 0, cx, cy));   	Mat q10(mag, Rect(cx, 0, cx, cy));  Mat q20(mag, Rect(0, cy, cx, cy));  Mat q30(mag, Rect(cx, cy, cx, cy)); //交换象限q00.copyTo(tmp);q30.copyTo(q00);tmp.copyTo(q30);q10.copyTo(tmp);q20.copyTo(q10);tmp.copyTo(q20);mag = mag * maxVal;//将归一化的矩阵还原 exp(mag, mag);//对应于前述去对数mag = mag - Scalar::all(1);//对应前述+1polarToCart(mag, ph, planes[0], planes[1]);//由幅度谱mag和相位谱ph恢复实部planes[0]和虚部planes[1]merge(planes, 2, complexImg);//将实部虚部合并

正片开始 idtf

Mat ifft(Size(src.cols, src.rows), CV_8UC1);//傅里叶逆变换idft(complexImg, ifft, DFT_REAL_OUTPUT);normalize(ifft, ifft, 0, 1, CV_MINMAX);Rect rect(0, 0, src.cols, src.rows);dst = ifft(rect);dst = dst * 255;cv::Mat dspMat;dst.convertTo(dspMat, CV_8UC1);imshow("dst", dspMat);imshow("src", src);waitKey(0);return 0;

注意这里有个转换 idft类型要转换成8UC1才能展示

这里有个疑问 mag不×255才能显示出图像 ×了反而显示出全白 

但是imwirte出的图像又是正常的 为什么?

相关文章:

OPENCV C++(九)鼠标响应+dft+idft

鼠标响应回调函数&#xff08;固定格式&#xff09; void on_mouse(int EVENT, int x, int y, int flags, void* userdata) {Mat hh;hh *(Mat*)userdata;Point p(x, y);switch (EVENT){case EVENT_LBUTTONDOWN:{points.x x;points.y y;mousePoints.push_back(points);circle…...

python编程求出介于这两个数 之间的所有质数并打印输出。显示格式为“*数是质数

这里写自定义目录标题 练习 &#xff1a;提示用户输入两个正整数&#xff0c;编程求出介于这两个数之间的所有质数并打印输出。显示格式为“*数是质数。”代码打印效果 练习 &#xff1a;提示用户输入两个正整数&#xff0c;编程求出介于这两个数之间的所有质数并打印输出。显示…...

基于Selenium模块实现无界面模式 执行JS脚本

此篇文章主要介绍如何使用 Selenium 模块实现 无界面模式 & 执行JS脚本(把滚动条拉到底部)&#xff0c;并以具体的示例进行展示。 1、Selenium 设置无界面模式 创建浏览器对象之前&#xff0c;创建 options 功能对象 &#xff1a;options webdriver.ChromeOptions() 添加…...

【LangChain学习】基于PDF文档构建问答知识库(二)创建项目

这里我们使用到 fastapi 作为项目的web框架&#xff0c;它是一个快速&#xff08;高性能&#xff09;的 web 框架&#xff0c;上手简单。 一.创建 FastAPI 项目 我们在IDE中&#xff0c;左侧选择 FastAPI &#xff0c;右侧选择创建一个新的虚拟环境。 创建成功&#xff0c;会有…...

【Kubernetes】Kubernetes之kubectl详解

kubectl 一、陈述式资源管理1. 陈述式资源管理方法2. 基本信息查看3. 项目周期管理3.1 创建 kubectl create 命令3.2 发布 kubectl expose命令3.3 更新 kubectl set3.4 回滚 kubectl rollout3.5 删除 kubectl delete 4. kubectl 的发布策略4.1 蓝绿发布4.2 红黑发布4.3 灰度发布…...

【torch.nn.PixelShuffle】和 【torch.nn.UnpixelShuffle】

文章目录 torch.nn.PixelShuffle直观解释官方文档 torch.nn.PixelUnshuffle直观解释官方文档 torch.nn.PixelShuffle 直观解释 PixelShuffle是一种上采样方法&#xff0c;它将形状为 ( ∗ , C r 2 , H , W ) (∗, C\times r^2, H, W) (∗,Cr2,H,W)的张量重新排列转换为形状为…...

Rocky9 KVM网桥的配置

KVM的默认网络模式为NAT,借助宿主机模式上网,现在我们来改成桥接模式,这样外界就可以直接和宿主机里的虚拟机通讯了。 Bridge方式即虚拟网桥的网络连接方式,是客户机和子网里面的机器能够互相通信。可以使虚拟机成为网络中具有独立IP的主机。 桥接网络(也叫物理设备共享…...

爬虫013_函数的定义_调用_参数_返回值_局部变量_全局变量---python工作笔记032

然后再来看函数,可以避免重复代码 可以看到定义函数以及调用函数...

将.doc文档的默认打开方式从WPS修改为word office打开方式的具体方法(以win 10 操作系统为例)

将.doc文档的默认打开方式从WPS修改为word office打开方式的具体方法&#xff08;以win 10 操作系统为例&#xff09; 随着近几年WPS软件的不断完善和丰富&#xff0c;在某些方面取得了具有特色的优势。在平时编辑.doc文档时候也常常用到wps软件&#xff0c;不过WPS文献也存在…...

如何搭建个人的GPT网页服务

写在前面 在创建个人的 GPT网页之前&#xff0c;我登录了 Git 并尝试了一些开源项目&#xff0c;但是没有找到满足我个性化需求的设计。虽然许多收费的 GPT网页提供了一些免费额度&#xff0c;足够我使用&#xff0c;但是公司的安全策略会屏蔽这些网页。因此&#xff0c;我决定…...

[QCM6125][Android13] 默认关闭SELinux权限

文章目录 开发平台基本信息问题描述解决方法 开发平台基本信息 芯片: QCM6125 版本: Android 13 kernel: msm-4.14 问题描述 正常智能硬件设备源码开发&#xff0c;到手的第一件事就是默认关闭SELinux权限&#xff0c;这样能够更加方便于调试功能。 解决方法 --- a/QSSI.1…...

【jvm】jvm发展历程

目录 一、Sun Classic VM二、Exact VM三、HotSpot VM四、JRockit五、J9六、KVM、CDC、CLDC七、Azul VM八、Liquid VM九、Apache Harmony十、Microsoft JVM十一、Taobao JVM十二、Dalvik VM 一、Sun Classic VM 1.1996年java1.0版本&#xff0c;sun公司发布了sun classic vm虚拟…...

Dubbo3.0 Demo

将SpringBoot工程集成Dubbo 1.创建父工程 2.创建子工程consumer&#xff0c;provider 3.初始化工程 4.引入依赖 在provider和consumer中引入dubbo依赖 <dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo-spring-boot-starter</a…...

源码分析——ConcurrentHashMap源码+底层数据结构分析

文章目录 1. ConcurrentHashMap 1.71. 存储结构2. 初始化3. put4. 扩容 rehash5. get 2. ConcurrentHashMap 1.81. 存储结构2. 初始化 initTable3. put4. get 3. 总结 1. ConcurrentHashMap 1.7 1. 存储结构 Java 7 中 ConcurrentHashMap 的存储结构如上图&#xff0c;Concurr…...

R语言中的函数25:paste,paste0

文章目录 介绍paste0()实例 paste()实例 介绍 paste0()和paste()函数都可以实现对字符串的连接&#xff0c;paste0是paste的简化版。 paste0() paste (..., sep " ", collapse NULL, recycle0 FALSE)… one or more R objects, to be converted to character …...

(八)穿越多媒体奇境:探索Streamlit的图像、音频与视频魔法

文章目录 1 前言2 st.image&#xff1a;嵌入图像内容2.1 图像展示与描述2.2 调整图像尺寸2.3 使用本地文件或URL 3 st.audio&#xff1a;嵌入音频内容3.1 播放音频文件3.2 生成音频数据播放 4 st.video&#xff1a;嵌入视频内容4.1 播放视频文件4.2 嵌入在线视频 5 结语&#x…...

CAD练习——绘制房子平面图

首先还是需要设置图层、标注、文字等 XL&#xff1a;构造线 用构造线勾勒大致的轮廓&#xff1a; 使用多线命令&#xff1a;ML 绘制墙壁 可以看到有很多交叉点的位置 用多线编辑工具将交叉点处理 有一部分处理不了的&#xff0c;先讲多线分解&#xff0c;然后用修剪打理&…...

spring 面试题

一、Spring面试题 专题部分 1.1、什么是spring? Spring是一个轻量级Java开发框架&#xff0c;最早有Rod Johnson创建&#xff0c;目的是为了解决企业级应用开发的业务逻辑层和其他各层的耦合问题。它是一个分层的JavaSE/JavaEE full-stack&#xff08;一站式&#xff09;轻量…...

Springboot项目集成Durid数据源和P6Spy以及dbType not support问题

项目开发阶段&#xff0c;mybatis的SQL打印有占位符&#xff0c;调试起来还是有点麻烦&#xff0c;随想整合P6Spy打印可以直接执行的SQL&#xff0c;方便调试&#xff0c;用的Durid连接池。 Springboot项目集成Durid <dependency><groupId>com.alibaba</group…...

安卓如何卸载应用

卸载系统应用 首先需要打开手机的开发者选项&#xff0c;启动usb调试。 第二步需要在电脑上安装adb命令&#xff0c;喜欢的话还可以将它加入系统path。如果不知道怎么安装&#xff0c;可以从这里下载免安装版本。 第三步将手机与电脑用数据线连接&#xff0c;注意是数据线&a…...

挑战杯推荐项目

“人工智能”创意赛 - 智能艺术创作助手&#xff1a;借助大模型技术&#xff0c;开发能根据用户输入的主题、风格等要求&#xff0c;生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用&#xff0c;帮助艺术家和创意爱好者激发创意、提高创作效率。 ​ - 个性化梦境…...

【JavaEE】-- HTTP

1. HTTP是什么&#xff1f; HTTP&#xff08;全称为"超文本传输协议"&#xff09;是一种应用非常广泛的应用层协议&#xff0c;HTTP是基于TCP协议的一种应用层协议。 应用层协议&#xff1a;是计算机网络协议栈中最高层的协议&#xff0c;它定义了运行在不同主机上…...

大型活动交通拥堵治理的视觉算法应用

大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动&#xff08;如演唱会、马拉松赛事、高考中考等&#xff09;期间&#xff0c;城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例&#xff0c;暖城商圈曾因观众集中离场导致周边…...

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)

0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述&#xff0c;后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作&#xff0c;其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...

【网络安全产品大调研系列】2. 体验漏洞扫描

前言 2023 年漏洞扫描服务市场规模预计为 3.06&#xff08;十亿美元&#xff09;。漏洞扫描服务市场行业预计将从 2024 年的 3.48&#xff08;十亿美元&#xff09;增长到 2032 年的 9.54&#xff08;十亿美元&#xff09;。预测期内漏洞扫描服务市场 CAGR&#xff08;增长率&…...

Java - Mysql数据类型对应

Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 在 GPU 上对图像执行 均值漂移滤波&#xff08;Mean Shift Filtering&#xff09;&#xff0c;用于图像分割或平滑处理。 该函数将输入图像中的…...

JS设计模式(4):观察者模式

JS设计模式(4):观察者模式 一、引入 在开发中&#xff0c;我们经常会遇到这样的场景&#xff1a;一个对象的状态变化需要自动通知其他对象&#xff0c;比如&#xff1a; 电商平台中&#xff0c;商品库存变化时需要通知所有订阅该商品的用户&#xff1b;新闻网站中&#xff0…...

基于 TAPD 进行项目管理

起因 自己写了个小工具&#xff0c;仓库用的Github。之前在用markdown进行需求管理&#xff0c;现在随着功能的增加&#xff0c;感觉有点难以管理了&#xff0c;所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD&#xff0c;需要提供一个企业名新建一个项目&#…...

uniapp手机号一键登录保姆级教程(包含前端和后端)

目录 前置条件创建uniapp项目并关联uniClound云空间开启一键登录模块并开通一键登录服务编写云函数并上传部署获取手机号流程(第一种) 前端直接调用云函数获取手机号&#xff08;第三种&#xff09;后台调用云函数获取手机号 错误码常见问题 前置条件 手机安装有sim卡手机开启…...