2016-04-07 11:50:02 luokh327 阅读数 4579
  • 携手STM32CubeMX玩转STM32

    本课程教大家如何利用STM32CubeMX玩转STM32(STM32CubeMX支持的所有型号MCU都适用于本课程)。课程内容分为基础内容和扩展内容,例如:讲解串口时会扩展开讲Xmodem通信协议,讲解ADC/DAC时会扩展讲傅里叶计算,讲解完FLASH操作会扩展将bootloader的编写,讲解完M3的bootloader编写会扩展讲解M0的bootloader...... 内容绝对实在,对于学习以及工作都会有很大的帮助。最终的目的就是让大家学会快速开发STM32并收获与STM32有关的实用技术知识。

    1001 人正在学习 去看看 李凯龙

1、简介

      在CCS5.5从硬盘读入.dat数据格式的单张图像http://blog.csdn.net/luokh327/article/details/49617041中说明了怎么使用CCS5.5导入单张图像到DSP的SDRAM中,接下来将利用TM6437以及DM642两块芯片对图像进行二维快速傅里叶变换以及IFFT变换、在此基础上进行的滤波操作过程做一下记录整个工程代码下载:http://download.csdn.net/detail/luokh327/9483582

2、二维FFT、IFFT

      对二维傅里叶变换及其逆变换的原理,可以查阅资料获得。这里给出其C语言实现。

      在DSP中做计算时,涉及到很多内存的动态分配,这里采用的是固定内存分配的方式,即将内存直接使用#pragma        DATA_SECTION(IMG,"DDR2_VIDEO"); 的方式直接映射到SDRAM空间中。执行此操作还需要配置相应的内存连接文件.cmd

-c
-stack          0x00020000      /* Stack Size */
-heap           0x00020000      /* Heap Size */

MEMORY
{
    VECS:       o = 0x00000000  l = 0x00000080
    IRAM:       o = 0x00000080  l = 0x00007f80  /*  32 kBytes */
    DRAM:       o = 0x00010000  l = 0x00008000  /*  32 kBytes */
    DDR2:       o = 0x80000000  l = 0x04000000  /* 128 MBytes */
    DDR2_VIDEO: o = 0x84000000  l = 0x04000000  /* 128 MBytes */
}

SECTIONS
{

	.bss        >   DDR2    
	.cinit      >   DDR2    
	.cio        >   DDR2    
	.const      >   DDR2    
	.data       >   DDR2   
	.far        >   DDR2     
	.stack      >   DDR2     
	.switch     >   DDR2    
	.sysmem     >   DDR2    
	.text       >   DDR2    
	.ddr2       >   DDR2 
	.IMG     >  DDR2_VIDEO
	.Source  >  DDR2_VIDEO
	.Scale   > DDR2_VIDEO
	.Out     >  DDR2_VIDEO
	.tdd     > DDR2_VIDEO
	.fdd     > DDR2_VIDEO
	.W       > DDR2_VIDEO
	.X1      >DDR2_VIDEO
	.X2      > DDR2_VIDEO
	.TempT   > DDR2_VIDEO
	.TempF   > DDR2_VIDEO
}

3、滤波

      对2中的FFT2d变换的结果采用退化函数进行退化,然后在频率域下进行滤波操作,滤波完成后进行二维傅里叶逆变换IFFT2d(),便可以得到经过滤波的图像。

4、结果展示


原  图


扩展图


频谱中心化


退化


总体流程变化图


2018-12-09 23:06:23 wuyi0105 阅读数 2353
  • 携手STM32CubeMX玩转STM32

    本课程教大家如何利用STM32CubeMX玩转STM32(STM32CubeMX支持的所有型号MCU都适用于本课程)。课程内容分为基础内容和扩展内容,例如:讲解串口时会扩展开讲Xmodem通信协议,讲解ADC/DAC时会扩展讲傅里叶计算,讲解完FLASH操作会扩展将bootloader的编写,讲解完M3的bootloader编写会扩展讲解M0的bootloader...... 内容绝对实在,对于学习以及工作都会有很大的帮助。最终的目的就是让大家学会快速开发STM32并收获与STM32有关的实用技术知识。

    1001 人正在学习 去看看 李凯龙

图像处理领域离散傅里叶变换的作用

将图像由时空域,转换为频域

二维离散傅里叶变换

二维离散傅里叶变换公式

二维离散傅里叶变换公式

将二维的离散傅里叶变换进行转化

将不好处理的二维离散傅里叶变换转化为进行两次一维处理
先处理行,再处理列
二维离散傅里叶转化为两次一维处理
公式如下:
二维离散傅里叶变换公式

将系数转化为矩阵形式

在这里插入图片描述

注意,从矩阵的乘积i形式可以看出,原来是N个值,输出后依然是N个值,而且要注意,输出的N个值的每一个值和输入得每一个值都有关系。换句话说,输出的F(0),F(1),F(2)…F(N),之中的每一个值,比如F(1),都需要,输入的所有值做贡献。
f(x)的全部值对离散的傅氏变换四项中的每一项都产生影响。反之亦然。

所以按照刚才将维的思路,进行矩阵的操作。
权值矩阵A,原函数矩阵FF

采用88的DFT操作,对每一个88图像块,进行一次操作

matlab代码

N=8;
A=zeros(N);
for k=0:N-1
    for m=0:N-1
        A(k+1,m+1)=(1/N)*exp(-2*pi*i*(k*m/N));%8*8的 w 的矩阵
    end
end

[Hh,Hw]=size(WYY);
X=ceil(Hw/8)*8;
Y=ceil(Hw/8)*8;
hall_new=zeros(X,Y);
hall_new(1:Hh,1:Hw)=WYY;%把Y分量赋值进去
%hall_new(Hh+1:X,1:Hw)=repmat(WYY(Hh,1:Hw),X-Hh,1);
%hall_new(1:Hh,Hw+1:Y)=repmat(WYY(1:Hh,Hw),1,Y-Hw);
m=X/8;%行块数
n=Y/8;%列块数
for i1=1:m
     for i2=1:n
         FF=double(hall_new((i1-1)*8+1:i1*8,(i2-1)*8+1:i2*8));%按顺序取8*8的每一块
         BB((i1-1)*8+1:i1*8,(i2-1)*8+1:i2*8)=N*A*FF*A';%DFT变换,变成两次一维度处理,另一个函数,先处理一行,一行的8个值都会产生影响,以行和列为整体看
         KK((i1-1)*8+1:i1*8,(i2-1)*8+1:i2*8)=A'*BB((i1-1)*8+1:i1*8,(i2-1)*8+1:i2*8)*A;%DFT反变换
     end
end

未完待续

2018-11-23 19:39:43 shanwenkang 阅读数 1422
  • 携手STM32CubeMX玩转STM32

    本课程教大家如何利用STM32CubeMX玩转STM32(STM32CubeMX支持的所有型号MCU都适用于本课程)。课程内容分为基础内容和扩展内容,例如:讲解串口时会扩展开讲Xmodem通信协议,讲解ADC/DAC时会扩展讲傅里叶计算,讲解完FLASH操作会扩展将bootloader的编写,讲解完M3的bootloader编写会扩展讲解M0的bootloader...... 内容绝对实在,对于学习以及工作都会有很大的帮助。最终的目的就是让大家学会快速开发STM32并收获与STM32有关的实用技术知识。

    1001 人正在学习 去看看 李凯龙

二维傅里叶变换

我们先来看看一维情况的傅里叶变换。在信号系统中讲过连续时间的傅里叶变换和离散时间的傅里叶变换,连续时间傅里叶变换在频谱上时非周期的,离散时间傅里叶变换(DTFT)在频谱上是周期的。在DSP中讲了离散傅里叶变换,它的思想是将时域周期化,反映在频域上就是对连续的周期频谱进行抽样

有了一维的离散傅里叶变换(DFT),我们可以将其推广到二维的情况

我们其实可以将二维离散傅里叶变换看成两次一维的离散傅里叶变换,在matlab中我们可以用fft2这个函数来计算

和一维DFT类似,二维DFT显示了图像的频率成分组成情况

如下图所示就是不同的频率成分,也就是说图像实际上是由以下各种不同的图像叠加而成

由于在某一幅特定的图像中,频谱值差距很大,因此我们通常会用log来调整。在实际调用的时候我们还可以采用频谱搬移的方法使得频谱特性更容易观察,例如out=fftshift(log(abs(fft2(im))));由于图像频谱具有中心对称性(一维傅里叶变换是轴对称,二维傅里叶变换是中心对称),我们实际上只需要看频谱的1/2就可以了

我们会看到图中会有两条白色的线,在课程中老师解释说是由于DFT会将图像进行周期化,使得图像的边缘不连续(也就是图像下半部分会与下一幅图的上半部分接壤,左半部分会与右半部分接壤),引入了高频成分导致的。但是关于这点我有点不是很理解,我认为对于一幅图像而言,我们直接对他进行DTFT得到的是一个连续的周期谱,我们对图像进行周期化的过程实际上只是对连续谱进行一个采样,而不会引入新的频率成分,也就是说周期化与否并不影响频谱成分,而差别只是频谱由连续变为离散了。因此我认为频谱存在横竖的白线仅仅是因为图像中存在水平或竖直的边缘(例如上图中的海水与海岸形成竖直的线,山峦与天空形成水平的线)导致的

那么为什么图像中的边缘会使得频谱中也出现相应的白线呢,我们先给出结论:如果图像中存在角度为θ的边线,那么在频谱中我们会看到角度为θ+90度的一条白线。我们在此不做数学上的推导而是举个例子让大家能够理解:我们假设有一幅图像是黑白相间的竖条纹,我们对这幅图像进行傅里叶变换,我们知道二维傅里叶变换可以看做两次一维的傅里叶变换,因此我们对产生图像的矩阵分别进行DFT,得到的结果就是只有频谱中央的一条横线上是有值的,而这个值具体是什么,跟条纹的图案有关

下图是一个实际的例子,我们可以看到对于一幅存在倾斜方格的图片,它的频谱也会出现对应角度的白线

 

二维傅里叶变换的性质

以下是二维傅里叶变换的一些性质,在这就不细讲了

要注意的是DTFT中的卷积性质到DFT中变成了循环卷积,也就是将信号周期化后做卷积(每个位置的值会被循环使用)

但是循环卷积出来的结果往往不是我们想要的,因为周期化的过程使得引入的循环部分也参与卷积运算,而这部分是我们不需要的,解决方法是在序列后面补零,使得循环卷积结果与普通卷积相同,好消息是我们在matlab中调用函数时这些函数会自动帮我们完成这些工作

 

 

2015-06-25 07:00:19 Quason 阅读数 4415
  • 携手STM32CubeMX玩转STM32

    本课程教大家如何利用STM32CubeMX玩转STM32(STM32CubeMX支持的所有型号MCU都适用于本课程)。课程内容分为基础内容和扩展内容,例如:讲解串口时会扩展开讲Xmodem通信协议,讲解ADC/DAC时会扩展讲傅里叶计算,讲解完FLASH操作会扩展将bootloader的编写,讲解完M3的bootloader编写会扩展讲解M0的bootloader...... 内容绝对实在,对于学习以及工作都会有很大的帮助。最终的目的就是让大家学会快速开发STM32并收获与STM32有关的实用技术知识。

    1001 人正在学习 去看看 李凯龙

傅里叶变换在图像处理领域的应用

1、什么是傅里叶变换

任何函数(信号)都能分解成若干个周期函数(周期信号)的叠加形式。在这里原始信号一般是时间域信号或空间域信号,而分解后的信号是频率域信号。下图展示了一维傅里叶变换的过程,其中f=0时的幅值表示信号的直流分量(DC),其余频率的幅值表示信号的交流分量(AC)

2、二维傅里叶变换

