之前对于RF信号下采样这个问题特别的懵,上采样我是知道的,其中一种方法就是对于矩阵插值,使得它具有更多的信息。

但是下采样,我查了很多资料,在知网上看到一篇论文(好像不是计算机领域的),他对于矩阵下采样就是删除特定的列和行,比如是8 * 8的矩阵,那就删除2 4 6 8列和行,得到一个含1 3 5 7列和行的4 * 4大小的矩阵。

上周开了组会,刚好听一个很厉害的师兄在查新汇报中说到了RF信号下采样的问题,我就去请教了师兄,啊,其实,很简单呐,就是卷积,比如卷积核大小是3 * 3,那就可以让一个5 * 5大小的矩阵变为3 * 3大小的。

嗯……所以,我对卷积这方面还不是很熟悉,我要去详细的学习一下卷积的相关内容~~~

一、卷积是什么呢?

卷积(又名褶积)和反卷积(又名反褶积)是一种积分变换的数学方法。

卷积是分析数学中一种重要的运算。
简单定义:设: f(x),g(x)是R1上的两个可积函数,作积分:

可以证明,关于几乎所有的实数 x,上述积分是存在的。这样,随着 x 的不同取值,这个积分就定义了一个新函数,称为函数与的卷积,记为:

容易验证,并且仍为可积函数。这就是说,把卷积代替乘法,L1(R1)空间是一个代数,甚至是巴拿赫代数。

由卷积得到的函数一般要比和都光滑。特别当为具有紧致集的光滑函数,为局部可积时,它们的卷积也是光滑函数。利用这一性质,对于任意的可积函数,都可以简单地构造出一列逼近于的光滑函数列,这种方法称为函数的光滑化或正则化

卷积是两个变量在某范围内相乘后求和的结果。如果卷积的变量是序列和,则卷积的结果:

其中星号*表示卷积。当时序时,序列是的时序 i 取反的结果;时序取反使得以纵轴为中心翻转180度,所以这种相乘后求和的计算法称为卷积和,简称卷积。另外,是使位移的量,不同的对应不同的卷积结果。

如果卷积的变量是函数和,则卷积的计算变为:

其中p是积分变量,积分也是求和,t是使函数h(-p)位移的量,星号*表示卷积。

好了,以上是百度百科的内容。也算是对于卷积有了一个初步的理解了~~

二、如何卷积

然后,我们就要看看,要怎么卷积

对卷积这个名词的理解:所谓两个函数的卷积,本质上就是先将一个函数翻转,然后进行滑动叠加

在连续情况下,叠加指的是对两个函数的乘积求积分,在离散情况下就是加权求和,为简单起见就统一称为叠加。整体看来是这么个过程:

翻转——>滑动——>叠加——>滑动——>叠加——>滑动——>叠加…多次滑动得到的一系列叠加值,构成了卷积函数

卷积的“”,指的的函数的翻转,从 g(t) 变成 g(-t) 的这个过程;卷积的“”,指的是积分/加权求和

三、理解图像中的矩阵

图像可以表示为矩阵的形式

对图像的处理函数(如平滑,或者边缘提取),也可以用一个 g 矩阵来表示,如:

注意,我们在处理平面空间的问题,已经是二维函数了,相当于:


那么函数 f 和 g 的在(u,v)处的卷积 [公式] 该如何计算呢?
按卷积的定义,二维离散形式的卷积公式应该是:

从卷积定义来看,应该是在 x 和 y 两个方向去累加(对应上面离散公式中的 i 和 j 两个下标),而且是无界的,从负无穷到正无穷。可是,真实世界都是有界的。例如,上面列举的图像处理函数 g 实际上是个3 * 3的矩阵,意味着,在除了原点附近以外,其它所有点的取值都为0。考虑到这个因素,上面的公式其实退化了,它只把坐标(u,v)附近的点选择出来做计算了。所以,真正的计算如下所示:

