MATLAB函数的filter2 conv2 imfilter2函数 与opencv中的cvFilter2D函数的异同及图像的频率滤波
2014-07-10 19:05
579 查看
最近在做科研的过程中用到图像的滤波,由于图像数据量比较大,就考虑空域转化频域相乘来提高效率,测试的的时候出现MATLAB 与OPENCV的结果不相同,以前也知道MATLAB和OPENCV的滤波机理不相同,但是具体的过程也是不是太清楚,于是用程序测试filter2,conv2,imfilter2,cvFilter2D函数的异同。
conv2用来计算源图像A和滤波模板H的卷积,计算过程为将滤波模板旋转180度后,进行掩膜计算,计算的过程中要对边界补0计算。
输出为
conv2的计算可以使用频域的乘积计算,但是要对矩阵的边界补零
输出为
filter2计算过程为对滤波模板H进行180度旋转后,再调用conv2函数。由于conv2函数又对模板旋转180度,等于直接对滤波模板H直接进行掩膜计算。
输出结果:
可以看出filter2函数已经不满足卷积的可交换律了
imfilter则是对函数filter2和conv2函数的综合,当选择参数conv时则,进行卷积计算与函数conv2函数相同, 选择corr参数时,进行相关运算和filter2过程相同
opencv中的滤波函数 cvFilter2D( const CvArr* src, CvArr* dst, const CvMat* kernel, CvPoint anchor CV_DEFAULT(cvPoint(-1,-1)))可以实现图像的卷及滤波,但是cvFilter2D处理时不对滤波核进行180度旋转,边界处理时实行镜像处理
上面代码:函数speedy_convolution代码参考/article/7805566.html
测试结果:
cvFilter2D 处理过程对Mb1的边界镜像补数为:
再以Ma1:
的cvPoint(1,1)为滤波核为中心进行掩膜计算
一般图像滤波的模板都是关于中心对称的,因此在计算图像卷积滤波时,是否对卷积模板旋转180度关系不是太大。
由于矩阵比较小,fft的效果不是太明显,如果是图像的维数比较大的话,效率的提高就比较可观了
以上只是本人的个人感悟,不当之处希望和大家一起进步。
conv2用来计算源图像A和滤波模板H的卷积,计算过程为将滤波模板旋转180度后,进行掩膜计算,计算的过程中要对边界补0计算。
a=[1 2;3 4]; b=[-1 1;-2 2]; c=conv2(a,b,'full')
输出为
conv2的计算可以使用频域的乘积计算,但是要对矩阵的边界补零
a1=[1 2 0;3 4 0;0 0 0]; b1=[-1 1 0;-2 2 0;0 0 0]; a1f=fft2(a1); b1f=fft2(b1); abf1=a1f.*b1f; c1=ifft2(abf1)
输出为
filter2计算过程为对滤波模板H进行180度旋转后,再调用conv2函数。由于conv2函数又对模板旋转180度,等于直接对滤波模板H直接进行掩膜计算。
a=[1 2;3 4]; b=[-1 1;-2 2]; c2=filter2(a,b,'full') c3=filter2(b,a,'full')
输出结果:
可以看出filter2函数已经不满足卷积的可交换律了
imfilter则是对函数filter2和conv2函数的综合,当选择参数conv时则,进行卷积计算与函数conv2函数相同, 选择corr参数时,进行相关运算和filter2过程相同
opencv中的滤波函数 cvFilter2D( const CvArr* src, CvArr* dst, const CvMat* kernel, CvPoint anchor CV_DEFAULT(cvPoint(-1,-1)))可以实现图像的卷及滤波,但是cvFilter2D处理时不对滤波核进行180度旋转,边界处理时实行镜像处理
#include "iostream" #include "cv.h" #include "highgui.h" using namespace std; void speedy_convolution(const CvMat *A,const CvMat *B,CvMat *C); void ShowMat(CvMat *m); int main() { float A1[]={1,2,3,4};float B1[]={-1,1,-2,2}; //float A[]={1,2,0,3,4,0,0,0,0}; //float B[]={-1,1,0,-2,2,0,0,0,0}; CvMat Ma1=cvMat(2,2,CV_32FC1,&A1); CvMat Mb1=cvMat(2,2,CV_32FC1,&B1); CvMat *C1=cvCreateMat(3,3,CV_32FC1); CvMat *C=cvCreateMat(2,2,CV_32FC1); double t=cvGetTickCount(); speedy_convolution(&Ma1,&Mb1,C1);// t=cvGetTickCount()-t; cout<<"fft时间:"<<t/((double)cvGetTickFrequency()*1000.)<<endl; cout<<"FFT卷积计算结果:"<<endl; ShowMat(C1); t=cvGetTickCount(); cvFilter2D(&Mb1,C,&Ma1,cvPoint(1,1)); t=cvGetTickCount()-t; cout<<endl<<"cvFilter2D时间:"<<t/((double)cvGetTickFrequency()*1000.)<<endl; cout<<"cvFilter2D函数测试结果:"<<endl; ShowMat(C); cout<<endl; } void ShowMat(CvMat *m) { int i,j; for (i=0;i<m->rows;i++) { for (j=0;j<m->cols;j++) { cout<<cvGet2D(m,i,j).val[0]<<" "; } cout<<endl; } } void speedy_convolution( const CvMat *A,//size:M1 * N1 const CvMat *B, //size : M2 * N2 CvMat *C //size:(M1+M2-1) * (N1+N2-1) ) { int dft_M = cvGetOptimalDFTSize(A->rows + B->rows -1); int dft_N = cvGetOptimalDFTSize(A->cols + B->cols -1); CvMat *dft_A = cvCreateMat(dft_M , dft_N , A->type); CvMat *dft_B = cvCreateMat(dft_M, dft_N, B->type); CvMat tmp; //copy A TO dft_A and pad dft_A with zeros cvGetSubRect(dft_A,&tmp , cvRect(0,0,A->cols,A->rows)); cvCopy(A,&tmp); cvGetSubRect(dft_A,&tmp,cvRect(A->cols,0,dft_A->cols - A->cols , A->rows)); cvZero(&tmp); //no need to pad bottom part of dft_A with zeros because of //use nonzero_rows parameter in cvDFT() call below cvDFT(dft_A,dft_A,CV_DXT_FORWARD,A->rows); //repeat the same with the second array cvGetSubRect(dft_B,&tmp,cvRect(0,0,B->cols,B->rows)); cvCopy(B,&tmp); cvGetSubRect(dft_B,&tmp,cvRect(B->cols,0,dft_B->cols - B->cols , B->rows)); cvZero(&tmp); //no need to pad bottom part of dft_B with zeros because of //use nonzero-rows parameter in cvDFT() call below cvDFT(dft_B,dft_B,CV_DXT_FORWARD,B->rows); //or CV_DXT_MUL_CONJ to get correlation rather than convolution cvMulSpectrums(dft_A,dft_B,dft_A,0); //calculate only the top part cvDFT(dft_A,dft_A,CV_DXT_INV_SCALE,C->rows); cvGetSubRect(dft_A,&tmp,cvRect(0,0,C->cols,C->rows)); cvCopy(&tmp,C); cvReleaseMat(&dft_A); cvReleaseMat(&dft_B); }
上面代码:函数speedy_convolution代码参考/article/7805566.html
测试结果:
cvFilter2D 处理过程对Mb1的边界镜像补数为:
再以Ma1:
的cvPoint(1,1)为滤波核为中心进行掩膜计算
一般图像滤波的模板都是关于中心对称的,因此在计算图像卷积滤波时,是否对卷积模板旋转180度关系不是太大。
由于矩阵比较小,fft的效果不是太明显,如果是图像的维数比较大的话,效率的提高就比较可观了
以上只是本人的个人感悟,不当之处希望和大家一起进步。
相关文章推荐
- opencv中cvFilter2D( ) 函数filter2D()函数与MATLAB中imfilter()函数的差异
- opencv中有和matlab中conv2一样功能的函数吗?
- C语言实现Matlab自带的滤波filter()函数
- MatLab 自编的 均值滤波、中值滤波、高斯滤波 图像处理函数
- 转载:发个MatLab 自编的 均值滤波、中值滤波、高斯滤波 图像处理函数
- 使用OpenCV中的filter2D函数精确实现matlab中的imfilter函数(已测)
- 发个MatLab 自编的 均值滤波、中值滤波、高斯滤波 图像处理函数
- MatLab 自编的 均值滤波、中值滤波、高斯滤波 图像处理函数(转)
- MatLab自编的均值滤波、中值滤波、高斯滤波三种滤波算子,可以直接调用 图像处理函数
- opencv3_java 图像的方框滤波BoxFilter BoxFilter
- 用OpenCV的函数bilateralFilter做双边滤波~
- 发个MatLab 自编的 均值滤波、中值滤波、高斯滤波 图像处理函数
- opencv学习(七)之图像卷积运算函数filter2D()
- opencv学习(7)图像的各种滤波函数的介绍
- MatLab 自编的 均值滤波、中值滤波、高斯滤波 图像处理函数(转)
- 发个MatLab 自编的 均值滤波、中值滤波、高斯滤波 图像处理函数
- opencv 旋转图像函数实现 等同于matlab里的rotate() (注:旋转后图像变大,超出部分填为黑色)
- OpenCV中与matlab中相对应的函数
- OpenCV学习笔记(12)OpenCV调用Matlab函数进行保存视频的尝试
- 转载:MATLAB图像处理函数汇总 (二)