📄 freqpro.cpp
字号:
if(bIs2Power((int)mSize.r(1,2))) bPowered = TRUE;
if(bIs2Power((int)mSize.r(1,2)/12)) bPowered = TRUE;
if(bIs2Power((int)mSize.r(1,2)/20)) bPowered = TRUE;
if(!bPowered)
{
// 提示用户参数设置错误
AfxMessageBox("尺寸不是2^N、12*2^N、20*2^N,无法生成哈达玛矩阵!");
// 返回
return( FALSE );
}
//生成哈达玛矩阵
Mm HColum = hadamard(mSize.r(1,1));
Mm HRow = hadamard(mSize.r(1,2));
//进行离散哈达玛变换
Mm ff = HRow * m_matBits * HColum;
Mm matTransed = ff / (mSize.r(1,1)*mSize.r(1,2));
//调整系数以便以图像方式显示结果
ff = ff / sqrt(mSize.r(1,1)*mSize.r(1,2));
//调用Matrix<Lib>C++库函数mabs()计算频谱
m_matBits = mabs(ff);
//将矩阵数据赋给图像数据区
SetBits();
return matTransed;
}
////////////////////////////////////////////////////////////////////////
//BOOL NWHT2()
//----------------------------------------------------------------------
//基本功能:本函数完成图像的快速傅立叶逆变换。
//----------------------------------------------------------------------
//参数说明:Mm matTransed 被变换的矩阵
//----------------------------------------------------------------------
//返 回:BOOL
// 成功时返回TRUE,失败时返回FALSE。
//----------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////
BOOL CFreqPro::NWHT2(Mm matTransed)
{
//若未指定 CDibObject 对象指针返回FALSE
if( m_pDibObject == NULL ) return( FALSE );
//获得矩阵的行数和列数
Mm mSize = size(matTransed);
BOOL bPowered = FALSE;
if(bIs2Power((int)mSize.r(1,1))) bPowered = TRUE;
if(bIs2Power((int)mSize.r(1,1)/12)) bPowered = TRUE;
if(bIs2Power((int)mSize.r(1,1)/20)) bPowered = TRUE;
if(bIs2Power((int)mSize.r(1,2))) bPowered = TRUE;
if(bIs2Power((int)mSize.r(1,2)/12)) bPowered = TRUE;
if(bIs2Power((int)mSize.r(1,2)/20)) bPowered = TRUE;
if(!bPowered)
{
// 提示用户参数设置错误
AfxMessageBox("尺寸不是2^N、12*2^N、20*2^N,无法生成哈达玛矩阵!");
// 返回
return( FALSE );
}
//生成哈达玛矩阵
Mm HColum = hadamard(mSize.r(1,1));
Mm HRow = hadamard(mSize.r(1,2));
//进行离散哈达玛变换
m_matBits = HRow * matTransed * HColum;
//将矩阵数据赋给图像数据区
SetBits();
return(TRUE);
}
////////////////////////////////////////////////////////////////////////
//Mm dct()
//----------------------------------------------------------------------
//基本功能:本函数完成一个向量X的一维离散余弦变换。
//----------------------------------------------------------------------
//参数说明:Mm a 待变换向量(若为矩阵,按列进行运算)
// Mm n 变换长度,若指定该参数,则自动将向量a补0或自动裁剪到
// 指定长度。
//----------------------------------------------------------------------
//返 回:Mm
// 变换结果矩阵。
//----------------------------------------------------------------------
//注 意:此函数声明为保护型,只能在CFreqPro类中使用
//----------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////
Mm CFreqPro::dct(Mm a, Mm n)
{
//定义相关矩阵变量
a.setname("a"); n.setname("n");
dMm(b); dMm(do_trans); dMm(m); dMm(aa); dMm(ww); dMm(y); dMm(yy);
//判断输入参数是否正确
double old_nargin=nargin_val;
if (!nargin_set) nargin_val=2.0;
nargin_set=0;
double old_nargout=nargout_val;
if (!nargout_set) nargout_val=1.0;
nargout_set=0;
if (istrue(nargin()==0.0))
{
error(TM("输入参数为空,无法完成操作!"));
}
if (istrue(isempty(a)))
{
error(TM("输入矩阵为空,无法完成操作!"));
b = nop_M;
nargin_val=old_nargin; nargout_val=old_nargout;
a.setname(NULL); n.setname(NULL);
return b;
}
//如果输入为一行向量,将其转换为列向量。
do_trans = (size(a,1.0)==1.0);
if (istrue(do_trans))
{
//是行向量,转换为列向量。
//相当于Matlab的a=a(:)。
a = a(c_p);
}
//只有一个输入参数,未指定变换点数n。
if (istrue(nargin()==1.0))
{
//得到第一维长度(矩阵列长度)
n = size(a,1.0);
}
//得到第二维长度(矩阵行长度)
m = size(a,2.0);
//根据需要为矩阵补零或截去多余元素
if (istrue(size(a,1.0)<n))
{
//矩阵列长度小于指定的变换点数
//生成n×m的零矩阵
aa = zeros(n,m);
//从输入矩阵a中取得所需元素
//相当于Matlab的aa(1:size(a,1),:) = a。
aa(colon(1.0,1.0,size(a,1.0)),c_p) = a;
}
else
{
//矩阵列长度大于或等于指定的变换点数
//从输入矩阵a中取得所需元素
//相当于Matlab的aa = a(1:n,:)。
aa = a(colon(1.0,1.0,n),c_p);
}
//计算用于DFT计算的系数
ww = transpose((exp(-i*(colon(0.0,1.0,n-1.0))*pi/(2.0*n))/msqrt(2.0*n)));
//调整第一个系数
ww(1.0) = ww(1.0)/msqrt(2.0);
//进行变换
if (istrue(rem(n,2.0)==1.0)||istrue(!isreal(a)))
{
//n为奇数
//生成中间变换矩阵
//生成2.0*n×m的零矩阵
y = zeros(2.0*n,m);
//相当于Matlab的y(1:n,:) = aa和y(n+1:2*n,:) = flipud(aa);。
y(colon(1.0,1.0,n),c_p) = aa;
y(colon(n+1.0,1.0,2.0*n),c_p) = flipud(aa);
//调用Matrix<Lib>C++库函数FFT()进行快速离散傅立叶变换,
yy = fft(y);
//保留需要的变换结果数据
//相当于Matlab的yy = yy(1:n,:)。
yy = yy(colon(1.0,1.0,n),c_p);
}
else
{
//n为偶数
//对aa矩阵的各列元素重新进行排序
//相当于Matlab的y = [ aa(1:2:n,:); aa(n:-2:2,:) ]。
y = (BR(aa(colon(1.0,2.0,n),c_p)),semi,
aa(colon(n,-2.0,2.0),c_p));
//调用Matrix<Lib>C++库函数FFT()进行快速离散傅立叶变换,
yy = fft(y);
//调整变换系数矩阵
ww = 2.0*ww;
}
//对FFT变换结果乘以变换系数
//相当于Matlab的b = ww(:,ones(1,m)) .* yy。
b = times(ww(c_p,ones(1.0,m)),yy);
//如果输入矩阵是实数矩阵,输出取变换结果的实部。
if (istrue(isreal(a)))
{
b = real(b);
}
//如果输入的是行向量,对结果进行转置操作。
if (istrue(do_trans))
{
b = transpose(b);
}
nargin_val=old_nargin; nargout_val=old_nargout;
a.setname(NULL); n.setname(NULL);
return b;
}
////////////////////////////////////////////////////////////////////////
//Mm dct()
//----------------------------------------------------------------------
//基本功能:本函数为离散余弦变换的无参重载版本。
//----------------------------------------------------------------------
//参数说明:无
//----------------------------------------------------------------------
//返 回:Mm
// 变换结果矩阵。
//----------------------------------------------------------------------
//注 意:此函数声明为保护型,只能在CFreqPro类中使用
//----------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////
Mm CFreqPro::dct()
{
begin_scope
double old_nargin=nargin_val; nargin_val=0.0; nargin_set=1;
dMm(a); dMm(n);
dMm(ret1a);
ret1a=dct(a, n);
nargin_val=old_nargin;
return ret1a;
end_scope
}
////////////////////////////////////////////////////////////////////////
//Mm dct()
//----------------------------------------------------------------------
//基本功能:本函数为离散余弦变换的无指定变换长度重载版本。
//----------------------------------------------------------------------
//参数说明:Mm a 待变换向量(若为矩阵,按列进行运算)
//----------------------------------------------------------------------
//返 回:Mm
// 变换结果矩阵。
//----------------------------------------------------------------------
//注 意:此函数声明为保护型,只能在CFreqPro类中使用
//----------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////
Mm CFreqPro::dct(Mm a)
{
begin_scope
double old_nargin=nargin_val; nargin_val=1.0; nargin_set=1;
dMm(n);
dMm(ret1a);
ret1a=dct(a, n);
nargin_val=old_nargin;
return ret1a;
end_scope
}
////////////////////////////////////////////////////////////////////////
//Mm dct2()
//----------------------------------------------------------------------
//基本功能:本函数完成矩阵的一维离散余弦变换。
//----------------------------------------------------------------------
//参数说明:Mm arg1 待变换矩阵
// Mm mrows 行变换长度,若指定该参数,则自动将向量a补0或自动
// 裁剪到指定长度。
// Mm ncols 列变换长度,若指定该参数,则自动将向量a补0或自动
// 裁剪到指定长度。
//----------------------------------------------------------------------
//返 回:Mm
// 变换结果矩阵。
//----------------------------------------------------------------------
//注 意:此函数声明为保护型,只能在CFreqPro类中使用。该函数是先对矩阵
// 按列进行一维离散余弦变换,再对其按列进行一维离散余弦变换,最
// 终得到其二维离散余弦变换结果。对程序在此不加详细注释,请参考
// 一维离散余弦变换程序注释。
//----------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////
Mm CFreqPro::dct2(Mm arg1, Mm mrows, Mm ncols)
{
arg1.setname("arg1"); mrows.setname("mrows"); ncols.setname("ncols");
dMm(b); dMm(m); dMm(n); dMm(a); dMm(mpad); dMm(npad);
double old_nargin=nargin_val;
if (!nargin_set) nargin_val=3.0;
nargin_set=0;
double old_nargout=nargout_val;
if (!nargout_set) nargout_val=1.0;
nargout_set=0;
size(arg1,i_o,m,n);
if (istrue(nargin()==1.0))
{
if (istrue((m>1.0))&&istrue((n>1.0)))
{
b = transpose(dct(transpose(dct(arg1))));
nargin_val=old_nargin; nargout_val=old_nargout;
arg1.setname(NULL); mrows.setname(NULL); ncols.setname(NULL);
return b;
}
else
{
mrows = m;
ncols = n;
}
}
a = arg1;
if (istrue(nargin()==2.0))
{
ncols = mrows(2.0);
mrows = mrows(1.0);
}
mpad = mrows;
npad = ncols;
if (istrue(m==1.0)&&istrue(mpad>m))
{
a(2.0,1.0) = 0.0;
m = 2.0;
}
if (istrue(n==1.0)&&istrue(npad>n))
{
a(1.0,2.0) = 0.0;
n = 2.0;
}
if (istrue(m==1.0))
{
mpad = npad;
npad = 1.0;
}
b = dct(a,mpad);
if (istrue(m>1.0)&&istrue(n>1.0))
{
b = transpose(dct(transpose(b),npad));
}
arg1.setname(NULL); mrows.setname(NULL); ncols.setname(NULL);
return b;
}
////////////////////////////////////////////////////////////////////////
//Mm dct2()
//----------------------------------------------------------------------
//基本功能:本函数为二维离散余弦变换的无指定变换长度重载版本。
//----------------------------------------------------------------------
//参数说明:Mm arg1 待变换矩阵
//----------------------------------------------------------------------
//返 回:Mm
// 变换结果矩阵。
//----------------------------------------------------------------------
//注 意:此函数声明为保护型,只能在CFreqPro类中使用
//----------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////
Mm CFreqPro::dct2(Mm arg1)
{
begin_scope
double old_nargin=nargin_val; nargin_val=1.0; nargin_set=1;
dMm(mrows); dMm(ncols);
dMm(ret1a);
ret1a=dct2(arg1, mrows, ncols);
nargin_val=old_nargin;
return ret1a;
end_scope
}
////////////////////////////////////////////////////////////////////////
//Mm dct2()
//----------------------------------------------------------------------
//基本功能:本函数为二维离散余弦变换的无指定列变换长度重载版本。
//----------------------------------------------------------------------
//参数说明:Mm arg1 待变换矩阵
// Mm mrows 行变换长度,若指定该参数,则自动将向量a补0或自动
// 裁剪到指定长度。
//----------------------------------------------------------------------
//返 回:Mm
// 变换结果矩阵。
//----------------------------------------------------------------------
//注 意:此函数声明为保护型,只能在CFreqPro类中使用
//----------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////
Mm CFreqPro::dct2(Mm arg1, Mm mrows)
{
begin_scope
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -