C++实现最大值滤波器

来源:互联网 发布:类似知乎的论坛 编辑:程序博客网 时间:2024/06/03 22:53

    今天给大家分享我最近写的几行代码,用C语言实现的1*3、3*1以及3*3最大值滤波....

    首先,什么是最大值滤波?

    做图像研究的人都知道,常用的一个平滑操作是中值滤波,比如3*3中值滤波就是用当前位置的3*3领域内9个像素值的中间大小的值来替代当前位置像素值。  同理,3*3最大值滤波就是用当前位置3*3领域内9个像素值的最大的值来替代当前位置像素值。

    其次,我为什么要写这个代码?

    实不相瞒,鄙人常用openCV,但是我发现CV里面只提供了中值滤波,没有提供最大值滤波(matlab里面倒是有个ordfilt2函数提供了该功能),因为要用,就写了这么个函数。

    以前我写过一些代码放到资源里去给人下载,别人用的时候提了很多意见,我又懒得改了再传,所以这次直接贴到博客,大家给点意见,我觉得合理就直接改了。下面开始贴代码。

<hr/>
// 第一段代码:第一种版本的1*3最大值滤波#include <stdio.h>#ifndef MAX#define MAX(a,b) (a>b?a:b)#endif/* 1*3 maximum filter;B(i,j) is set to local maximum of A(i,j) neighborhood;suppose: A's size is rows*cols, A(i,j) (i<rows,j<cols) is indexed by A[i*witdhstepA+j], i.e. A's element is arranged in memory like: the first row, the second row, ... so on. B is alike. widthstep should be no smaller than cols.(the memory arrangement actually accords with that in openCV)by: Yu Xianguo, NUDT, 2014/6/19*/template<typename T>void  _rowMaxFilter( const T *A, int rows, int cols, T *B, int witdhstepA, int widthstepB ){int i = 0, j = 0;const T *Apt = A;T *Bpt = B;// copy A into Bwhile( i++<rows ){j = 0;while( j++<cols )*(Bpt++) = *(Apt++);Apt += witdhstepA - cols;Bpt += widthstepB - cols;}// apply row-max to each rowApt = A, Bpt = B;for( i=0; i<rows; i++ ){if( Apt[0]>Apt[1] )Bpt[1] = Apt[0];elseBpt[0] = Apt[1];for( j=2; j<cols; j++ )if( Apt[j-1]>Apt[j] )Bpt[j] = Apt[j-1];elseBpt[j-1] = MAX( Apt[j-2], Apt[j] );Apt += witdhstepA;Bpt += widthstepB;}}void  rowMaxFilter( const int *A, int rows, int cols, int *B, int widthstepA, int witdhstepB){_rowMaxFilter(A,rows,cols,B,widthstepA,witdhstepB);}void  rowMaxFilter( const float *A, int rows, int cols, float *B, int widthstepA, int witdhstepB){_rowMaxFilter(A,rows,cols,B,widthstepA,witdhstepB);}void  rowMaxFilter( const double *A, int rows, int cols, double *B, int widthstepA, int witdhstepB){_rowMaxFilter(A,rows,cols,B,widthstepA,witdhstepB);}/* >>>TEST<<<int main(){// use matlab to generate a random array: A = rand(5,6)float A[5*6] = { 1.0347, 0.8884, 1.4384, -0.1022, -0.0301, -0.8637, 0.7269, -1.1471, 0.3252, -0.2414, -0.1649, 0.0774, -0.3034, -1.0689, -0.7549, 0.3192, 0.6277, -1.2141, 0.2939, -0.8095, 1.3703, 0.3129, 1.0933, -1.1135, -0.7873, -2.9443, -1.7115, -0.8649, 1.1093, -0.0068 };float B[30];rowMaxFilter( A, 5, 6, B, 6, 6 );for( int i=0; i<5; i++ ){for( int j=0; j<6; j++ )printf("%g\t",B[i*6+j]);printf("\n");}// true result is://1.0347  1.4384  1.4384  1.4384  -0.0301 -0.0301//0.7269  0.7269  0.3252  0.3252  0.0774  0.0774//-0.3034 -0.3034 0.3192  0.6277  0.6277  0.6277//0.2939  1.3703  1.3703  1.3703  1.0933  1.0933//-0.7873 -0.7873 -0.8649 1.1093  1.1093  1.1093return 0;}*///===================corresponding matlab code========================================/*function  B = colMaxFilter(A)%% 3*1 maximum filter%% B(i,j) is set to local maximum of A(i,j) neighborhoodB = A;[M,N] = size(A);for i=1:N    % apply col-max to each col    if A(1,i)>A(2,i)        B(2,i) = A(1,i);    else        B(1,i) = A(2,i);    end    for j=3:M        if A(j-1,i)>A(j,i)            B(j,i) = A(j-1,i);        else            B(j-1,i) = max(A(j-2,i),A(j,i));        end    endend%% TEST% A = rand(50,60);% B1 = ordfilt2(A,3,[1;1;1]);% B2 = colMaxFilter(A);% C = B1 - B2;% max(abs(C(:))) % should be ZERO*/
<hr/>

