OpenCV学习笔记-傅里叶变换
一、傅里叶变换
空间域
一般情况下,空间域的图像是f(x, y) = 灰度级(0-255),形象一点就是一个二维矩阵,每一个坐标对应一个颜色值。
频率域
二、Numpy中的傅里叶变换
#快速傅里叶变换算法得到频率分布 f = np.fft.fft2(img) #默认结果中心点位置在左上角,转移到中间 fshift = np.fft.fftshift(f) #fshift是复数,求绝对值结果才是振幅 magnitude_spectrum = np.log(np.abs(fshift))plt.subplot(121),plt.imshow(img, cmap='gray') plt.title('Input Image'),plt.xticks([]),plt.yticks([]) plt.subplot(122),plt.imshow(magnitude_spectrum, cmap='gray') plt.title('Magnitude Spectrum'),plt.xticks([]),plt.yticks([]) plt.show()
ϕ = a t a n ( 实部虚部 ),numpy包自带一个angle函数可以直接根据复数的实部和虚部求出角度(默认出来的角度是弧度。)像上述的程序中的f和fshift都是复数,就可以直接用angle直接求解相位,我们和振幅图对比一下:
f = np.fft.fft2(img) fshift = np.fft.fftshift(f) #取绝对值:将复数变成实数 #取对数的目的为了将数据变化到0-255 s1 = np.log(np.abs(fshift))#求相位 s1_angle = np.angle(fshift)plt.subplot(221),plt.imshow(img, cmap='gray'),plt.title('original') plt.subplot(222),plt.imshow(s1, 'gray'),plt.title('center') plt.subplot(223),plt.imshow(s1_angle, 'gray'),plt.title('angel') #逆变换 f1shift = np.fft.ifftshift(fshift) img_back = np.fft.ifft2(f1shift) #出来的复数,无法显示,转成实数 img_back = np.abs(img_back) plt.subplot(224),plt.imshow(img_back, 'gray'),plt.title('img back') plt.show()
a t a n ( 实部虚部 ),现在假设我们只用一幅图像的振幅或者相位来将频域内图像恢复到时域会怎么样?
f = np.fft.fft2(img) fshift = np.fft.fftshift(f) # 取绝对值: 将复数变成实数 # 取对数是为了将数据变换到0-255 s1 = np.log(np.abs(fshift)) plt.subplot(221),plt.imshow(img, 'gray'),plt.title('original') plt.xticks([]), plt.yticks([]) #------------------------------------- #逆变换 -- 取绝对值就是振幅 f1shift = np.fft.ifftshift(np.abs(fshift)) img_back = np.fft.ifft2(f1shift)img_back = np.abs(img_back) plt.subplot(222),plt.imshow(img_back, 'gray'),plt.title('only Amplitude') plt.xticks([]),plt.yticks([]) #------------------------------------ #逆变换 -- 取相位 f2shift = np.fft.ifftshift(np.angle(fshift)) img_back = np.fft.ifft2(f2shift) #结果是复数,无法显示 img_back = np.abs(img_back) plt.subplot(223), plt.imshow(img_back, 'gray'), plt.title('only phase') plt.xticks([]), plt.yticks([]) #------------------------------------ #逆变换--将两者结合看看 s1 = np.abs(fshift) # 取振幅 s1_angle = np.angle(fshift) # 取相位 s1_real = s1*np.cos(s1_angle) # 取实部 s1_imag = s1*np.sin(s1_angle) # 去虚部 s2 = np.zeros(img.shape, dtype=complex) s2.real = np.array(s1_real) # 重新赋值给s2 s2.imag = np.array(s1_imag)#对新的进行逆变换 f3shift = np.fft.ifftshift(s2) img_back = np.fft.ifft2(f3shift)img_back = np.abs(img_back) plt.subplot(224), plt.imshow(img_back, 'gray'), plt.title('another way') plt.xticks([]), plt.yticks([]) plt.show()
img_1 = cv.imread('img/WindowsLogo.jpg', 0) img_2 = cv.imread('img/LinuxLogo.jpg', 0) plt.subplot(221), plt.imshow(img_1, 'gray'), plt.title('original_1') plt.xticks([]), plt.yticks([]) plt.subplot(222), plt.imshow(img_2, 'gray'), plt.title('original_2') plt.xticks([]), plt.yticks([]) #---------------------------- f1 = np.fft.fft2(img_1) f1shift = np.fft.fftshift(f1) f1_A = np.abs(f1shift) # 取振幅 f1_P = np.angle(f1shift) # 取相位 #----------------------------- f2 = np.fft.fft2(img_2) f2shift = np.fft.fftshift(f2) f2_A = np.abs(f2shift) # 取振幅 f2_P = np.angle(f2shift) # 取相位 #--------图1的振幅--图2的相位----- img_new_1 = np.zeros(img_1.shape, dtype=complex) img_new_1_real = f1_A * np.cos(f2_P) # 取实部 img_new_1_imag = f1_A * np.sin(f2_P) # 取虚部 img_new_1.real = img_new_1_real img_new_1.imag = img_new_1_imag # 对新图像赋值 f3shift = np.fft.ifftshift(img_new_1) # 对新的图像进行逆变换 img_new_1_back = np.fft.ifft2(f3shift) #结果是复数,无法显示 img_new_1_back = np.abs(img_new_1_back)plt.subplot(223), plt.imshow(img_new_1_back, 'gray'), plt.title('img1_A img2_P') plt.xticks([]), plt.yticks([]) #-------图1的相位--图2的振幅--------- img_new_2 = np.zeros(img_2.shape, dtype=complex) img_new_2_real = f2_A * np.cos(f1_P) # 取实部 img_new_2_imag = f2_A * np.sin(f1_P) # 取虚部 img_new_2.real = img_new_2_real img_new_2.imag = img_new_2_imag #对新图像赋值 f4shift = np.fft.ifftshift(img_new_2) # 对新的图像进行逆变换 img_new_2_back = np.fft.ifft2(f4shift) #结果是复数,无法显示 img_new_2_back = np.abs(img_new_2_back)plt.subplot(224), plt.imshow(img_new_2_back, 'gray'), plt.title('img1_P img2_A') plt.xticks([]), plt.yticks([]) plt.show()
rows, cols = img.shape #宽高的1/2 取中心坐标 crow, ccol = int(rows / 2), int(cols / 2) #60 * 60 的矩形窗口,去除低频分量 fshift[crow-30:crow+30,ccol-30:ccol+30] = 0 #进行逆平移操作,直流分量又回到左上角 f_shift = np.fft.ifftshift(fshift) #进行FFT逆变换 img_back = np.fft.ifft2(f_shift) #取绝对值 img_back = np.abs(img_back)plt.subplot(131),plt.imshow(img, cmap='gray') plt.title('Input Image'),plt.xticks([]),plt.yticks([]) plt.subplot(132), plt.imshow(img_back, cmap='gray') plt.title('Image after HPF'), plt.xticks([]), plt.yticks([]) plt.subplot(133), plt.imshow(img_back) plt.title('Result in JET'), plt.xticks([]), plt.yticks([]) plt.show()
plt.subplot(131), plt.imshow(img, 'gray'), plt.title('original') plt.xticks([]), plt.yticks([])rows, cols = img.shape crow, ccol = int(rows/2), int(cols/2) # -------高通滤波--------- mask = np.ones(img.shape, np.uint8) mask[crow - 30:crow + 30, ccol - 30:ccol + 30] = 0 f1 = np.fft.fft2(img) f1shift = np.fft.fftshift(f1) f1shift = f1shift * mask f2shift = np.fft.ifftshift(f1shift) # 对新得到图像进行逆变换 img_new = np.fft.ifft2(f2shift)img_new = np.abs(img_new)plt.subplot(132), plt.imshow(img_new, 'gray'), plt.title('Highpass') plt.xticks([]), plt.yticks([])# --------低通滤波--------- mask2 = np.zeros(img.shape, np.uint8) mask2[crow - 30:crow + 30, ccol - 30:ccol + 30] = 1 f1 = np.fft.fft2(img) f1shift = np.fft.fftshift(f1) f1shift = f1shift * mask2 f2shift = np.fft.ifftshift(f1shift) # 对新得到图像进行逆变换 img_new = np.fft.ifft2(f2shift)img_new = np.abs(img_new)plt.subplot(133), plt.imshow(img_new, 'gray'), plt.title('Lowpass') plt.xticks([]), plt.yticks([]) plt.show()
plt.subplot(121), plt.imshow(img, 'gray'), plt.title('original') plt.xticks([]), plt.yticks([]) #----------------------------- rows, cols = img.shape crow, ccol = int(rows/2), int(cols/2) #高通滤波器 mask1 = np.ones(img.shape, np.uint8) mask1[crow-8:crow+8, ccol-8:ccol+8] = 0 #低通滤波器 mask2 = np.zeros(img.shape, np.uint8) mask2[crow-80:crow+80, ccol-80:ccol+80] = 1 #带通滤波器 mask = mask1 * mask2 #---------------------------------- f1 = np.fft.fft2(img) f1shift = np.fft.fftshift(f1) f1shift = f1shift * mask #对新得到的图像进行逆变换 f2shift = np.fft.ifftshift(f1shift) img_new = np.fft.ifft2(f2shift)img_new = np.abs(img_new) plt.subplot(122), plt.imshow(img_new, 'gray'), plt.title('new image') plt.xticks([]), plt.yticks([]) plt.show()
#对一些算子进行比较 def demo5():mean_filter = np.ones((3, 3))x = cv.getGaussianKernel(5, 10)guassian = x * x.Tscharr = np.array([[-3, 0, -3],[-10, 0, -10],[-3, 0, 3]])sobel_x = np.array([[-1, 0, 1],[-2, 0, -2],[-1, 0, 1]])sobel_y = np.array([[-1, -2, -1],[0, 0, 0],[1, 2, 1]])laplacian = np.array([[0, 1, 0],[1, -4, 1],[0, 1, 0]])#我看有两个版本的laplacian算子,这个博客给了解释https://www.cnblogs.com/german-iris/p/4840647.html filters = [mean_filter, guassian, laplacian, sobel_x, sobel_y, scharr]filter_name = ['mean_filter', 'guassian', 'laplacian', 'sobel_x', 'sobel_y', 'scharr']fft_filters = [np.fft.fft2(x) for x in filters]fft_shift = [np.fft.fftshift(x) for x in fft_filters]mag_spectrum = [np.log(np.abs(x)+1) for z in fft_shift]for i in range(6):plt.subplot(2, 3, i+1),plt.imshow(mag_spectrum[i], 'gray')plt.title(filter_name[i]),plt.xticks([]),plt.yticks([])plt.show()
从结果我们可以看出:mean_filter、guassian算子是LPH,laplacian、sobel、scharr算子是HPF
OpenCV学习笔记-傅里叶变换相关推荐
- opencv学习笔记22:傅里叶变换,高通滤波,低通滤波
傅里叶变换原理 任何连续的周期信号,都可以由一组适当的正弦曲线组合而成. 下列左上图由其他三图构成. 左图经过傅里叶变换,由时域图转换到频域图.相互可逆 相位:不是同时开始的一组余弦函数,在叠加时要体 ...
- 36篇博文带你学完opencv :python3+opencv学习笔记汇总目录(基础版)
经过几天的学习,opencv基础部分学习完啦.整理出来. OpenCV opencv学习笔记1:图片读入,显示与保存(有代码) opencv学习笔记2:图像处理基础 opencv学习笔记3:像素处理 ...
- OpenCV学习笔记5
OpenCV学习笔记5 图像变换 傅里叶变换 这里可以先学习一下卷积分,了解清除卷积的过程和实际意义,在看这一章节的内容. 原理: 傅里叶变换经常被用来分析不同滤波器的频率特性.我们可以使用 2D 离 ...
- OpenCV 学习笔记03 boundingRect、minAreaRect、minEnclosingCircle、boxPoints、int0、circle、rectangle函数的用法...
函数中的代码是部分代码,详细代码在最后 1 cv2.boundingRect 作用:矩形边框(boundingRect),用于计算图像一系列点的外部矩形边界. cv2.boundingRect(arr ...
- opencv学习笔记(二):基于肤色的人手检测
opencv学习笔记(二):基于肤色的人手检测 原文:http://blog.csdn.net/wzmsltw/article/details/50849810 先写了人手的检测程序,下一步基于检测程 ...
- python做直方图-python OpenCV学习笔记实现二维直方图
本文介绍了python OpenCV学习笔记实现二维直方图,分享给大家,具体如下: 官方文档 – https://docs.opencv.org/3.4.0/dd/d0d/tutorial_py_2d ...
- OpenCV学习笔记大集锦
转载自: OpenCV学习笔记大集锦 – 视觉机器人 http://www.cvrobot.net/collect-opencv-resource-learn-study-note-chinese/ ...
- OpenCV学习笔记(五十六)——InputArray和OutputArray的那些事core OpenCV学习笔记(五十七)——在同一窗口显示多幅图片 OpenCV学习笔记(五十八)——读《Mast
OpenCV学习笔记(五十六)--InputArray和OutputArray的那些事core 看过OpenCV源代码的朋友,肯定都知道很多函数的接口都是InputArray或者OutputArray ...
- OpenCV学习笔记(五十一)——imge stitching图像拼接stitching OpenCV学习笔记(五十二)——号外:OpenCV 2.4.1 又出来了。。。。。 OpenCV学习笔记(五
OpenCV学习笔记(五十一)--imge stitching图像拼接stitching stitching是OpenCV2.4.0一个新模块,功能是实现图像拼接,所有的相关函数都被封装在Stitch ...
最新文章
- 查看Windows系统里的进程已运行的时间
- Sharepoint学习笔记—ECMAScript对象模型系列-- 7、获取和修改List的Lookup字段
- css列表格式属性,css list-style-type属性笔记
- pwm 正弦波_CC6420单相正弦波直流无刷马达驱动应用指南
- 大数据组件的各种协议与作用(持续更新中)
- 扑克牌图片一张一张_培养孩子的数学力,不妨试试这五个扑克牌游戏
- 四种依恋类型_“我值得被爱吗?”| 如何在亲密关系中培养安全型依恋
- 认识队列技术中的硬件队列和软件队列及如何改变硬件队列长度
- 【VMware vSAN 6.6】5.4.vSAN 配置提示:vSAN硬件服务器解决方案
- 基于SSM的NBA篮球球队运营系统
- 使用VMWARE安装Mac OSX 雪豹操作系统并配置iphone开发环境
- 云原生小课堂 | Envoy请求流程源码解析(一):流量劫持
- Unity中下载图片、音频和视频
- django基础入门之搭建博客系统
- 查看linux服务器存储空间状况
- 数字通信学习笔记——基带信号解调
- html页面打包为小程序
- 5个网站让你成为主宰网络世界的神秘黑客
- 线下空间体验如何承载商业策略——从宜家的冰淇淋说起
- 将json对象转换为数组,获取json对象的属性值