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

这篇具有很好参考价值的文章主要介绍了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();
	//计算roi
	contours.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);//对应前述+1
	polarToCart(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出的图像又是正常的 为什么?文章来源地址https://www.toymoban.com/news/detail-637896.html

到了这里,关于OPENCV C++(九)鼠标响应+dft+idft的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • OpenCV-Python学习(15)—— OpenCV 鼠标操作和响应(cv.setMouseCallback)

    1. 学习目标 学习如何在OpenCV中处理鼠标事件; 学习鼠标事件与回调; 学习鼠标事件回调函数的基本流程。 2. Callback 基本流程 3. 鼠标事件 cv.setMouseCallback 函数说明 3.1 cv.setMouseCallback() 函数使用 3.2 参数说明 参数 说明 winname 表示监听鼠标事件的窗口。 onMouse 表示响应函数,即

    2024年02月10日
    浏览(50)
  • OpenCV学习(三)——响应鼠标事件(获取点击点坐标和颜色,利用鼠标进行绘图)

    使用OpenCV读取图像,可以在读取图像的窗口通过鼠标点击可以实现:获取鼠标点击像素点的坐标、获取鼠标点击像素点的颜色和在鼠标点击的像素点生成圆等等。 winname:窗口的名字 callback:回调函数 userdata:给回调函数的参数 enent:鼠标事件 x:横坐标 y:纵坐标 flags:事件

    2024年02月08日
    浏览(92)
  • 计算机视觉OpenCv学习系列:第四部分、键盘+鼠标响应操作

    键盘响应中有一个函数叫做 waitKey ,所有的获取键盘键值都是通过waitKey函数实现的。 1.键盘响应事件 cv.waitKey( [, delay] ) -- retval delay如果没有声明或者delay=0,表示一直阻塞 delay大于0,表示阻塞指定毫秒数 retval返回的对应键盘键值,注意:在不同的操作系统中可能会有差异! 典

    2024年02月09日
    浏览(49)
  • 002 OpenCV dft 傅里叶变换

    目录 一、傅里叶变换 1.1 傅里叶变换概念 1.2 opencv中傅里叶变换 二、实验代码 本文使用环境为: Windows10 Python 3.9.17 opencv-python 4.8.0.74 傅里叶变换(Fourier Transform)是一种在数学、物理和工程领域广泛应用的算法,用于分析信号或数据的频率成分。它是由法国数学家约瑟夫·傅

    2024年02月05日
    浏览(44)
  • Opencv4基于C++基础入门笔记:图像 颜色 事件响应 图形 视频 直方图 Opencv4基于C++的 实时人脸监测

      效果图 ◕‿◕:opencv人脸识别效果图(请叫我真爱粉)✌✌✌先看一下效果图勾起你的兴趣!  文章目录: 一:环境配置搭建 二:图像 1.图像读取与显示 main.cpp  运行结果 2.图像色彩空间转换 2.1 换色彩  test.h  test.cpp main.cpp    运行结果 2.2 照片换背景 test.h        test.

    2024年02月10日
    浏览(57)
  • Opencv4基于C++基础入门笔记:图像 颜色 事件响应 图形 视频 直方图 Opencv4基于C++的 实时人脸检测

      效果图 ◕‿◕:opencv人脸识别效果图(请叫我真爱粉)✌✌✌先看一下效果图勾起你的兴趣!  文章目录: 一:环境配置搭建 二:图像 1.图像读取与显示 main.cpp  运行结果 2.图像色彩空间转换 2.1 换色彩  test.h  test.cpp main.cpp    运行结果 2.2 照片换背景 test.h        test.

    2024年02月13日
    浏览(54)
  • C++ opencv鼠标事件,在图像上画矩形

    opencv中常用的除了TrackBar滑动条事件,还有丰富的鼠标事件,与TrackBar类似,鼠标事件也是使用回调函数判断动作的发生,并执行相关的操作。整个行为与QT的信号与槽类似。 在图像中画出矩形,需要使用setMouseCallback()和MouseCallback()函数。 本文使用的头文件及命名空间: 设

    2024年02月11日
    浏览(35)
  • C++中键盘响应结合OpenCV库进行图像灰度图、HSV图转换和亮度调整

    QuickDemo.cpp quick_opencv.h main.cpp 按键esc退出程序。 注意必须点击原图上再输入1或2或3才有响应。

    2024年02月20日
    浏览(66)
  • Opencv C++图像处理:矩阵Mat + 随机数RNG + 计算耗时 + 鼠标事件

    数据类型 字节数 取值范围 bool型(布尔型) 1 [0 or 1] BOOL型(int型) 4 [TRUE or FALSE] sbyte型(有符号8位整数) 1 [128 ~ 127] bytet型(无符号8位整数) 8U 2 [0 ~ 255] short型(有符号16位整数) 16S 2 [-32,768 ~ 32,767] ushort型(无符号16位整数) 16U 2 [0 ~ 65,535] int型(有符号32位整数) 32S 4 [

    2024年02月03日
    浏览(56)
  • 【opencv3】鼠标框选矩形并显示当前像素点坐标和矩形中心点坐标C++

    (1)用鼠标在图中框选矩形目标,然后保存框选的图片; (2)鼠标拖动过程中要求显示框的线条以及鼠标当前像素点信息(坐标和RGB值); (3)拖动完成后单独显示框取的图像,拖动完成后cout输出框中心像素点坐标。 鼠标事件: 鼠标左键按下时(event == CV_EVENT_LBUTTONUP),标

    2024年02月09日
    浏览(50)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包