C++实现最大值滤波器

    今天给大家分享我最近写的几行代码,用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 B
	while( i++<rows ){
		j = 0;
		while( j++<cols )
			*(Bpt++) = *(Apt++);
		Apt += witdhstepA - cols;
		Bpt += widthstepB - cols;
	}
	// apply row-max to each row
	Apt = A, Bpt = B;
	for( i=0; i<rows; i++ ){
		if( Apt[0]>Apt[1] )
			Bpt[1] = Apt[0];
		else
			Bpt[0] = Apt[1];
		for( j=2; j<cols; j++ )
			if( Apt[j-1]>Apt[j] )
				Bpt[j] = Apt[j-1];
			else
				Bpt[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.1093
	return 0;
}
*/

//===================corresponding matlab code========================================
/*
function  B = colMaxFilter(A)
%% 3*1 maximum filter
%% B(i,j) is set to local maximum of A(i,j) neighborhood
B = 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
    end
end

%% 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)=0
	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  _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 B
	while( i++<rows ){
		j = 0;
		while( j++<cols )
			*(Bpt++) = *(Apt++);
		Apt += witdhstepA - cols;
		Bpt += widthstepB - cols;
	}
	// apply row-max to each row
	Apt = A, Bpt = B;
	for( i=0; i<rows; i++ ){
		for( j=1; j<cols; j++ )
			if( Apt[j-1]>Apt[j] )
				Bpt[j] = 0;
			else
				Bpt[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         0
	return 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)=0
B = 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
    end
end
%% 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 B
	while( i++<rows ){
		j = 0;
		while( j++<cols )
			*(Bpt++) = *(Apt++);
		Apt += witdhstepA - cols;
		Bpt += widthstepB - cols;
	}
	// apply col-max to each col
	Apt = A, Bpt = B;
	for( i=0; i<cols; i++ ){
		if( Apt[0]>Apt[witdhstepA] )
			Bpt[widthstepB] = Apt[0];
		else
			Bpt[0] = Apt[witdhstepA];
		for( j=2; j<rows; j++ )
			if( Apt[(j-1)*witdhstepA]>Apt[j*witdhstepA] )
				Bpt[j*widthstepB] = Apt[(j-1)*witdhstepA];
			else
				Bpt[(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.0068
	return 0;
}
*/

//===================corresponding matlab code========================================
/*
function  B = rowMaxFilter(A)
%% 1*3 maximum filter
%% B(i,j) is set to local maximum of A(i,j) neighborhood
B = 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
    end
end

%% 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)=0
	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  _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 B
	while( i++<rows ){
		j = 0;
		while( j++<cols )
			*(Bpt++) = *(Apt++);
		Apt += witdhstepA - cols;
		Bpt += widthstepB - cols;
	}
	// apply col-max to each col
	Apt = 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;
			else
				Bpt[(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.0068
	return 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)=0
B = 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
    end
end
%% 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 B
	while( i++<rows ){
		j = 0;
		while( j++<cols )
			*(Bpt++) = *(Apt++);
		Apt += witdhstepA - cols;
		Bpt += widthstepB - cols;
	}
	// apply row-max to each row
	Apt = A, Bpt = B;
	for( i=0; i<rows; i++ ){
		if( Apt[0]>Apt[1] )
			Bpt[1] = Apt[0];
		else
			Bpt[0] = Apt[1];
		for( j=2; j<cols; j++ )
			if( Apt[j-1]>Apt[j] )
				Bpt[j] = Apt[j-1];
			else
				Bpt[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 B
	while( i++<rows ){
		j = 0;
		while( j++<cols )
			*(Bpt++) = *(Apt++);
		Apt += witdhstepA - cols;
		Bpt += widthstepB - cols;
	}
	// apply col-max to each col
	Apt = A, Bpt = B;
	for( i=0; i<cols; i++ ){
		if( Apt[0]>Apt[witdhstepA] )
			Bpt[widthstepB] = Apt[0];
		else
			Bpt[0] = Apt[witdhstepA];
		for( j=2; j<rows; j++ )
			if( Apt[(j-1)*witdhstepA]>Apt[j*witdhstepA] )
				Bpt[j*widthstepB] = Apt[(j-1)*witdhstepA];
			else
				Bpt[(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.1093
	return 0;
}
*/











  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值