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

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

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

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

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

二维离散傅里叶变换

二维离散傅里叶变换公式

二维离散傅里叶变换公式

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

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

将系数转化为矩阵形式

在这里插入图片描述

注意,从矩阵的乘积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-12-30 15:24:17 webzhuce 阅读数 2291
  • 携手STM32CubeMX玩转STM32

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

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

图像傅里叶变换

二维离散傅里叶变换是将图像从空间域转至频域,在图像增强、图像去噪、图像边缘检测、图像特征提取、图像压缩等等应用中都起着极其重要的作用。理论基础是任意函数都可以表示成正弦函数的线性组合的形式。公式如下
在这里插入图片描述
逆变换公式如下
在这里插入图片描述
令 R(u,v) 和 I(u,c) 分别表示 F(u,v) 的实部和虚部。
幅度谱为
在这里插入图片描述
相位谱为
在这里插入图片描述
指数表示
在这里插入图片描述
功率谱为
在这里插入图片描述

示例演示

首先我们演示下,从一幅图像得到其的幅度谱和相位谱,然后再根据幅度谱和相位谱还原图像。代码如下。

void MainWindow::dftTransform(cv::Mat &image)
{
    image.convertTo(image, CV_32F);
    std::vector<cv::Mat> channels;
    split(image, channels);  //分离图像的RGB通道,
    cv::Mat image_B = channels[0]; //OpenCV:BGR
    //expand input image to optimal size
    int m1 = cv::getOptimalDFTSize(image_B.rows);  //选取最适合做fft的宽和高
    int n1 = cv::getOptimalDFTSize(image_B.cols);
    cv::Mat padded;
    //填充0
    cv::copyMakeBorder(image_B, padded, 0, m1 - image_B.rows, 0, n1 - image_B.cols, cv::BORDER_CONSTANT, cv::Scalar::all(0));
    cv::Mat planes[] = { cv::Mat_<float>(padded), cv::Mat::zeros(padded.size(), CV_32F) };
    cv::Mat complexI;
    cv::merge(planes, 2, complexI);  //planes[0], planes[1]是实部和虚部

    cv::dft(complexI, complexI, cv::DFT_SCALE | cv::DFT_COMPLEX_OUTPUT);
    cv::split(complexI, planes);

    //定义幅度谱和相位谱
    cv::Mat ph, mag, idft;
    cv::phase(planes[0], planes[1], ph);
    cv::magnitude(planes[0], planes[1], mag);  //由实部planes[0]和虚部planes[1]得到幅度谱mag和相位谱ph

    cv::imshow("phase", ph);
    cv::imshow("magnitude", mag);
    /*
    如果需要对实部planes[0]和虚部planes[1],或者幅度谱mag和相位谱ph进行操作,在这里进行更改
    */


    cv::polarToCart(mag, ph, planes[0], planes[1]);  //由幅度谱mag和相位谱ph恢复实部planes[0]和虚部planes[1]
    cv::merge(planes, 2, idft);
    cv::dft(idft, idft, cv::DFT_INVERSE | cv::DFT_REAL_OUTPUT);
    image_B = idft(cv::Rect(0, 0, image.cols & -2, image.rows & -2));
    image_B.copyTo(channels[0]);
    merge(channels, image);
    image.convertTo(image, CV_8U);
    cv::imshow("idft", image);
}

运行结果

在这里插入图片描述

2018-08-22 15:49:09 Replus_ 阅读数 8590
  • 携手STM32CubeMX玩转STM32

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

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

声明:       

       这篇文章的主要目的是通过建立一维傅里叶变换与图像傅里叶变换中相关概念的对应关系来帮助读者理解图像处理中的离散傅里叶变换,因此,理解图像中离散傅里叶变换的前提条件是读者需要了解一维傅里叶变换的基本知识,详情可参考:https://zhuanlan.zhihu.com/p/19763358


基本数学概念的对应关系:

       一维傅里叶变换的作用对象是信号,信号是一维连续的,其数学表现形式如图1所示,该图反应的是随着时间不断推移,信号强度的变换情况,可称为时域:

图1

       而图像处理中的傅里叶变换的作用对象是二维矩阵。二维矩阵的数学表现形式如下图所示,反应了随着位置的不断改变,灰度值大小的变化情况。我们在此将其称为“距离-灰度变化图”:

图2

       从正面看去,由x轴与灰度值轴构成的切面图如图3所示:

图3

       图3与图1的本质是类似的,都是一个自变量一个因变量。因此可以构成对应关系:时间<->距离、信号强度<->灰度值。

傅里叶变换结果的对应关系:

       一维傅里叶变换的原理可以通俗的理解为:将一个复杂无规律的信号拆分成多个简单有规律的子信号来表示(如果对泰勒展开有深刻的理解的话,可以将傅里叶变换理解为将任意一个函数分解为任意个多项式的组合)。如图4所示。

图4

       为了定量表示这个结果,我们用下图进行表达。其中,横轴为频率大小,纵轴为振幅(即信号的最高强度),该图可称为频谱

图5

       通过观察频谱,我们可以发现,频谱中的每个点在时域中都对应一个函数(这个特点很重要,说明了频谱和时域的对应关系是点与线)。

       因此,通过类比,可将图像处理中傅里叶变换理解为:将一个复杂无规律的图像拆分成多个简单有规律的子图像来表示(此处画图太麻烦,请读者自行发挥想象力对图4中的众多子信号,想象成不断起伏的平面)。

       那要如何定量表达众多分解后的子图像呢?

       我们先来看一下图像傅里叶变换后的表现形式,即图像的“频谱”。

       现在,我们就通过类比,来理解这上幅图中的各个方向的自变量到底对应信号频谱中的哪个变量。

       在信号的频谱中,频率的定义为:单位时间内完成周期性变化的次数。而在上文“基本数学概念的对应关系”中,我们已经将时间和距离对应起来了。那么此处只需要将频率定义中的“时间”换成“距离”即可。最终得到用于表达图像傅里叶变换结果的“频谱”中频率的定义:单位距离内完成周期性变化的次数。由于图像中表达距离的单位是像素大小,所以对这个定义进一步可理解为:N个像素内灰度值完成周期性变化的次数。因此我们就成功的将图像“频谱”和信号“频谱”中的自变量联立起来了。在信号频谱中的频率是x(横)轴,而在图像的频谱中频率是(xy轴构成的)平面。距离原点越远,则说明频率越大。因此,窗口边缘处即为高频区域,原点周边即为低频区域。

注意:上文提到了对于信号来说,频谱中的一个点对应子信号时域中的一条线。通过类比,我们可以得出结论:图像频谱中的一个点对应子图像的一整张距离-灰度变化图。(而图像傅里叶变换的数学公式也反应了这个特点)

       同样的,信号频谱中的y轴反应子信号,信号强度的变化范围,而图像频谱中的z轴反应子图像的灰度值的变化范围。频谱窗口中对应的点越亮,则说明该点对应频率的变化范围越大。

总结与举例:

       综上,可对图像频谱进行解读:

       距离原点越远=频率越高=原图中灰度值的变化越频繁。

       灰度值越大=幅值越大=原图中灰度值变化的范围越大。

       因此,低通滤波能保留图像的大致轮廓信息是因为,一张图像所记录到的主要信息(由于受到关照等必然因素的影响)在图像上灰度值的变化是缓慢的,因此主要信息集中在低频区域。而噪音等偶然因素是突然附加到图像上使得灰度值快速变化,而且密密麻麻,这导致N个像元内,灰度值的变化不仅频繁,而且变化的范围还很大。因此,噪音就位于图像频谱的高频区域,表现为高灰度值。

 

 

