当前位置:网站首页>二维卷积定理的验证(下,cv2.filter2D())
二维卷积定理的验证(下,cv2.filter2D())
2022-08-10 05:34:00 【天真的和感伤的想象家】
二维卷积定理的验证(下,cv2.filter2D())
前言 : 内容承接了二维卷积定理的验证(上)。主要解决该博文中最后提到的问题,也即
cv2.filter2D()
如何应用傅里叶变换来替代进行图像的卷积计算。
0. 基本问题
二维卷积定理表达式如下
f ( x , y ) ∗ g ( x , y ) = F − 1 [ F ( f ( x , y ) ) ⋅ F ( g ( x , y ) ) ] f(x,y)*g(x,y) = F^{-1}[F(f(x,y))·F(g(x,y))] f(x,y)∗g(x,y)=F−1[F(f(x,y))⋅F(g(x,y))]
如博文二维卷积定理的验证(上)中所述,在验证过程中发现,padding 的不同影响着最终结果的不同。
而等式左侧卷积操作和右侧傅里叶变换,都需要预先对图像进行 padding 操作,也即边界处理。
因此,在前述博文验证基础上,衍生出一个问题,即“是否存在着某种边界处理方式,使得卷积图像结果矩阵尺寸没有变化,且所有值都可以与傅里叶方式计算下等价。”
也即,cv2.filter2D()
是如何进行边界处理的。
1. 思路与流程
问题以及验证流程简化下,可以描述成以下:
先使用
cv2.filter2D( img, -1, kenel)
函数计算出一个结果。注意 kenel 要大于11*11,只有尺寸大时,该函数才是使用傅里叶变换来实现卷积操作。
使用
scipy.signal.convolve2d()
函数完成正常卷积操作。注意:这里涉及到了边界处理和卷积类型选择
使用
np.fft.fft2()
和np.fft.ifft2()
函数完成傅里叶变换操作。注意:这里涉及到了边界处理
最终目的是,通过调节(2)中卷积时的边界处理和类型选择,以及,(3)傅里叶变换时的边界处理,使得(2)(3)结果与(1)中结果完全一致。
这样,(1)(2)结果相同,也就验证了卷积定理;(1)(3)结果相同,可以弄清cv2.filter2D()
中傅里叶变换代替卷积过程。
2. 代码实践
按照上述思路,进行参数调试,因为比较繁琐,不呈现调试过程,只呈现最终代码。
完整代码
import cv2
import numpy as np
from scipy import signal
# ---------- 原始图像 f(x) 和 卷积核 g(x) -------------- #
img = cv2.imread("fp.jpg")[0:101,0:101]
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
kenel = np.ones((17,17))/17**2
# ---------------- cv2.filter2D() ---------------------#
# 数据类型
gray = gray.astype(np.float64)
Conv_img = cv2.filter2D(gray, -1, kenel)
np.savetxt('Conv_img64.txt', Conv_img, fmt='%0.8f')
# ------------------ signal.convolve2d() --------------#
# 边界类型选取
#img_pad = cv2.copyMakeBorder(gray, 8,8,8,8, cv2.BORDER_REFLECT)
img_pad = cv2.copyMakeBorder(gray, 8,8,8,8, cv2.BORDER_REFLECT_101)
#img_pad = cv2.copyMakeBorder(gray, 8,8,8,8, cv2.BORDER_REPLICATE)
#img_pad = cv2.copyMakeBorder(gray, 8,8,8,8, cv2.BORDER_CONSTANT, 0)
# 数据类型
img_pad = img_pad.astype(np.float64)
kenel = kenel.astype(np.float64)
Conv = signal.convolve2d(img_pad, kenel, mode='valid')
np.savetxt('Conv64.txt', Conv, fmt='%0.8f')
# ---------------- fft() & ifft() ---------------------#
# padding 边界选择
img_pad = cv2.copyMakeBorder(gray, 8,8,8,8, cv2.BORDER_REFLECT_101) #cv2.BORDER_REPLICATE
kenel_pad = cv2.copyMakeBorder(kenel, 50,50,50,50, cv2.BORDER_CONSTANT, 0)
# 数据类型
img_pad = img_pad.astype(np.float64)
kenel_pad = kenel_pad.astype(np.float64)
# F(f(x))
img_fft = np.fft.fftshift(np.fft.fft2(img_pad))
# F(g(x))
kenel_fft = np.fft.fftshift(np.fft.fft2(kenel_pad))
# ifft( F(f(x))·F(g(x)) )
FFT = np.fft.ifftshift(np.fft.ifft2(np.fft.fftshift(img_fft*kenel_fft)))
np.savetxt('FFT64.txt', np.abs(FFT)[8:-8, 8:-8], fmt='%0.8f')
细节说明
- 三种方法下,数据类型要保持一致!!!不然结果的小数点后会有些许差异。
- 傅里叶变换的结果图像尺寸会变大,需要剪切掉一部分,才能与前两者方法完全相等!!!
这两点,上述代码都有体现。
最终结果
- cv2.filter2D() 结果
- 卷积结果
- 傅里叶变换结果
3. 结论与分析
从上述结果中可以看出,三者结果是一致的,此条件下:
卷积,图片 padding 使用
cv2.BORDER_REFLECT_101
边界。使用了 ‘same’ 卷积。说明:上述代码中虽然使用了 ‘valid’。但因为预先进行了padding,所以实际上是 ’same‘ 操作。
傅里叶变换,图片 padding 使用
cv2.BORDER_REFLECT_101
边界,核 padding 使用补零操作。结果尺寸为 ( i m g _ H + k e n e l _ H − 1 ) × ( i m g _ W + k e n e l _ W − 1 ) (img\_H + kenel\_H-1)\times (img\_W + kenel\_W-1) (img_H+kenel_H−1)×(img_W+kenel_W−1) ,因此需要剪裁。
三种函数计算前,数据的精度要保持一致!!!这样最终结果才会完全相同。
边栏推荐
- LeetCode refers to the offer 21. Adjust the order of the array so that the odd numbers are in front of the even numbers (simple)
- cesium rotate image
- opencv
- WeChat applet wx.writeBLECharacteristicValue Chinese character to buffer problem
- pytorch-10.卷积神经网络
- Machine Learning - Clustering - Shopping Mall Customer Clustering
- Small program wx.request simple Promise package
- network security firewall
- 基于 .NET Core MVC 的权限管理系统
- Chain Reading|The latest and most complete digital collection sales calendar-07.29
猜你喜欢
pytorch-11.卷积神经网络(高级篇)
一个基于.Net Core跨平台小程序考试系统
Notes for RNN and Decision Tree
链表API设计
LeetCode 2011. Variable Value After Action (Simple)
The latest and most complete digital collection sales calendar-07.27
Test of the opposite sex what you look like?
堆的原理与实现以及排序
Timer (setInterval) on and off
Collection tool class
随机推荐
Common class String overview
The way for programmers to make money from a sideline business and increase their monthly income by 20K
The latest and most complete digital collection sales calendar-07.26
pytorch-11.卷积神经网络(高级篇)
pytorch-09. Multi-classification problem
分享一款恋爱星座男女配对微信小程序源码
MySQL中MyISAM为什么比InnoDB查询快
Chain Reading Good Article: Jeff Garzik Launches Web3 Production Company
LeetCode 938. Range Sum of Binary Search Trees (Simple)
PyTorch之模型定义
LeetCode 面试题17.14 最小k个数(中等)
集合 set接口
符号表
Ten years of sharpening a sword!The digital collection market software, Link Reading APP is officially open for internal testing!
Analysis of the investment value of domestic digital collections
棋类游戏-五子棋小游戏
generic notes()()()
pytorch-10.卷积神经网络(作业)
Chain Reading Recommendation: From Tiles to Generative NFTs
Notes for RNN and Decision Tree