// 第二段代码:第二种版本的1*3滤波#include <stdio.h>/* 1*3 maximum filter;if A(i,j) is local maximum, then B(i,j)=A(i,j); else B(i,j)=0suppose: A's size is rows*cols, A(i,j) (i<rows,j<cols) is indexed by A[i*witdhstepA+j], i.e. A's element is arranged in memory like: the first row, the second row, ... so on. B is alike. widthstep should be no smaller than cols.(the memory arrangement actually accords with that in openCV)by: Yu Xianguo, NUDT, 2014/6/19*/template<typename T>void  _rowMaxFilter2( const T *A, int rows, int cols, T *B, int witdhstepA, int widthstepB ){int i = 0, j = 0;const T *Apt = A;T *Bpt = B;// copy A into Bwhile( i++<rows ){j = 0;while( j++<cols )*(Bpt++) = *(Apt++);Apt += witdhstepA - cols;Bpt += widthstepB - cols;}// apply row-max to each rowApt = A, Bpt = B;for( i=0; i<rows; i++ ){for( j=1; j<cols; j++ )if( Apt[j-1]>Apt[j] )Bpt[j] = 0;elseBpt[j-1] = 0;Apt += witdhstepA;Bpt += widthstepB;}}void  rowMaxFilter2( const int *A, int rows, int cols, int *B, int widthstepA, int witdhstepB){_rowMaxFilter2(A,rows,cols,B,widthstepA,witdhstepB);}void  rowMaxFilter2( const float *A, int rows, int cols, float *B, int widthstepA, int witdhstepB){_rowMaxFilter2(A,rows,cols,B,widthstepA,witdhstepB);}void  rowMaxFilter2( const double *A, int rows, int cols, double *B, int widthstepA, int witdhstepB){_rowMaxFilter2(A,rows,cols,B,widthstepA,witdhstepB);}/* >>>TEST<<<int main(){// use matlab to generate a random array: A = rand(5,6)float A[5*6] = { 1.0347, 0.8884, 1.4384, -0.1022, -0.0301, -0.8637, 0.7269, -1.1471, 0.3252, -0.2414, -0.1649, 0.0774, -0.3034, -1.0689, -0.7549, 0.3192, 0.6277, -1.2141, 0.2939, -0.8095, 1.3703, 0.3129, 1.0933, -1.1135, -0.7873, -2.9443, -1.7115, -0.8649, 1.1093, -0.0068 };float B[30];rowMaxFilter2( A, 5, 6, B, 6, 6 );for( int i=0; i<5; i++ ){for( int j=0; j<6; j++ )printf("%g\t",B[i*6+j]);printf("\n");}// true result is://1.0347         0    1.4384         0   -0.0301         0//0.7269         0    0.3252         0         0    0.0774//-0.3034         0         0         0    0.6277         0//0.2939         0    1.3703         0    1.0933         0//-0.7873         0         0         0    1.1093         0return 0;}*///===================corresponding matlab code========================================/*function   B = rowMaxFilter2(A)%% 1*3 maximum filter%% if A(i,j) is local maximum, then B(i,j)=A(i,j); else B(i,j)=0B = A;[M,N] = size(A);for i=1:M    % apply row-max to each row    for j=2:N        if A(i,j-1)>A(i,j)            B(i,j) = 0;        else            B(i,j-1) = 0;        end    endend%% TEST% A = rand(30,40);% B1 = ordfilt2(A,3,[1 1 1]);% B1(B1~=A) = 0;% B2 = rowMaxFilter2(A);% B1-B2 % should be all zero*/
<hr/>
// 第三段代码:第一种版本的3*1滤波#include <math.h>#ifndef MAX#define MAX(a,b) (a>b?a:b)#endif/* 3*1 maximum filter;B(i,j) is set to local maximum of A(i,j) neighborhood;suppose: A's size is rows*cols, A(i,j) (i<rows,j<cols) is indexed by A[i*witdhstepA+j], i.e. A's element is arranged in memory like: the first row, the second row, ... so on. B is alike. widthstep should be no smaller than cols.(the memory arrangement actually accords with that in openCV)by: Yu Xianguo, NUDT, 2014/6/19*/template<typename T>void  _colMaxFilter( const T *A, int rows, int cols, T *B, int witdhstepA, int widthstepB ){int i = 0, j = 0;const T *Apt = A;T *Bpt = B;// copy A into Bwhile( i++<rows ){j = 0;while( j++<cols )*(Bpt++) = *(Apt++);Apt += witdhstepA - cols;Bpt += widthstepB - cols;}// apply col-max to each colApt = A, Bpt = B;for( i=0; i<cols; i++ ){if( Apt[0]>Apt[witdhstepA] )Bpt[widthstepB] = Apt[0];elseBpt[0] = Apt[witdhstepA];for( j=2; j<rows; j++ )if( Apt[(j-1)*witdhstepA]>Apt[j*witdhstepA] )Bpt[j*widthstepB] = Apt[(j-1)*witdhstepA];elseBpt[(j-1)*widthstepB] = MAX( Apt[j*witdhstepA], Apt[(j-2)*witdhstepA] );Apt++, Bpt++;}}void  colMaxFilter( const int *A, int rows, int cols, int *B, int widthstepA, int witdhstepB){_colMaxFilter(A,rows,cols,B,widthstepA,witdhstepB);}void  colMaxFilter( const float *A, int rows, int cols, float *B, int widthstepA, int witdhstepB){_colMaxFilter(A,rows,cols,B,widthstepA,witdhstepB);}void  colMaxFilter( const double *A, int rows, int cols, double *B, int widthstepA, int witdhstepB){_colMaxFilter(A,rows,cols,B,widthstepA,witdhstepB);}/* >>>TEST<<<int main(){// use matlab to generate a random array: A = rand(5,6)float A[5*6] = { 1.0347, 0.8884, 1.4384, -0.1022, -0.0301, -0.8637, 0.7269, -1.1471, 0.3252, -0.2414, -0.1649, 0.0774, -0.3034, -1.0689, -0.7549, 0.3192, 0.6277, -1.2141, 0.2939, -0.8095, 1.3703, 0.3129, 1.0933, -1.1135, -0.7873, -2.9443, -1.7115, -0.8649, 1.1093, -0.0068 };float B[30];colMaxFilter( A, 5, 6, B, 6, 6 );for( int i=0; i<5; i++ ){for( int j=0; j<6; j++ )printf("%g\t",B[i*6+j]);printf("\n");}// true result is://1.0347    0.8884    1.4384   -0.1022   -0.0301    0.0774//1.0347    0.8884    1.4384    0.3192    0.6277    0.0774//0.7269   -0.8095    1.3703    0.3192    1.0933    0.0774//0.2939   -0.8095    1.3703    0.3192    1.1093   -0.0068//0.2939   -0.8095    1.3703    0.3129    1.1093   -0.0068return 0;}*///===================corresponding matlab code========================================/*function  B = rowMaxFilter(A)%% 1*3 maximum filter%% B(i,j) is set to local maximum of A(i,j) neighborhoodB = A;[M,N] = size(A);for i=1:M    % apply row-max to each row    if A(i,1)>A(i,2)        B(i,2) = A(i,1);    else        B(i,1) = A(i,2);    end    for j=3:N        if A(i,j-1)>A(i,j)            B(i,j) = A(i,j-1);        else            B(i,j-1) = max(A(i,j-2),A(i,j));        end    endend%% TEST% A = rand(50,60);% B1 = ordfilt2(A,3,[1 1 1]);% B2 = rowMaxFilter(A);% C = B1 - B2;% max(abs(C(:))) % should be ZERO*/
<hr/>
// 第四段代码:第二种版本的3*1滤波#include <stdio.h>/* 3*1 maximum filter;if A(i,j) is local maximum, then B(i,j)=A(i,j); else B(i,j)=0suppose: A's size is rows*cols, A(i,j) (i<rows,j<cols) is indexed by A[i*witdhstepA+j], i.e. A's element is arranged in memory like: the first row, the second row, ... so on. B is alike. widthstep should be no smaller than cols.(the memory arrangement actually accords with that in openCV)by: Yu Xianguo, NUDT, 2014/6/19*/template<typename T>void  _colMaxFilter2( const T *A, int rows, int cols, T *B, int witdhstepA, int widthstepB ){int i = 0, j = 0;const T *Apt = A;T *Bpt = B;// copy A into Bwhile( i++<rows ){j = 0;while( j++<cols )*(Bpt++) = *(Apt++);Apt += witdhstepA - cols;Bpt += widthstepB - cols;}// apply col-max to each colApt = A, Bpt = B;for( i=0; i<cols; i++ ){for( j=1; j<rows; j++ )if( Apt[(j-1)*witdhstepA]>Apt[j*witdhstepA] )Bpt[j*widthstepB] = 0;elseBpt[(j-1)*widthstepB] = 0;Apt++;Bpt++;}}void  colMaxFilter2( const int *A, int rows, int cols, int *B, int widthstepA, int witdhstepB){_colMaxFilter2(A,rows,cols,B,widthstepA,witdhstepB);}void  colMaxFilter2( const float *A, int rows, int cols, float *B, int widthstepA, int witdhstepB){_colMaxFilter2(A,rows,cols,B,widthstepA,witdhstepB);}void  colMaxFilter2( const double *A, int rows, int cols, double *B, int widthstepA, int witdhstepB){_colMaxFilter2(A,rows,cols,B,widthstepA,witdhstepB);}/* >>>TEST<<<int main(){// use matlab to generate a random array: A = rand(5,6)float A[5*6] = { 1.0347, 0.8884, 1.4384, -0.1022, -0.0301, -0.8637, 0.7269, -1.1471, 0.3252, -0.2414, -0.1649, 0.0774, -0.3034, -1.0689, -0.7549, 0.3192, 0.6277, -1.2141, 0.2939, -0.8095, 1.3703, 0.3129, 1.0933, -1.1135, -0.7873, -2.9443, -1.7115, -0.8649, 1.1093, -0.0068 };float B[30];colMaxFilter2( A, 5, 6, B, 6, 6 );for( int i=0; i<5; i++ ){for( int j=0; j<6; j++ )printf("%g\t",B[i*6+j]);printf("\n");}// true result is://1.0347    0.8884    1.4384   -0.1022   -0.0301         0//0         0         0         0         0    0.0774//0         0         0    0.3192         0         0//0.2939   -0.8095    1.3703         0         0         0//0         0         0         0    1.1093   -0.0068return 0;}*///===================corresponding matlab code========================================/*function   B = colMaxFilter2(A)%% 3*1 maximum filter%% if A(i,j) is local maximum, then B(i,j)=A(i,j); else B(i,j)=0B = A;[M,N] = size(A);for i=1:N    % apply col-max to each col    for j=2:M        if A(j-1,i)>A(j,i)            B(j,i) = 0;        else            B(j-1,i) = 0;        end    endend%% TEST% A = rand(30,40);% B1 = ordfilt2(A,3,[1;1;1]);% B1(B1~=A) = 0;% B2 = colMaxFilter2(A);% B1-B2 % should be all zero*/
<hr/>
// 第五段代码:3*3最大值滤波 ~ 应该是属于第一种版本#include <stdlib.h>#ifndef MAX#define MAX(a,b) (a>b?a:b)#endif/* 1*3 maximum filter;B(i,j) is set to local maximum of A(i,j) neighborhood;suppose: A's size is rows*cols, A(i,j) (i<rows,j<cols) is indexed by A[i*witdhstepA+j], i.e. A's element is arranged in memory like: the first row, the second row, ... so on. B is alike. widthstep should be no smaller than cols.(the memory arrangement actually accords with that in openCV)by: Yu Xianguo, NUDT, 2014/6/19*/template<typename T>void  _rowMaxFilter( const T *A, int rows, int cols, T *B, int witdhstepA, int widthstepB ){int i = 0, j = 0;const T *Apt = A;T *Bpt = B;// copy A into Bwhile( i++<rows ){j = 0;while( j++<cols )*(Bpt++) = *(Apt++);Apt += witdhstepA - cols;Bpt += widthstepB - cols;}// apply row-max to each rowApt = A, Bpt = B;for( i=0; i<rows; i++ ){if( Apt[0]>Apt[1] )Bpt[1] = Apt[0];elseBpt[0] = Apt[1];for( j=2; j<cols; j++ )if( Apt[j-1]>Apt[j] )Bpt[j] = Apt[j-1];elseBpt[j-1] = MAX( Apt[j-2], Apt[j] );Apt += witdhstepA;Bpt += widthstepB;}}/* 3*1 maximum filter;B(i,j) is set to local maximum of A(i,j) neighborhood;suppose: A's size is rows*cols, A(i,j) (i<rows,j<cols) is indexed by A[i*witdhstepA+j], i.e. A's element is arranged in memory like: the first row, the second row, ... so on. B is alike. widthstep should be no smaller than cols.(the memory arrangement actually accords with that in openCV)by: Yu Xianguo, NUDT, 2014/6/19*/template<typename T>void  _colMaxFilter( const T *A, int rows, int cols, T *B, int witdhstepA, int widthstepB ){int i = 0, j = 0;const T *Apt = A;T *Bpt = B;// copy A into Bwhile( i++<rows ){j = 0;while( j++<cols )*(Bpt++) = *(Apt++);Apt += witdhstepA - cols;Bpt += widthstepB - cols;}// apply col-max to each colApt = A, Bpt = B;for( i=0; i<cols; i++ ){if( Apt[0]>Apt[witdhstepA] )Bpt[widthstepB] = Apt[0];elseBpt[0] = Apt[witdhstepA];for( j=2; j<rows; j++ )if( Apt[(j-1)*witdhstepA]>Apt[j*witdhstepA] )Bpt[j*widthstepB] = Apt[(j-1)*witdhstepA];elseBpt[(j-1)*widthstepB] = MAX( Apt[j*witdhstepA], Apt[(j-2)*witdhstepA] );Apt++, Bpt++;}}/*3*3 maximum filter;B(i,j) is set to local maximum of A(i,j) neighborhood.by: Yu Xianguo, NUDT, 2014/6/19*/template<typename T>void  _maximumFilter( const T *A, int rows, int cols, T *B, int witdhstepA, int widthstepB ){T *tmp = new T [rows*cols] ();_rowMaxFilter( A, rows, cols, tmp, witdhstepA, cols );_colMaxFilter( tmp, rows, cols, B, cols, widthstepB );delete [] tmp;}void  maximumFilter( const int *A, int rows, int cols, int *B, int widthstepA, int witdhstepB){_maximumFilter(A,rows,cols,B,widthstepA,witdhstepB);}void  maximumFilter( const float *A, int rows, int cols, float *B, int widthstepA, int witdhstepB){_maximumFilter(A,rows,cols,B,widthstepA,witdhstepB);}void  maximumFilter( const double *A, int rows, int cols, double *B, int widthstepA, int witdhstepB){_maximumFilter(A,rows,cols,B,widthstepA,witdhstepB);}/* >>>TEST<<<int main(){// use matlab to generate a random array: A = rand(5,6)float A[5*6] = { 1.0347, 0.8884, 1.4384, -0.1022, -0.0301, -0.8637, 0.7269, -1.1471, 0.3252, -0.2414, -0.1649, 0.0774, -0.3034, -1.0689, -0.7549, 0.3192, 0.6277, -1.2141, 0.2939, -0.8095, 1.3703, 0.3129, 1.0933, -1.1135, -0.7873, -2.9443, -1.7115, -0.8649, 1.1093, -0.0068 };float B[30];maximumFilter( A, 5, 6, B, 6, 6 );for( int i=0; i<5; i++ ){for( int j=0; j<6; j++ )printf("%g\t",B[i*6+j]);printf("\n");}// true result is://1.0347    1.4384    1.4384    1.4384    0.0774    0.0774//1.0347    1.4384    1.4384    1.4384    0.6277    0.6277//0.7269    1.3703    1.3703    1.3703    1.0933    1.0933//0.2939    1.3703    1.3703    1.3703    1.1093    1.1093//0.2939    1.3703    1.3703    1.3703    1.1093    1.1093return 0;}*/











0 0
原创粉丝点击