​​首先我们在原始图像矩阵中取出(u,v)处的矩阵:

然后将图像处理矩阵翻转(这个翻转有点意思,可以有几种不同的理解,其效果是等效的:(1)先沿x轴翻转,再沿y轴翻转;(2)先沿x轴翻转,再沿y轴翻转;),如下:
原始矩阵:

翻转后的矩阵:

计算卷积时,就可以用 f 和 g’ 的内积:



以上公式有一个特点,做乘法的两个对应变量a,b的下标之和都是(u,v),其目的是对这种加权求和进行一种约束。

以上计算的是**(u,v)处的卷积**,沿x轴或者y轴滑动,就可以求出图像中各个位置的卷积,其输出结果是处理以后的图像(即经过平滑、边缘提取等各种处理的图像)。

如下图像处理矩阵将使得图像变得更为平滑,显得更模糊,因为它联合周边像素进行了平均处理:

而如下图像处理矩阵将使得像素值变化明显的地方更为明显,强化边缘,而变化平缓的地方没有影响,达到提取边缘的目的:

四、卷积核大小、个数,卷积层数如何确定?

在达到相同感受野的情况下,卷积核越小,所需要的参数和计算量越小。具体来说。卷积核大小必须大于1才有提升感受野的作用,1排除了。而大小为偶数的卷积核即使对称地加padding也不能保证输入feature map尺寸和输出feature map尺寸不变(画个图算一下就可以发现),2排除了。所以一般都用3作为卷积核大小

每一层卷积有多少channel数,以及一共有多少层卷积,这些暂时没有理论支撑,一般都是靠感觉去设置几组候选值,然后通过实验挑选出其中的最佳值。这也是现在深度卷积神经网络虽然效果拔群,但是一直为人诟病的原因之一。

五、对RF信号进行下采样

图像下采样原理:
对于一幅图像 I 尺寸为M * N,对其进行 s 倍下采样,即得到(M/s) * (N/s)尺寸的得分辨率图像,当然 s 应该是 M 和 N 的公约数才行,如果考虑的是矩阵形式的图像,就是把原始图像s * s窗口内的图像变成一个像素,这个像素点的值就是窗口内所有像素的均值:

那么如果图像按列向量化,变成了1*(MN)的向量之后,这个下采样过程也应当有一个对应的矩阵,这个矩阵的大小为(MN/s^2)*(MN)。

那么对RF信号进行下采样就等于对矩阵下采样,比如我的RF信号矩阵是处理为了 200 * 200 大小的,那么对它下4采样就是得到 50 * 50 大小的矩阵。

现在的问题就是 如何确定卷积核的大小和数值???

好了,搜了很久卷积核的数值都没找到,然后发现那个东西叫算子!!!而且,有一些常用的算子,是可以直接用的有个sobel?效果蛮好的。

一些常用的卷积核:


Sobel 算子为例

Sobel 算子 也叫 Sobel 滤波, 是两个 3*3 的矩阵,主要用来计算图像中某一点在横向/纵向上的梯度,看了不少网络上讲解 Sobel 算子 的文章,发现人们常常把它的横向梯度矩阵和纵向梯度矩阵混淆。这可能与 Sobel 算子 在它的两个主要应用场景中的不同用法有关。

Sobel 算子的两个梯度矩阵: Gx 和 Gy

这里以 Wiki 资料为准,Sobel 算子有两个滤波矩阵:Gx 和 Gy, Gx 用来计算横向的梯度,Gy 用来计算纵向的梯度, 下图就是具体的滤波器:

Sobel 算子的用途:

它可以用来对图像进行边缘检测,或者用来计算某个像素点的法线向量。这里需要注意的是:

边缘检测时:Gx 用于检测纵向边缘,Gy 用于检测横向边缘。

计算法线时:Gx 用于计算法线的横向偏移,Gy 用于计算法线的纵向偏移。

横向新值 = (-1) * [左上] + (-2) * [左] + (-1) * [左下] + 1 * [右上] + 2*[右] + 1*[右下]

纵向新值 = (-1) * [左上] + (-2) * [上] + (-1)[右] + 1 * [左下] + 2[下] + 1*[右下]

卷积核的个数对应输出通道,每个卷积核的通道对应输入的通道数

六、实战处理

首先是运用Sobel算子,对于mat文件(也就是矩阵形式)进行一个卷积,mat文件是200 * 200大小的矩阵,算子是3 * 3的,运用以下代码,得到了200 * 200大小的卷积后的矩阵:

对于mat文件的相关操作见 此处

import numpy as np
import scipy.io as scio #读取mat文件所用的包dataFile = 'K://数据集/train/00001/1/1.mat' #mat数据地址def zero_pad(x, pad_height, pad_width):# 先在待处理矩阵周围填充0H, W = x.shape# H为待处理矩阵的高(行),Wi为待处理矩阵的宽(列)out = Noneout = np.zeros((H+2*pad_height, W+2*pad_width))# 知道尺寸后先全填入0out[pad_height:pad_height+H, pad_width:pad_width+W] = x# 后在中间填入x,这样边缘填充0就完成了return outdef conv_fast(x, h):Hi, Wi = x.shape# Hi为待处理矩阵的高(行),Wi为待处理矩阵的宽(列)Hh, Wh = h.shape# Hh为卷积核的高(行),Wi为卷积的宽(列)out = np.zeros((Hi, Wi))# 相当于占位pad_height = Hh // 2   #mode为same情况下,填充0的数量取决于卷积核h的尺寸pad_width = Wh // 2image_padding = zero_pad(x, pad_height, pad_width)h_flip = np.flip(np.flip(h, 0), 1) #np.flip 是翻转函数,参数0为上下翻转也就是行翻转,而参数1为左右翻转也就是列翻转for i in range(Hi):for j in range(Wi):out[i][j] = np.sum(np.multiply(h_flip, image_padding[i:(i+Hh), j:(j+Wh)]))# 加权求和后写入结果到out对应位置return outdata = scio.loadmat(dataFile) #此时读取到的为dict形式
x = data['matrix']#读取其中的矩阵
h = np.array([[-1,-2,-1],[0,0,0],[1,2,1]]) #Sobel算子print('conv2d(x,h) :')
print(conv_fast(x,h)) #输出卷积后的矩阵
print(conv_fast(x,h).shape) #输出矩阵大小

然后我继续处理,因为这样得到的矩阵大小还是200 * 200
参数’full’:
拿到完整的卷积结果

参数’same’:
以中间向两边散开,拿到第一个输入数组同样长度的卷积数组
ps:如果输入数组是偶数长度,则最后一个数向左边取

参数’valid’:
拿到卷积序列的中间部分的一个/两个数(若x×y-1为奇数则取1个,偶数则取2个)

继续更改代码,我发现用signal.convolve2d()这个函数可以直接对两个矩阵卷积,继续修改代码

import numpy as np
import scipy.io as scio
from scipy import signaldataFile = 'K://数据集/train/00001/1/1.mat' #数据位置data = scio.loadmat(dataFile)
x = data['matrix']
h = np.array([[-1,-2,-1],[0,0,0],[1,2,1]]) #卷积核s = signal.convolve2d(x,h, 'valid')print(s)
print(s.shape)

这样得到的矩阵大小是198 * 198的,那我是不是可以循环一下,那要减少150岂不是要循环75次??

七、最终处理

因为我是要对矩阵下4采样,就是说从200 * 200大小的矩阵得到50 * 50大小的矩阵,所以要对上述的代码进行一定的更改:

