📄 freqfilter.cpp
字号:
LONG i;
LONG j;
// 进行付立叶变换的宽度和高度(2的整数次方)
LONG w;
LONG h;
int wp;
int hp;
// 指向DIB的指针
LPBYTE lpDIB;
// 指向DIB象素指针
LPBYTE lpDIBBits;
// 锁定DIB
lpDIB = (LPBYTE) ::GlobalLock((HGLOBAL) hDIB);
// 找到DIB图像象素起始位置
lpDIBBits = m_clsDIB.FindDIBBits(lpDIB);
// 判断是否是24-bpp位图
if (m_clsDIB.DIBBitCount(lpDIB) != 24)
{
// 提示用户
MessageBox("请先将其转换为24位色位图,再进行处理!", "系统提示" , MB_ICONINFORMATION | MB_OK);
// 解除锁定
::GlobalUnlock((HGLOBAL) hDIB);
// 返回
return;
}
// 更改光标形状
BeginWaitCursor();
// DIB的宽度
LONG lWidth = m_clsDIB.DIBWidth(lpDIB);
// DIB的高度
LONG lHeight = m_clsDIB.DIBHeight(lpDIB);
// 计算图像每行的字节数
LONG lLineBytes = WIDTHBYTES(lWidth * 24);
// 赋初值
w = 1;
h = 1;
wp = 0;
hp = 0;
// 计算进行付立叶变换的宽度和高度(2的整数次方)
while(w < lWidth)
{
w *= 2;
wp++;
}
while(h < lHeight)
{
h *= 2;
hp++;
}
CFreqCalculate clsFreqCalculate;
// 保存频域数据
complex<double> *FD, *TD;
FD = new complex<double>[w * h * 3];
TD = new complex<double>[w * h * 3];
// 行
for(i = 0; i < h; i++)
{
// 列
for(j = 0; j < 3 * w; j++)
{
if(i < lHeight && j < lLineBytes)
{
// 获取时域数值
unsigned char Value = *((unsigned char *)lpDIBBits + lLineBytes * i + j);
// 时域赋值
TD[w * i * 3 + j] = complex<double>(Value, 0.0f);
}
else
{
// 否则补零
TD[w * i * 3 + j] = complex<double>(0.0f, 0.0f);
}
}
}
// 进行频谱分析 时域->频域
if (clsFreqCalculate.Fourier(TD, lWidth, lHeight, FD) == FALSE)
return;
// 释放内存
delete[] TD;
// 当前频率
float fDN;
// 对图象进行低通滤波
for(i = 0; i < h; i++)
{
for(j = 0; j < w * 3; j++)
{
// 计算距离
int k = (int)(j / 3);
fDN = (float)sqrt( i * i + k * k);
float fH = 1 / (1 + 0.414 * (fDN / fD) * (fDN / fD));
// 逆滤波恢复
if(fH > 0.25f)
FD[i * 3 * w + j] /= complex<double>(fH, 0.0f);
else
FD[i * 3 * w + j] *= complex<double>(0.2f, 0.0f);
}
}
// 进行频谱分析 频域->时域
if (clsFreqCalculate.IFourier(lpDIBBits, lWidth, lHeight, FD) == FALSE)
return;
// 解除锁定
::GlobalUnlock((HGLOBAL) hDIB);
// 释放内存
delete[] FD;
// 恢复光标
EndWaitCursor();
}
/*************************************************************************
*
* 函数名称:
* WienerFilter()
*
* 参数:
* HDIB hDIB - 待处理的DIB
* float fD - 低通滤波阀值
*
* 返回值:
* void - 无返回值
*
* 说明:
* 该函数对图象进行有约束恢复的维纳滤波处理
*
************************************************************************/
void CFreqFilter::WienerFilter(HDIB hDIB, float fD)
{
// 临时变量
LONG i;
LONG j;
// 进行付立叶变换的宽度和高度(2的整数次方)
LONG w;
LONG h;
int wp;
int hp;
// 指向DIB的指针
LPBYTE lpDIB;
// 指向DIB象素指针
LPBYTE lpDIBBits;
// 锁定DIB
lpDIB = (LPBYTE) ::GlobalLock((HGLOBAL) hDIB);
// 找到DIB图像象素起始位置
lpDIBBits = m_clsDIB.FindDIBBits(lpDIB);
// 判断是否是24-bpp位图
if (m_clsDIB.DIBBitCount(lpDIB) != 24)
{
// 提示用户
MessageBox("请先将其转换为24位色位图,再进行处理!", "系统提示" , MB_ICONINFORMATION | MB_OK);
// 解除锁定
::GlobalUnlock((HGLOBAL) hDIB);
// 返回
return;
}
// 更改光标形状
BeginWaitCursor();
// DIB的宽度
LONG lWidth = m_clsDIB.DIBWidth(lpDIB);
// DIB的高度
LONG lHeight = m_clsDIB.DIBHeight(lpDIB);
// 计算图像每行的字节数
LONG lLineBytes = WIDTHBYTES(lWidth * 24);
// 赋初值
w = 1;
h = 1;
wp = 0;
hp = 0;
// 计算进行付立叶变换的宽度和高度(2的整数次方)
while(w < lWidth)
{
w *= 2;
wp++;
}
while(h < lHeight)
{
h *= 2;
hp++;
}
CFreqCalculate clsFreqCalculate;
// 保存频域数据
complex<double> *FD, *TD;
FD = new complex<double>[w * h * 3];
TD = new complex<double>[w * h * 3];
// 行
for(i = 0; i < h; i++)
{
// 列
for(j = 0; j < 3 * w; j++)
{
if(i < lHeight && j < lLineBytes)
{
// 获取时域数值
unsigned char Value = *((unsigned char *)lpDIBBits + lLineBytes * i + j);
// 时域赋值
TD[w * i * 3 + j] = complex<double>(Value, 0.0f);
}
else
{
// 否则补零
TD[w * i * 3 + j] = complex<double>(0.0f, 0.0f);
}
}
}
// 进行频谱分析 时域->频域
if (clsFreqCalculate.Fourier(TD, lWidth, lHeight, FD) == FALSE)
return;
// 释放内存
delete[] TD;
// 当前频率
float fDN;
// 预先设定的经验常数
float K = 0.05f;
// 对图象进行低通滤波
for(i = 0; i < h; i++)
{
for(j = 0; j < w * 3; j++)
{
// 计算距离
int k = (int)(j / 3);
fDN = (float)sqrt( i * i + k * k);
float fH = 1 / (1 + 0.414 * (fDN / fD) * (fDN / fD));
// 维纳滤波恢复
FD[i * 3 * w + j] *= complex<double>(fH / (fH * fH + K), 0.0f);
}
}
// 进行频谱分析 频域->时域
if (clsFreqCalculate.IFourier(lpDIBBits, lWidth, lHeight, FD) == FALSE)
return;
// 解除锁定
::GlobalUnlock((HGLOBAL) hDIB);
// 释放内存
delete[] FD;
// 恢复光标
EndWaitCursor();
}
/*************************************************************************
*
* 函数名称:
* PSE_Filter()
*
* 参数:
* HDIB hDIB - 待处理的DIB
* float fD - 低通滤波阀值
*
* 返回值:
* void - 无返回值
*
* 说明:
* 该函数对图象进行功率谱均衡滤波
*
************************************************************************/
void CFreqFilter::PSE_Filter(HDIB hDIB, float fD)
{
// 临时变量
LONG i;
LONG j;
// 进行付立叶变换的宽度和高度(2的整数次方)
LONG w;
LONG h;
int wp;
int hp;
// 指向DIB的指针
LPBYTE lpDIB;
// 指向DIB象素指针
LPBYTE lpDIBBits;
// 锁定DIB
lpDIB = (LPBYTE) ::GlobalLock((HGLOBAL) hDIB);
// 找到DIB图像象素起始位置
lpDIBBits = m_clsDIB.FindDIBBits(lpDIB);
// 判断是否是24-bpp位图
if (m_clsDIB.DIBBitCount(lpDIB) != 24)
{
// 提示用户
MessageBox("请先将其转换为24位色位图,再进行处理!", "系统提示" , MB_ICONINFORMATION | MB_OK);
// 解除锁定
::GlobalUnlock((HGLOBAL) hDIB);
// 返回
return;
}
// 更改光标形状
BeginWaitCursor();
// DIB的宽度
LONG lWidth = m_clsDIB.DIBWidth(lpDIB);
// DIB的高度
LONG lHeight = m_clsDIB.DIBHeight(lpDIB);
// 计算图像每行的字节数
LONG lLineBytes = WIDTHBYTES(lWidth * 24);
// 赋初值
w = 1;
h = 1;
wp = 0;
hp = 0;
// 计算进行付立叶变换的宽度和高度(2的整数次方)
while(w < lWidth)
{
w *= 2;
wp++;
}
while(h < lHeight)
{
h *= 2;
hp++;
}
CFreqCalculate clsFreqCalculate;
// 保存频域数据
complex<double> *FD, *TD;
FD = new complex<double>[w * h * 3];
TD = new complex<double>[w * h * 3];
// 行
for(i = 0; i < h; i++)
{
// 列
for(j = 0; j < 3 * w; j++)
{
if(i < lHeight && j < lLineBytes)
{
// 获取时域数值
unsigned char Value = *((unsigned char *)lpDIBBits + lLineBytes * i + j);
// 时域赋值
TD[w * i * 3 + j] = complex<double>(Value, 0.0f);
}
else
{
// 否则补零
TD[w * i * 3 + j] = complex<double>(0.0f, 0.0f);
}
}
}
// 进行频谱分析 时域->频域
if (clsFreqCalculate.Fourier(TD, lWidth, lHeight, FD) == FALSE)
return;
// 释放内存
delete[] TD;
// 当前频率
float fDN;
// 预先设定的经验常数
float K=0.05f;
// 对图象进行低通滤波
for(i = 0; i < h; i++)
{
for(j = 0; j < w * 3; j++)
{
// 计算距离
int k = (int)(j / 3);
fDN = (float)sqrt( i * i + k * k);
float fH = 1 / (1 + 0.414 * (fDN / fD) * (fDN / fD));
// 功率谱均衡滤波
FD[i * 3 * w + j] *= complex<double>(1 / sqrt(fH * fH + K), 0.0f);
}
}
// 进行频谱分析 频域->时域
if (clsFreqCalculate.IFourier(lpDIBBits, lWidth, lHeight, FD) == FALSE)
return;
// 解除锁定
::GlobalUnlock((HGLOBAL) hDIB);
// 释放内存
delete[] FD;
// 恢复光标
EndWaitCursor();
}
/*************************************************************************
*
* 函数名称:
* MinPower()
*
* 参数:
* HDIB hDIB - 待处理的DIB
* float fD - 低通滤波阀值
*
* 返回值:
* void - 无返回值
*
* 说明:
* 该函数对图象进行有约束最小平方滤波滤波
*
************************************************************************/
void CFreqFilter::MinPower(HDIB hDIB, float fD)
{
#define PI 3.1415
// 临时变量
LONG i;
LONG j;
// 进行付立叶变换的宽度和高度(2的整数次方)
LONG w;
LONG h;
int wp;
int hp;
// 指向DIB的指针
LPBYTE lpDIB;
// 指向DIB象素指针
LPBYTE lpDIBBits;
// 锁定DIB
lpDIB = (LPBYTE) ::GlobalLock((HGLOBAL) hDIB);
// 找到DIB图像象素起始位置
lpDIBBits = m_clsDIB.FindDIBBits(lpDIB);
// 判断是否是24-bpp位图
if (m_clsDIB.DIBBitCount(lpDIB) != 24)
{
// 提示用户
MessageBox("请先将其转换为24位色位图,再进行处理!", "系统提示" , MB_ICONINFORMATION | MB_OK);
// 解除锁定
::GlobalUnlock((HGLOBAL) hDIB);
// 返回
return;
}
// 更改光标形状
BeginWaitCursor();
// DIB的宽度
LONG lWidth = m_clsDIB.DIBWidth(lpDIB);
// DIB的高度
LONG lHeight = m_clsDIB.DIBHeight(lpDIB);
// 计算图像每行的字节数
LONG lLineBytes = WIDTHBYTES(lWidth * 24);
// 赋初值
w = 1;
h = 1;
wp = 0;
hp = 0;
// 计算进行付立叶变换的宽度和高度(2的整数次方)
while(w < lWidth)
{
w *= 2;
wp++;
}
while(h < lHeight)
{
h *= 2;
hp++;
}
CFreqCalculate clsFreqCalculate;
// 保存频域数据
complex<double> *FD, *TD;
FD = new complex<double>[w * h * 3];
TD = new complex<double>[w * h * 3];
// 行
for(i = 0; i < h; i++)
{
// 列
for(j = 0; j < 3 * w; j++)
{
if(i < lHeight && j < lLineBytes)
{
// 获取时域数值
unsigned char Value = *((unsigned char *)lpDIBBits + lLineBytes * i + j);
// 时域赋值
TD[w * i * 3 + j] = complex<double>(Value, 0.0f);
}
else
{
// 否则补零
TD[w * i * 3 + j] = complex<double>(0.0f, 0.0f);
}
}
}
// 进行频谱分析 时域->频域
if (clsFreqCalculate.Fourier(TD, lWidth, lHeight, FD) == FALSE)
return;
// 释放内存
delete[] TD;
// 当前频率
float fDN;
// 预先设定的经验常数
float S = 0.00003f;
// 对图象进行低通滤波
for(i = 0; i < h; i++)
{
for(j = 0; j < w * 3; j++)
{
// 计算距离
int k = (int)(j / 3);
fDN = (float)sqrt( i * i + k * k);
// 计算用Q实现的高通滤波器的转移函数P(u,v)
float P = 2 * PI * fDN;
// 计算H(u,v)
float fH = 1 / (1 + 0.414 * (fDN / fD) * (fDN / fD));
// 最小平方滤波恢复
FD[i * 3 * w + j] *= complex<double>(fH / (fH * fH + S * P), 0.0f);
}
}
// 进行频谱分析 频域->时域
if (clsFreqCalculate.IFourier(lpDIBBits, lWidth, lHeight, FD) == FALSE)
return;
// 解除锁定
::GlobalUnlock((HGLOBAL) hDIB);
// 释放内存
delete[] FD;
// 恢复光标
EndWaitCursor();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -