OpenCV邻域滤波代码模板

滤波是图像处理常用的操作,其中比较常用的是根据像素邻域的值计算某像素的值。

用OpenCV实现的代码模板如下:

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>

#define MAX_CHANNEL 3
#define MAX_CORE_X 11
#define MAX_CORE_Y 11
#define MAX_CORE_LENGTH MAX_CORE_X*MAX_CORE_Y
#define PI 3.1415926
#define E 2.7182818

using namespace cv;
using namespace std;

float core33[9]={
	0.0947416,0.118318,0.0947416,
	0.118318,0.147761,0.118318,
	0.0947416,0.118318,0.0947416
};

int gaussianCore(float core[], int cx, int cy, double lamda)
{
	double lamda2 = 2.0*lamda*lamda;
	double pi1 = 1.0 / PI / lamda2;
	int sq;
	double power;
	double gaus;
	double sum=0.0;

	for(int j=0; j<cy; j++)
	{
		for(int i=0; i<cx; i++)
		{
			sq = (cx/2-i)*(cx/2-i) + (cy/2-j)*(cy/2-j);
			power = -(double)sq / lamda2;
			gaus = pi1*pow(E,power);
			core[j*cx+i] = gaus;
			sum += gaus;
		}
	}

	for(int j=0; j<cy; j++)
	{
		for(int i=0; i<cx; i++)
		{
			core[j*cx+i] /= sum;
		}
	}

	return 1;
}

int meanCore(float* core,int width, int height)
{
	if(width > MAX_CORE_X || height > MAX_CORE_Y)
		return 0;

	int count = width*height;
	for(int i=0; i<count; i++)
		core[i] = 1.0/count;
	return 1;
}

int motionBlurCore(float* core, int width, int height, int dir)
{
	if(height != 1 || width%2 != 1)
		return 0;

	int count = width/2+1;
	if(dir == 0)
	{
		for(int i=0; i<count; i++)
			core[i] = 1.0/count;
		for(int i=count; i<width; i++)
			core[i] = 0.0;
	}else{
		for(int i=0; i<count-1; i++)
			core[i] = 0.0;
		for(int i=count-1; i<width; i++)
			core[i] = 1.0/count;
	}
	return 1;
}

void filter(Mat src, Mat dst, const float core[], int cx, int cy)
{
	int width = src.cols;
	int height = src.rows;
	int channel = src.channels();

	uchar *pout;
	uchar *tmp;

	int line[MAX_CORE_LENGTH]={0};
	int cx2 = cx/2;
	int cy2 = cy/2;
	for(int j=0; j<height; j++)
	{
		pout = dst.ptr<uchar>(j);
		for(int i=0; i<width; i++)
		{
			float sum[MAX_CHANNEL]={0};

			for(int y=0; y<cy; y++)
			{
				for(int x=0; x<cx; x++)
				{
					int tx = i+x-cx2;
					int cp = y*cx+x;

					for(int c=0; c<channel; c++)
					{
						if(j+y-cy2 < 0)
						{
							tmp = src.ptr<uchar>(0);
							if(tx < 0)
								sum[c] += tmp[c]*core[cp];
							else if(tx >= width)
								sum[c] += tmp[(width-1)*channel+c]*core[cp];
							else
								sum[c] += tmp[tx*channel+c]*core[cp];
						}else if(j+y-cy2 >= height)
						{
							tmp = src.ptr<uchar>(height-1);
							if(tx < 0)
								sum[c] += tmp[c]*core[cp];
							else if(tx >= width)
								sum[c] += tmp[(width-1)*channel+c]*core[cp];
							else
								sum[c] += tmp[tx*channel+c]*core[cp];
						}else{
							tmp = src.ptr<uchar>(j);
							int ty = (y-cy2)*width*channel;
							if(tx < 0)
								sum[c] += tmp[ty+c]*core[cp];
							else if(tx >= width)
								sum[c] += tmp[ty+(width-1)*channel+c]*core[cp];
							else
								sum[c] += tmp[ty+tx*channel+c]*core[cp];
						}
					}
				}
			}
			for(int r=0; r<channel; r++)
			{
				pout[i*channel+r] = (int)sum[r];
			}
		}
	}
}

int main( int argc, char** argv )
{
	Mat srcImg = imread("H:\\codmw2.jpg");

	if( !srcImg.data )
	{ return -1; }
	imshow("source",srcImg);

	double timeSpent = (double)getTickCount();

	Mat dstImg(srcImg.size(),CV_8UC3);

	float core[9];
	int x=9, y=1;
	if(motionBlurCore(core,x,y,0))
		filter(srcImg,dstImg,core,x,y);

	timeSpent = ((double)getTickCount() - timeSpent)/getTickFrequency();
	cout << "Time spent in seconds: " << timeSpent << endl;

	imshow("result",dstImg);
	//imwrite("H:\\codmw2_filter.jpg",dstImg);

	waitKey(0);

	return 0;
}

代码中给出了三个常用的模板核。

效果如下:

高斯滤波(gaussianCore)

x=9,y=9,lamda=0.84089642

gaussian-blur

均值滤波(meanCore)

x=7,y=7

mean-filter

运动模糊滤波(motionBlurCore)

该滤波器的原理可以参考http://blog.csdn.net/johnhany/article/details/8251369

x=13,y=1,dir=0

motion-blur

把这篇文章分享给你的朋友:
Subscribe
订阅评论
guest
2 评论
最新
最旧 得票最多
Inline Feedbacks
View all comments
liuyao
liuyao
2 年 之前

请问您的这个代码运行的时候是出现的运动模糊结果对吧??怎么换成别的呢??

liuyao
liuyao
2 年 之前

您好,有相关去模糊代码吗?谢谢