2016-11-09 12:07:55 BaiYH1994 阅读数 2666
  • 携手STM32CubeMX玩转STM32

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

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

  图像傅里叶变换方法有很多,可以通过空间光调制器输入图像后在通过平行光照明经过傅里叶变换透镜进行傅里叶变换,另一个方法就是利用计算机进行傅里叶变换,其中傅里叶变换有两种算法一种是DFT还有一种是FFT(快速傅里叶变换)。

  首先我介绍一下图像的定义,图像是怎么去得到的呢?图像是物体与点扩散函数卷积的结果加上一个噪声项(具体想了解可以查看“傅里叶光学"-吕乃光)。

  在这里我谈谈离散傅里叶变换的一些问题,以及离散傅里叶变换的MATLAB代码。首先谈谈傅里叶变换,想必大家一听到傅里叶变换整个人都不好了,傅里叶变换是做什么的呢,个人的理解就是通过无数个正交的向量去描述一个任意的曲线或者信号,最简单的理解就是我们可以通过xy直角坐标系通过一个关系建立一个二维曲线,这样我们就可以通过一个正交的向量去描述这个线上的任意一个点。

  在傅里叶变换中所谓的空间频率的高频与低频分别代表什么呢?高频代表的就是图像中灰度突变速度快的地方,说白了就是看起来密集的地方就是高频,看起来平坦的地方就是低频。这是最简单的理解方式。离散傅里叶变换可以处理任意大小的图像,FFT只能处理2^n*2^n大小的图像,当图像大小不够的时候需要填补空缺的地方。

一下为DFT函数的matlab代码,

<span style="font-size:18px;">function [out_dft_image,out_ab_dft_pic]=dft(input_image,mode)
%%  [out_dft_image,out_ab_dft_pic]=dft_test(input_image)     this function can make dft transform
% F(u-M/2,v-N/2)<=>f(x,y)*(-1).^(x+y)   or you can make dft transform like
% F(u,v)<=>f(x,y)
%     input_image:  had batter less than 150*150 large
%     mode:   if mode==1  this function is to do comfortable visable result   
%             else mode=~1 the result maybe make you uncomfortable 
%     out_dft_image: this is the complex matrix it can make the idft and
%                   get the surse image in spetial domain 
%     out_ab_dft_pic: this is the frequency spectrum picture matrix
%     design by baiyinhao 2015.9.28    20:07 Email:792499178@qq.com
%
%     作  者:光电科技协会     2015.9.28    20:07  白银浩
%


%空域变换到频率域
pic=double(input_image);
[u_p,v_p]=size(pic);%  F(u,v)中的u,v
%f(x,y)*(-1).^(x+y)   即对原图进行一次运算
if mode==1
    
    for x=1:u_p
        for y=1:v_p
            pic(x,y)=pic(x,y)*(-1)^(x+y);%在此处对输入的pic进行了改变  即变成f(x,y)*(-1).^(x+y) 白  添加 
        end
    end
    
    %居中傅里叶变换
    [x_p,y_p]=size(pic);
    dft_pic=zeros(u_p,v_p);
    flag=0;
    temp1=0;
    for u=1:u_p
        for v=1:v_p
            for x=1:x_p
                for y=1:y_p
                    temp1=temp1+pic(x,y)*exp(-1j*2*pi*(u*x/u_p+v*y/v_p));
                end
            end
            dft_pic(u,v)=temp1;
            temp1=0;
        end
        flag=flag+1;
        sprintf('运行到了图像的第:%d 行',flag)
    end
    %输出傅里叶变换 后的实部虚部
    R_dft_pic=real(dft_pic);%求出傅里叶变换后的实部
    I_dft_pic=imag(dft_pic);%求出傅里叶变换后的虚部

    %傅里叶谱
    ab_dft_pic(u_p,v_p)=0;
    for u=1:u_p
        for v=1:v_p
            ab_dft_pic(u,v)=sqrt(R_dft_pic(u,v).^2+I_dft_pic(u,v).^2);
       end
    end
    %最后输出值 
    m_dft_pic=max(max(ab_dft_pic));
    ab_dft_pic1=ab_dft_pic/m_dft_pic*255;



else
   %正常傅里叶变换
    [x_p,y_p]=size(pic);
    dft_pic=zeros(u_p,v_p);
    flag=0;
    temp1=0;
    for u=1:u_p
        for v=1:v_p
            for x=1:x_p
                for y=1:y_p
                    temp1=temp1+pic(x,y)*exp(-1j*2*pi*(u*x/u_p+v*y/v_p));
                end
            end
            dft_pic(u,v)=temp1;
            temp1=0;
        end
        flag=flag+1;
        sprintf('运行到了图像的第:%d 行',flag)
    end
    %输出傅里叶变换 后的实部虚部 白银浩添加
    R_dft_pic=real(dft_pic);%求出傅里叶变换后的实部
    I_dft_pic=imag(dft_pic);%求出傅里叶变换后的虚部

    %傅里叶谱
    ab_dft_pic(u_p,v_p)=0;
    for u=1:u_p
        for v=1:v_p
            ab_dft_pic(u,v)=sqrt(R_dft_pic(u,v).^2+I_dft_pic(u,v).^2);
        end
    end
    %最后输出值 
    m_dft_pic=max(max(ab_dft_pic));
    ab_dft_pic1=ab_dft_pic/m_dft_pic*255;
 end


    out_dft_image=dft_pic;
    out_ab_dft_pic=uint8(ab_dft_pic1);


end</span>

由于运行速度慢,有助于理解,如果有实际用途建议使用FFT。


2016.11.9   12:09

白银浩    

E-mail:BaiYH1994@163.com

Q    Q:792499178

2018-07-07 21:16:27 lindamtd 阅读数 6115
  • 携手STM32CubeMX玩转STM32

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

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

最近在看物体识别论文摘要,好多论文中涉及到使用离散余弦傅里叶变换DFT(Discrete Fourier Transform)对图像进行处理,因此特地看了这部分的内容,傅里叶变换和小波变换。

一、DFT的原理:

以二维图像为例,归一化的二维离散傅里叶变换可以写成如下形式:


其中f(x,y)表示图像的空间域的值,而F表示频域的值,傅里叶转换的结果为复数,这也表明,傅里叶变换其实是一副实数图像和虚数图像叠加或幅度图像和相位图像叠加的结果,在实际的图像处理算法中,仅有幅度图像能够用得到,因为其包含了图像的所有几何结构信息。但是如果想通过修改幅度图和相位图来修改原空间图像,需保留幅度图和相位图来进行傅里叶变换,从而得到修改后的图像。

在频域里面,高频部分代表了图像边缘、线条以及纹理等细节信息,低频部分代表了图像的轮廓信息。在这里首先介绍下空间域和频率域:

空间域:

一般情况下,空间域的图像为f(x,y),形象一点就是一个二维矩阵,每个坐标对应一个颜色值。

频率域:

频率:对于图像来说,可以指图像颜色值的梯度,即灰度级的变化速度。

幅度:频率的权,即该频率所占的比例。

二、代码实现与效果

#include<iostream>
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
using namespace std;
using namespace cv;
int main()
{
	//(1)读取原图像
	Mat src = imread("101200.jpg",0);
	if (!src.data)
	{
		cout << "Reading image error!" << endl;
		return false;
	}
	imshow("src",src);
	//(2)将输入图像扩展到最佳尺寸,将添加的像素扩展为0
	int m = getOptimalDFTSize(src.rows);
	int n = getOptimalDFTSize(src.cols);
	Mat padded;
	copyMakeBorder(src,padded,0,m-src.rows,0,n-src.cols,BORDER_CONSTANT,Scalar::all(0));//扩充图像边界
	//(3)为傅里叶变换的结果(实部和虚部)分配存储空间
	//将planes数组合并成一个多通道的数组complexI
	Mat planes[] = {Mat_<float>(padded), Mat::zeros(padded.size(),CV_32F)};
	Mat complexI;
	merge(planes,2,complexI);
	//(4)离散傅里叶变换
	dft(complexI,complexI);
	//(5)将复数转换为幅值,即=> log(1 + sqrt(Re(DFT(I))^2 + Im(DFT(I))^2))
	split(complexI, planes); // 将多通道数组complexI分离成几个单通道数组,planes[0] = Re(DFT(I), planes[1] = Im(DFT(I))
	magnitude(planes[0], planes[1], planes[0]);//planes[0] = magnitude
	Mat magnitudeImage = planes[0];
	//(5)进行对数尺度(logarithmic scale)缩放
	//由于幅度范围太大,不适合在屏幕显示。为了在屏幕显示,用对数尺度来替换线性尺度M1=log(1+M)
	magnitudeImage += Scalar::all(1);//转换到对数尺度
	log(magnitudeImage, magnitudeImage);//求自然对数
	//(6)剪切和重分布幅度图象限
	/*
	剔除第二步添加的像素。重分布是把四个象限的四张图像拼接到一起
	*/
	//若有奇数行或奇数列,进行频谱裁剪      
	magnitudeImage = magnitudeImage(Rect(0, 0, magnitudeImage.cols & -2, magnitudeImage.rows & -2));
	//重新排列傅立叶图像中的象限,使得原点位于图像中心  
	int cx = magnitudeImage.cols / 2;
	int cy = magnitudeImage.rows / 2;
	Mat q0(magnitudeImage, Rect(0, 0, cx, cy));  //roi区域的左上
	Mat q1(magnitudeImage, Rect(cx, 0, cx, cy));  //roi区域的右上
	Mat q2(magnitudeImage, Rect(0, cy, cx, cy));  //roi区域的左下
	Mat q3(magnitudeImage, Rect(cx, cy, cx, cy)); //roi区域的右下
	//交换象限(左上与右下进行交换)
	Mat tmp;
	q0.copyTo(tmp);
	q3.copyTo(q0);
	tmp.copyTo(q3);
	//交换象限(右上与左下进行交换)
	q1.copyTo(tmp);
	q2.copyTo(q1);
	tmp.copyTo(q2);
	//(7)归一化,用0到1之间的浮点值将矩阵变换为可视的图像格式
	/*
	幅度值仍然超过可显示范围[0,1],normalize()归一化后可以显示
	*/
	normalize(magnitudeImage, magnitudeImage, 0, 1, NORM_MINMAX); 
	//【9】显示效果图
	imshow("dft", magnitudeImage);
	//逆变换
	Mat _complexim;
	complexI.copyTo(_complexim);//把变换结果复制一份,进行逆变换,也就是恢复原图
	Mat iDft[] = { Mat::zeros(planes[0].size(), CV_32F), Mat::zeros(planes[0].size(), CV_32F) };//创建两个通道,类型为float,大小为填充后的尺寸
	idft(_complexim, _complexim);//傅立叶逆变换
	split(_complexim, iDft);//结果貌似也是复数
	magnitude(iDft[0], iDft[1], iDft[0]);//分离通道,主要获取0通道
	normalize(iDft[0], iDft[0], 1, 0, CV_MINMAX);//归一化处理,float类型的显示范围为0-1,大于1为白色,小于0为黑色
	imshow("idft",iDft[0]);
	waitKey(0);
	return 0;
}

实现结果:


二、小波变换

# include<opencv2/opencv.hpp>
# include<iostream>

using namespace std;
using namespace cv;

int main()
{
	Mat img = imread("101200.jpg", 0);
	int Height = img.cols;
	int Width = img.rows;
	int depth = 1;    //定义分解深度,也就是几级分解
	int depthcount = 1;
	Mat tmp = Mat::ones(Width, Height, CV_32FC1);//CV_32FC1表示32位float,这在32位编译器上是32位float,也就是单精度。CV_64FC1在32位编译器上是64位float,也就是双精度。
	Mat wavelet = Mat::ones(Width, Height, CV_32FC1);
	Mat imgtmp = img.clone();
	imgtmp.convertTo(imgtmp, CV_32FC1);
	while (depthcount <= depth){
		Width = img.rows / depthcount;
		Height = img.cols / depthcount;
		for (int i = 0; i < Width; i++)
		{
			for (int j = 0; j < Height / 2; j++)
			{
				tmp.at<float>(i, j) = (imgtmp.at<float>(i, 2 * j) + imgtmp.at<float>(i, 2 * j + 1)) / 2;//整体信息
				tmp.at<float>(i, j + Height / 2) = (imgtmp.at<float>(i, 2 * j) - imgtmp.at<float>(i, 2 * j + 1)) / 2;//细节信息
			}
		}
		for (int i = 0; i < Width / 2; i++)
		{
			for (int j = 0; j < Height; j++)
			{
				wavelet.at<float>(i, j) = (tmp.at<float>(2 * i, j) + tmp.at<float>(2 * i + 1, j)) / 2;//整体信息
				wavelet.at<float>(i + Width / 2, j) = (tmp.at<float>(2 * i, j) - tmp.at<float>(2 * i + 1, j)) / 2;//细节信息
			}
		}
		imgtmp = wavelet;
		depthcount++;
	}
	wavelet.convertTo(wavelet, CV_8UC1);
	wavelet += 100;            //图像暗度过低,所以这里我加了50
	imshow("小波变换", wavelet);
	waitKey(0);
	return 0;
}

实现效果:

.

图像的傅里叶变换

阅读数 6640

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