import numpy as np
import scipy.io as scio
from scipy import signaldataFile = 'K://数据集/train/00001/1/1.mat' #数据位置data = scio.loadmat(dataFile)
x = data['matrix']
h = np.array([[-1,-2,-1],[0,0,0],[1,2,1]]) #卷积核for i in range(0,75):s = signal.convolve2d(x,h, 'valid')x = sprint(s)
print(s.shape)New_data = 'K://数据集/LR/1.mat'scio.savemat(New_data,{'s':s})

这样就得到了50 * 50大小的矩阵了,再把它保存一下~~~

在保存那遇到了点问题,因为mat文件存入的是字典,而我们s中存的是数组,刚开始用的是scio.savemat(New_data,{‘s’:data[‘s’]}),一直说KeyError:s,然后发现,直接像上面那样写就可以了!

所以就处理完了,现在就是写个循环对我所有的mat文件下采样就行了~~~

补:
我又发现了一点问题……

这样卷的太狠了,丢失了很多信息,转换出来的图像和之前差距特别大,我觉得,可能要设置卷积步长,卷一次那种,不是卷这么多次,弄出来是个什么东西,哭了……

行,自己写了一个……

import numpy as np
import scipy.io as scio
from scipy import signaldataFile = 'K://数据集/train/00001/1/1.mat' #数据位置data = scio.loadmat(dataFile)
x = data['matrix']
h = np.array([[-1,-2,-1],[0,0,0],[1,2,1]]) #卷积核def convolution(h, x):n,m = x.shape #n为行,m为列new = []for i in range(1,n+1,4):line = []for j in range(1,m+1,4):a = x[i:i+3,j:j+3]a = signal.convolve2d(a,h,'valid')line.append(a[0][0])new.append(line)return np.array(new)new = convolution(h, x)#卷积过程print(x.shape)
print(new.shape)

a[0][0]是因为如果用a,那么new的shape输出会是(50,50,1,1),而且就是,每一个数据外面多了两层括号,所以就给删了……

大功告成!

参考链接:
1、https://blog.csdn.net/liulina603/article/details/47727277/
2、https://www.zhihu.com/question/22298352
3、https://www.sohu.com/a/241208957_787107
4、https://www.pianshen.com/article/302985268/
5、https://blog.csdn.net/CSDN_CQD/article/details/105224388
6、https://blog.csdn.net/weixin_41861700/article/details/103649951

RF信号下采样/矩阵下采样(附python实现代码)相关推荐

  1. 【机器学习入门】(5) 决策树算法实战:sklearn实现决策树,实例应用(沉船幸存者预测)附python完整代码及数据集

    各位同学好,今天和大家分享一下python机器学习中的决策树算法,在上一节中我介绍了决策树算法的基本原理,这一节,我将通过实例应用带大家进一步认识这个算法.文末有完整代码和数据集,需要的自取.那我们开 ...

  2. 【机器视觉案例】(5) AI视觉,手势调节物体尺寸,附python完整代码

    各位同学好,今天和大家分享一下如何使用opencv+mediapipe完成远程手势调节图片尺寸的案例.先放张图看效果.当拇指和食指竖起时,根据食指间的连线的长度自由缩放图片尺寸.图片的中点始终位于指尖 ...

  3. 【机器视觉案例】(5) AI视觉,远程手势控制虚拟计算器,附python完整代码

    各位同学好,今天和大家分享一下如何使用MediaPipe+Opencv完成虚拟计算器,先放张图看效果.FPS值为29,食指和中指距离小于规定阈值则认为点击按键,为避免重复数字出现,规定每20帧可点击一 ...

  4. 【MediaPipe】(4) AI视觉,远程手势调节电脑音量,附python完整代码

    各位同学好,今天和大家分享一下如何使用MediaPipe完成手势调节电脑音量,先放张图看效果. 注意!! 本节需要用到手部关键点的实时跟踪,我已经在之前的文章中详细写过了,本节会直接使用,有疑问的同学 ...

  5. 【深度学习】(2) 数据加载,前向传播2,附python完整代码

    生成数据集: tf.data.Dataset.from_tensor_slices(tensor变量) 创建一个数据集,其元素是给定张量的切片 生成迭代器: next(iter()) next() 返 ...

  6. 【机器学习入门】(13) 实战:心脏病预测,补充: ROC曲线、精确率--召回率曲线,附python完整代码和数据集

    各位同学好,经过前几章python机器学习的探索,想必大家对各种预测方法也有了一定的认识.今天我们来进行一次实战,心脏病病例预测,本文对一些基础方法就不进行详细解释,有疑问的同学可以看我前几篇机器学习 ...

  7. 【机器学习入门】(8) 线性回归算法:正则化、岭回归、实例应用(房价预测)附python完整代码和数据集

    各位同学好,今天我和大家分享一下python机器学习中线性回归算法的实例应用,并介绍正则化.岭回归方法.在上一篇文章中我介绍了线性回归算法的原理及推导过程:[机器学习](7) 线性回归算法:原理.公式 ...

  8. 前景背景样本不均衡解决方案:Focal Loss,GHM与PISA(附python实现代码)

    参考文献:Imbalance Problems in Object Detection: A Review 1 定义 在前景-背景类别不平衡中,背景占有很大比例,而前景的比例过小,这类问题是不可避免的 ...

  9. 【机器学习入门】(3) 朴素贝叶斯算法:多项式、高斯、伯努利,实例应用(心脏病预测)附python完整代码及数据集

    各位同学好,今天我和大家分享一下朴素贝叶斯算法中的三大模型.在上一篇文章中,我介绍了朴素贝叶斯算法的原理,并利用多项式模型进行了文本分类预测. 朴素贝叶斯算法 -- 原理,多项式模型文档分类预测,附p ...

  10. word2vec模型原理(附python实现代码)

    附python实现代码 模型训练 import logging import gensim from gensim.models import word2vec # 设置输出日志 logging.ba ...

最新文章

  1. java如何被调用_java – 如何知道Parse.initialize()是否已被调用?
  2. 使用Storm实现WordSum
  3. Eclipse安装hibernate插件的问题
  4. 一份技术简历是如何搞定BAT的面试官?
  5. 【BootStrap】初步教程
  6. Java 多线程 并发编程
  7. pythonweb框架_浅谈python web三大框架
  8. Jscript 控制程序的流程
  9. OpenCV-标准霍夫变换cv::HoughLines
  10. JZOJ5197 C
  11. Hawkeye - The .Net Runtime Object Editor
  12. 禁忌搜索算法求解TSP问题python实现
  13. 【软件测试】时制转换时的电话账单
  14. Android 图片资源大瘦身
  15. python文件重命名加日期_Python文件创建日期和Critiqu的重命名请求
  16. 不同网络下 一台电脑连接另一台电脑的mysql数据库
  17. 资源文件冲突error RC2151 : cannot reuse string constants, 61446(0xF006)
  18. 传真服务器的常见问题处理
  19. 类,__dift__,__len__,__add__,__new__,__init__
  20. 人大金仓再次荣获“国家鼓励的重点软件企业”认定

热门文章

  1. Excel里面输入18位数字,但是显示却是其他的?!请问怎么解决?
  2. RK3288 android添加HAL 层导致无法进入主界面原因分析,重复打印 camsys_marvin(deaa1510) is closed
  3. 自动批量配音软件V2.6 附参数和使用教程
  4. 新华文娱数据发布年度白皮书 口碑成观影首要驱动力
  5. 为什么oracle打不开,oracle-Ora-01081_数据库打不开_错误解决方法
  6. 按键精灵打卡怎么写_按键精灵手机版定时点击脚本
  7. 【音乐-睡眠系列】【第一期】音乐改善睡眠质量
  8. vue中forEach跳出循环的问题,以及for循环
  9. java相关资料下载
  10. 我个人的人生学习感想!