图像处理领域用到的傅里叶变换是二维的,其目的是得到空间图像的频率分布情况,之后在频率域对图像进行各种处理可以有目的地实现很多功能。如降噪是弱化频率过高的像素点,图像压缩是对图像高频部分的信息进行简化处理,其余的应用还有图像边缘增强纹理分析等。DC在二维图像信号中表示整幅图像的平均亮度。二维傅里叶图谱中越亮的点对应图像中对比度越大的点,原图频率越集中,对应的频谱图中亮点就越集中。

2019-09-20 19:15:23 qq_42138454 阅读数 869
  • 携手STM32CubeMX玩转STM32

    本课程教大家如何利用STM32CubeMX玩转STM32(STM32CubeMX支持的所有型号MCU都适用于本课程)。课程内容分为基础内容和扩展内容,例如:讲解串口时会扩展开讲Xmodem通信协议,讲解ADC/DAC时会扩展讲傅里叶计算,讲解完FLASH操作会扩展将bootloader的编写,讲解完M3的bootloader编写会扩展讲解M0的bootloader...... 内容绝对实在,对于学习以及工作都会有很大的帮助。最终的目的就是让大家学会快速开发STM32并收获与STM32有关的实用技术知识。

    1001 人正在学习 去看看 李凯龙

  这学期选了《图像工程基础》这门课,课上老师留了一个作业:对图像进行二维傅里叶变换。

  现在我使用matlab解决这个问题

 1.实验基本指令

首先我试了一下matlab图像处理的基本指令

原图:

经过以下指令后

将图片导入matlab后,命名为ini,经过以下指令后,图片变为

ini(:,:,1)=0;
ini(:,:,2)=0;
imshow(ini);

 

2.进行二维傅里叶变换

仍然以上文的图片为例(在我的文件夹中这张图片名为'千反田2.jpg')

前置代码:

ini=imread('千反田2.jpg');
iniGray=rgb2gray(ini);
iniDouble=im2double(iniGray);
  • ini矩阵是720*1280*3的矩阵,其中720*1280是图片的尺寸(像素点),3是RGB数值(一共有三层)
  • iniGray是将原图像灰度化后的矩阵,720*1280
  • iniDouble则是将iniGray归一化后的矩阵,720*1280

如图是iniGray矩阵的值(一部分)

 

以下是iniDouble(部分)

 

注:

在实验过程后,我将iniDouble整个矩阵乘以255后,可以发现iniGray与iniDouble矩阵是完全相同的

iniDouble=iniDouble*255;

这说明,im2Double()这个过程的算法,不过是把灰度矩阵的数据全部除以255;

实际上,如果不使用im2Double这个命令,后面的步骤仍然可以继续进行。

 

 

 

 

 

 

 

进行fftshift后:

 

 

 

整体代码:

ini=imread('千反田2.jpg');
iniGray=rgb2gray(ini);
iniDouble=im2double(iniGray);
iniFFT=fft2(iniDouble);
iniShift=fftshift(iniFFT);
iniAbs=abs(iniShift);
iniT=log(iniAbs+1);
imshow(iniT,[]);

取对数原因:

iniAbs矩阵中,数的范围大致在0~500000之间,靠近500000的值实际上非常少,大部分<10,这样,如果进行绘图imshow(iniAbs,[]),会导致整个图像基本是黑的,因为imshow(iniT,[])命令把最大的那个值(接近500000)当作白色,而矩阵中的其他部分全部被划为灰度值十分接近0的黑色。

而在取对数后,iniT的值大致局限在了[0,13]。因为对数的增长十分缓慢,所以对数化后的矩阵的矩阵各个值之间的差变小了

imshow(iniT,[])命令把13当作白色,而接近13的数比较多,所以导致图像不会几乎全黑,能够直观显示

 

画图命令使用imshow(iniT,[])而不是imshow(iniT)的原因:

imshow(iniT)只使用iniT矩阵中值在[0,1]之间的部分,而iniT实际上大致在[0,13]之间,所以不能正确显示图像。如果使用imshow(iniT/13)或者imshow(iniT,[]),那么均可以正确显示图像

 

 

 

结果:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

图像的傅里叶变换

阅读数 6644

没有更多推荐了,返回首页