社区
C++ Builder
帖子详情
有数子滤波器经验的的进来一下:
MEFULEU
2004-07-22 05:19:45
谁能够提供一下滤波器的源码?说说其中的奥妙?
某使用fft的方法;进行滤波;但是逆回来的数据怎么都不是以为要的结果??
...全文
232
14
打赏
收藏
有数子滤波器经验的的进来一下:
谁能够提供一下滤波器的源码?说说其中的奥妙? 某使用fft的方法;进行滤波;但是逆回来的数据怎么都不是以为要的结果??
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
14 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
MEFULEU
2004-08-03
打赏
举报
回复
有没有时域滤波?????
MEFULEU
2004-07-29
打赏
举报
回复
有没有时域滤波?????
aiirii
2004-07-28
打赏
举报
回复
学习
constantine
2004-07-28
打赏
举报
回复
mark,study....
smartduck
2004-07-28
打赏
举报
回复
这个算法速度上是不怎么理想。情况如下:
800X600的bmp图片(相当480000的数据)通过低通要24秒
(我的机器配置:p4 2.0g 256M)
smartduck
2004-07-28
打赏
举报
回复
>>你这种频域滤波:假设我要滤掉1000hz的数据;怎么处理调用???
你是指低通还是高通还是带通?
举个低通的例子,其它的类似
/*************************************************************************
*
* \函数名称:
* LowPassFilterEnhance()
*
* \输入参数:
* LPBYTE lpImage - 指向需要增强得图象数据
* int nWidth - 数据宽度
* int nHeight - 数据高度
* int nRadius - 低通滤波的滤波半径
*
* \返回值:
* 无
*
* \说明:
* lpImage 是指向需要增强的数据指针。注意,这个指针指向的数据区不能是CDib指向的数据区
* 因为CDib指向的数据区的每一行是DWORD对齐的。
* 经过低通滤波的数据存储在lpImage当中。
*
*************************************************************************
*/
void LowPassFilterEnhance(CRGBDib* lpImage, int nWidth, int nHeight, int nRadius)
{
// 循环控制变量
int y ;
int x ;
double dTmpOne ;
double dTmpTwo ;
// 傅立叶变换的宽度和高度(2的整数次幂)
int nTransWidth ;
int nTransHeight;
// 图象象素值
RGBQUAD unchValue;
// 指向时域数据的指针
complex<double> * pCTData ;
// 指向频域数据的指针
complex<double> * pCFData ;
// 计算进行傅立叶变换的点数 (2的整数次幂)
dTmpOne = log(nWidth)/log(2);
dTmpTwo = ceil(dTmpOne) ;
dTmpTwo = pow(2,dTmpTwo) ;
nTransWidth = (int) dTmpTwo ;
// 计算进行傅立叶变换的点数 (2的整数次幂)
dTmpOne = log(nHeight)/log(2);
dTmpTwo = ceil(dTmpOne) ;
dTmpTwo = pow(2,dTmpTwo) ;
nTransHeight = (int) dTmpTwo ;
// 傅立叶变换的实部和虚部
double dReal;
double dImag;
// 低通滤波的半径不能超过频域的最大半径
if(nRadius>nTransWidth-1 || nRadius>nTransHeight-1)
{
return ;
}
// 分配内存
pCTData=new complex<double>[nTransWidth * nTransHeight];
pCFData=new complex<double>[nTransWidth * nTransHeight];
// 初始化
// 图像数据的宽和高不一定是2的整数次幂,所以pCTData
// 有一部分数据需要补0
for(y=0; y<nTransHeight; y++)
{
for(x=0; x<nTransWidth; x++)
{
pCTData[y*nTransWidth + x]=complex<double>(0,0);
}
}
// 把图像数据传给pCTData
for(y=0; y<nHeight; y++)
{
for(x=0; x<nWidth; x++)
{
unchValue = lpImage->GetPixel(x,y);//lpImage[y*nWidth +x];
pCTData[y*nTransWidth + x]=complex<double>(unchValue.rgbBlue,0);
}
}
// 傅立叶正变换
DIBFFT_2D(pCTData, nWidth, nHeight, pCFData) ;
// 下面开始实施低通滤波,把所有大于nRadius的高频分量设置为0
// 注意这里高频分量采用的范数不是欧式距离,而是无穷大范数
// || (u,v)-(0,0) || = max(|u|,|v|)
for(y=nRadius; y<nTransHeight; y++)
{
for(x=nRadius; x<nTransWidth; x++)
{
pCFData[y*nTransWidth + x]=complex<double>(0,0);
}
}
// 经过低通滤波的图象进行反变换
IFFT_2D(pCFData, pCTData, nWidth, nHeight);
// 反变换的数据传给lpImage
for(y=0; y<nHeight; y++)
{
for(x=0; x<nWidth; x++)
{
dReal = pCTData[y*nTransWidth + x].real() ;
dImag = pCTData[y*nTransWidth + x].imag() ;
unchValue.rgbBlue = (unsigned char)max(0,min(255,sqrt(dReal*dReal+dImag*dImag) ));
unchValue.rgbRed = unchValue.rgbGreen = unchValue.rgbBlue;
lpImage->SetPixel(x,y,unchValue);//lpImage[y*nWidth + x] = unchValue ;
}
}
// 释放内存
delete pCTData;
delete pCFData;
pCTData = NULL;
pCFData = NULL;
}
flowercity
2004-07-27
打赏
举报
回复
学习中~~!
MEFULEU
2004-07-27
打赏
举报
回复
to :
smartduck(聪明鸭子)
你这种频域滤波:假设我要滤掉1000hz的数据;怎么处理调用???
MEFULEU
2004-07-27
打赏
举报
回复
有没有时域的滤波???
频域的滤波我数据量也是很大,好几百万的数据;我担心fft速度跟不上;
smartduck
2004-07-27
打赏
举报
回复
/*************************************************************************
*
* \函数名称:
* IFFT_2D()
*
* \输入参数:
* complex<double> * pCFData - 频域数据
* complex<double> * pCTData - 时域数据
* int nWidth - 图像数据宽度
* int nHeight - 图像数据高度
*
* \返回值:
* 无
*
* \说明:
* 二维傅立叶反变换。
*
************************************************************************
*/
VOID WINAPI IFFT_2D(complex<double> * pCFData, complex<double> * pCTData, int nWidth, int nHeight)
{
// 循环控制变量
int x;
int y;
// 临时变量
double dTmpOne;
double dTmpTwo;
// 进行傅立叶变换的宽度和高度,(2的整数次幂)
// 图像的宽度和高度不一定为2的整数次幂
int nTransWidth;
int nTransHeight;
// 计算进行傅立叶变换的宽度 (2的整数次幂)
dTmpOne = log(nWidth)/log(2);
dTmpTwo = ceil(dTmpOne) ;
dTmpTwo = pow(2,dTmpTwo) ;
nTransWidth = (int) dTmpTwo ;
// 计算进行傅立叶变换的高度 (2的整数次幂)
dTmpOne = log(nHeight)/log(2);
dTmpTwo = ceil(dTmpOne) ;
dTmpTwo = pow(2,dTmpTwo) ;
nTransHeight = (int) dTmpTwo ;
// 分配工作需要的内存空间
complex<double> *pCWork= new complex<double>[nTransWidth * nTransHeight];
//临时变量
complex<double> *pCTmp ;
// 为了利用傅立叶正变换,可以把傅立叶频域的数据取共轭
// 然后直接利用正变换,输出结果就是傅立叶反变换结果的共轭
for(y = 0; y < nTransHeight; y++)
{
for(x = 0; x < nTransWidth; x++)
{
pCTmp = &pCFData[nTransWidth * y + x] ;
pCWork[nTransWidth * y + x] = complex<double>( pCTmp->real() , -pCTmp->imag() );
}
}
// 调用傅立叶正变换
::DIBFFT_2D(pCWork, nWidth, nHeight, pCTData) ;
// 求时域点的共轭,求得最终结果
// 根据傅立叶变换原理,利用这样的方法求得的结果和实际的时域数据
// 相差一个系数
for(y = 0; y < nTransHeight; y++)
{
for(x = 0; x < nTransWidth; x++)
{
pCTmp = &pCTData[nTransWidth * y + x] ;
pCTData[nTransWidth * y + x] =
complex<double>( pCTmp->real()/(nTransWidth*nTransHeight),
-pCTmp->imag()/(nTransWidth*nTransHeight) );
}
}
delete pCWork ;
pCWork = NULL ;
}
smartduck
2004-07-27
打赏
举报
回复
/*************************************************************************
*
* \函数名称:
* FFT_2D()
*
* \输入参数:
* complex<double> * pCTData - 图像数据
* int nWidth - 数据宽度
* int nHeight - 数据高度
* complex<double> * pCFData - 傅立叶变换后的结果
*
* \返回值:
* 无
*
* \说明:
* 二维傅立叶变换。
*
************************************************************************
*/
VOID WINAPI DIBFFT_2D(complex<double> * pCTData, int nWidth, int nHeight, complex<double> * pCFData)
{
// 循环控制变量
int x;
int y;
// 临时变量
double dTmpOne;
double dTmpTwo;
// 进行傅立叶变换的宽度和高度,(2的整数次幂)
// 图像的宽度和高度不一定为2的整数次幂
int nTransWidth;
int nTransHeight;
// 计算进行傅立叶变换的宽度 (2的整数次幂)
dTmpOne = log(nWidth)/log(2);
dTmpTwo = ceil(dTmpOne) ;
dTmpTwo = pow(2,dTmpTwo) ;
nTransWidth = (int) dTmpTwo ;
// 计算进行傅立叶变换的高度 (2的整数次幂)
dTmpOne = log(nHeight)/log(2);
dTmpTwo = ceil(dTmpOne) ;
dTmpTwo = pow(2,dTmpTwo) ;
nTransHeight = (int) dTmpTwo ;
// x,y(行列)方向上的迭代次数
int nXLev;
int nYLev;
// 计算x,y(行列)方向上的迭代次数
nXLev = (int) ( log(nTransWidth)/log(2) + 0.5 );
nYLev = (int) ( log(nTransHeight)/log(2) + 0.5 );
for(y = 0; y < nTransHeight; y++)
{
// x方向进行快速傅立叶变换
FFT_1D(&pCTData[nTransWidth * y], &pCFData[nTransWidth * y], nXLev);
}
// pCFData中目前存储了pCTData经过行变换的结果
// 为了直接利用FFT_1D,需要把pCFData的二维数据转置,再一次利用FFT_1D进行
// 傅立叶行变换(实际上相当于对列进行傅立叶变换)
for(y = 0; y < nTransHeight; y++)
{
for(x = 0; x < nTransWidth; x++)
{
pCTData[nTransHeight * x + y] = pCFData[nTransWidth * y + x];
}
}
for(x = 0; x < nTransWidth; x++)
{
// 对x方向进行快速傅立叶变换,实际上相当于对原来的图象数据进行列方向的
// 傅立叶变换
FFT_1D(&pCTData[x * nTransHeight], &pCFData[x * nTransHeight], nYLev);
}
// pCFData中目前存储了pCTData经过二维傅立叶变换的结果,但是为了方便列方向
// 的傅立叶变换,对其进行了转置,现在把结果转置回来
for(y = 0; y < nTransHeight; y++)
{
for(x = 0; x < nTransWidth; x++)
{
pCTData[nTransWidth * y + x] = pCFData[nTransHeight * x + y];
}
}
memcpy(pCTData, pCFData, sizeof(complex<double>) * nTransHeight * nTransWidth );
}
smartduck
2004-07-27
打赏
举报
回复
/*************************************************************************
*
* \函数名称:
* FFT_1D()
*
* \输入参数:
* complex<double> * pCTData - 指向时域数据的指针,输入的需要变换的数据
* complex<double> * pCFData - 指向频域数据的指针,输出的经过变换的数据
* nLevel -傅立叶变换蝶形算法的级数,2的幂数,
*
* \返回值:
* 无
*
* \说明:
* 一维快速傅立叶变换。
*
*************************************************************************
*/
VOID WINAPI FFT_1D(complex<double> * pCTData, complex<double> * pCFData, int nLevel)
{
// 循环控制变量
int i;
int j;
int k;
double PI = 3.1415926;
// 傅立叶变换点数
int nCount =0 ;
// 计算傅立叶变换点数
nCount =(int)pow(2,nLevel) ;
// 某一级的长度
int nBtFlyLen;
nBtFlyLen = 0 ;
// 变换系数的角度 =2 * PI * i / nCount
double dAngle;
complex<double> *pCW ;
// 分配内存,存储傅立叶变化需要的系数表
pCW = new complex<double>[nCount / 2];
// 计算傅立叶变换的系数
for(i = 0; i < nCount / 2; i++)
{
dAngle = -2 * PI * i / nCount;
pCW[i] = complex<double> ( cos(dAngle), sin(dAngle) );
}
// 变换需要的工作空间
complex<double> *pCWork1,*pCWork2;
// 分配工作空间
pCWork1 = new complex<double>[nCount];
pCWork2 = new complex<double>[nCount];
// 临时变量
complex<double> *pCTmp;
// 初始化,写入数据
memcpy(pCWork1, pCTData, sizeof(complex<double>) * nCount);
// 临时变量
int nInter;
nInter = 0;
// 蝶形算法进行快速傅立叶变换
for(k = 0; k < nLevel; k++)
{
for(j = 0; j < (int)pow(2,k); j++)
{
//计算长度
nBtFlyLen = (int)pow( 2,(nLevel-k) );
//倒序重排,加权计算
for(i = 0; i < nBtFlyLen/2; i++)
{
nInter = j * nBtFlyLen;
pCWork2[i + nInter] =
pCWork1[i + nInter] + pCWork1[i + nInter + nBtFlyLen / 2];
pCWork2[i + nInter + nBtFlyLen / 2] =
(pCWork1[i + nInter] - pCWork1[i + nInter + nBtFlyLen / 2])
* pCW[(int)(i * pow(2,k))];
}
}
// 交换 pCWork1和pCWork2的数据
pCTmp = pCWork1 ;
pCWork1 = pCWork2 ;
pCWork2 = pCTmp ;
}
// 重新排序
for(j = 0; j < nCount; j++)
{
nInter = 0;
for(i = 0; i < nLevel; i++)
{
if ( j&(1<<i) )
{
nInter += 1<<(nLevel-i-1);
}
}
pCFData[j]=pCWork1[nInter];
}
// 释放内存空间
delete pCW;
delete pCWork1;
delete pCWork2;
pCW = NULL ;
pCWork1 = NULL ;
pCWork2 = NULL ;
}
MEFULEU
2004-07-26
打赏
举报
回复
??大大呢?
ToIP
2004-07-22
打赏
举报
回复
学学dsp
FFmpeg音视频基础之C++系列第1:C++入门经典第10版
初步认识:做到心中
有数
51.2 图解:章节关系 61.3 探讨:教学方法论 71.4 探讨:学习方法论 71.5 C++的1.0与2.0 81.6 开发工具Qt5.9和VS2015/7/9 8控制台:&...
跟杨老师学习电磁兼容【16-41】
P22:怎样降低时钟信号的辐射 有
经验
的设计师都知道,时钟信号导致辐射发射超标的主要原因。除了前面所介绍的在布线方面要特别关注时钟信号的电路以外,对于时钟信号本身也可以采取措施,使时钟信号本身丧失一些强...
秋招面试问题总结-视觉算法
1.YOLOv3对YOLOv2的改进: 1.loss不同:作者v3替换了v3=2的softmax loss变成logistic loss,由于每个点所对应的...3.detection的策略不同:v2只有一个detection,v3
一下
子
变成了3个,分别是一个下采样的,feature ma
BAT机器学习面试1000题系列(第1~305题)
下面解释
一下
特殊情况的 M > H: 实际上,除了输入数据的通道数比较少之外,中间层的feature map数很多,这样中间层算卷积会累死计算机(鱼塘太深,每层鱼都打,需要的鱼网太重了)。所以很多深度卷积网络把全部...
BAT机器学习面试1000题系列
下面解释
一下
特殊情况的 M > H: 实际上,除了输入数据的通道数比较少之外,中间层的feature map数很多,这样中间层算卷积会累死计算机(鱼塘太深,每层鱼都打,需要的鱼网太重了)。所以很多深度卷积网络把全部...
C++ Builder
13,826
社区成员
102,678
社区内容
发帖
与我相关
我的任务
C++ Builder
C++ Builder相关内容讨论区
复制链接
扫一扫
分享
社区描述
C++ Builder相关内容讨论区
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章