高斯模糊算法

1.高斯模糊算法效果(左边是原始图像,右边是处理后的图像)

2.算法原理

2.1"模糊"的算法有很多种,其中有一种叫做"高斯模糊"(Gaussian Blur)。它将正态分布(又名"高斯分布")用于图像处理。
2.2“高斯模糊“二维正态分布为权重,以K((2xK+1)*2)为半径,进行卷积,K越大模糊程度越大
2.3距离中心点越远的像素所获得权重越小
2.4权值计算:二维正态分布函数

2.5x,y坐标选取,其中б是方差,可以自己选取,方差越大,模糊效果越好,注意算得权值要进行归一化,因为算得权值之和不一定为1,所以要使得他们的值之和为1

2.6将算得的权值与图像中的每个像素进行卷积,算得新的图像,就是你需要的图像
2.7边缘处理:对边缘像素进行对称处理来代替没有像素的值,这里以3*3(半径K=1)模板为例,首先判断模板的X坐标在图像坐标中的位置,如果不在图像中,将其X坐标关于模板中心的X坐标对称,如果此时该点还在图像外面,再将其Y坐标关于模板中心的Y坐标对称,此时该点一定在图像上,以此点的坐标的像素值来代替模板在图像外面的像素值。

2.8.计算权重的函数

//获取核函数
float *getWeight(int k, float sigma) {
	int radius = 2 * k + 1;
	float *filter = new float[radius*radius];
	float sum = 0;
	float e = 2.71828;
	int i, j;
	for (i = 1; i<radius + 1; i++)
		for (j = 1; j<radius + 1; j++)
		{
			float cifang = -((i - k - 1)*(i - k - 1) + (j - k - 1)*(j - k - 1)) / (2 * sigma*sigma);
			filter[(i - 1)*radius + j - 1] = pow(e, cifang) / (2 * 3.14159*sigma*sigma);
			sum = sum + filter[(i - 1)*radius + j - 1];
		}
		//将权值归一化
		for (i = 0; i<radius; i++)
		{			
			for (int j = 0; j<radius; j++)
			{
				filter[i*radius + j] = filter[i*radius + j] / sum;
			}
		}
		return filter;
}

这里我读图片是用了opencv的函数,在VS中配置OpenCV(https://blog.csdn.net/yuanheng19930119/article/details/87972536)的步骤,见链接

#include "highgui.h"
#include "time.h"
#include "math.h"
#include "omp.h"
 
//获取核函数
float *getWeight(int k, float sigma) {
	int radius = 2 * k + 1;
	float *filter = new float[radius*radius];
	float sum = 0;
	float e = 2.71828;
	int i, j;
	for (i = 1; i<radius + 1; i++)
		for (j = 1; j<radius + 1; j++)
		{
			float cifang = -((i - k - 1)*(i - k - 1) + (j - k - 1)*(j - k - 1)) / (2 * sigma*sigma);
			filter[(i - 1)*radius + j - 1] = pow(e, cifang) / (2 * 3.14159*sigma*sigma);
			sum = sum + filter[(i - 1)*radius + j - 1];
		}
		//将权值归一化
		for (i = 0; i<radius; i++)
		{			
			for (int j = 0; j<radius; j++)
			{
				filter[i*radius + j] = filter[i*radius + j] / sum;
			}
		}
		return filter;
}
float *mgaussian(int height, int width, int k, float *weight, float *imagedata, int type) {
float *newimage = new float[height*width*type];
//omp_get_num_threads();
//omp_set_num_threads(3);
//#pragma omp parallel for
	for (int i = 0; i<height; i++)
	{
		for (int j = 0; j<width; j++) {
			//对边缘像素的处理
			if(i<k||j<k||i>=height-k||j>=width-k)
			{
				//for(int m=0;m<type;m++)
				//newimage[3*width*i+3*j+m]=imagedata[3*width*i+3*j+m];
				for(int mtype=0;mtype<type;mtype++)
				{
					float valuep=0;
					for(int nh=0;nh<2*k+1;nh++)
						for(int nw=0;nw<2*k+1;nw++)
						{
							//纵向是否超出范围
							int mx=i+nh-k;
							if(mx<0||mx>height-1)
								mx=2*i-mx;
							//判断横向是否超出范围
							int my=j+nw-k;
							if(my<0||my>width-1)
								my=2*j-my;
							valuep=valuep+weight[nh*(2*k+1)+nw]*imagedata[type*mx*width+type*my+mtype];
						}
						newimage[type*i*width+type*j+mtype]=valuep;
				}
				continue;
			}
 
			//高斯核函数计算
			for (int mtype2 = 0; mtype2<type; mtype2++)
			{
				float pixelval = 0;
				for (int nh2 = 0; nh2<2 * k + 1; nh2++)
					for (int nw2 = 0; nw2<2 * k + 1; nw2++)
					{
						pixelval = pixelval + weight[nh2*(2 * k + 1) + nw2] * imagedata[type*(i + nh2 - k)*width + type*(j + nw2 - k) + mtype2];
					}
					newimage[type*i*width + type*j + mtype2] = pixelval;
			}
		}
	}
	return newimage;
}
int main(int argc, char** argv)
{
 
	
	IplImage* img = cvLoadImage("C:\\Users\\heng\\Desktop\\test.jpg");
	int mwidth, mheight, mtype;
	int i, j, k = 1;
	float sigma = 10;
	printf("请输入高斯核函数的半径:");
	scanf("%d",&k);
	printf("请输入高斯核函数的方差sigma:");
	scanf("%f",&sigma);
	
	//double start = clock();
 
	mwidth = img->width;
	mheight = img->height;
	mtype = img->nChannels;
	//CvMat *imageMat=cvCreateMat(mheight,mheight*mtype,CV_32FC1);
	float *imageMat = new float[mwidth*mheight*mtype];
	float *Gweight = getWeight(k, sigma);
	//去除像素点放到imageMat中
	for (i = 0; i<mheight; i++)
		for (j = 0; j<mwidth; j++) {
			CvScalar s;
			s = cvGet2D(img, i, j);// get the (i,j) pixel value
			for (int index = 0; index<mtype; index++) {
				imageMat[3 * mwidth*i + 3 * j + index] = s.val[index];
			}
		}
		float *imageMat2 = mgaussian(mheight, mwidth, k, Gweight, imageMat, mtype);
		IplImage* img2 = cvCreateImage(cvSize(mwidth, mheight), IPL_DEPTH_8U, mtype);
		//将处理后的图像值放入图像中显示
		for (i = 0; i<mheight; i++)
			for (j = 0; j<mwidth; j++) {
				CvScalar s;
				for (int mmtype = 0; mmtype<mtype; mmtype++) {
					int p = int(imageMat2[mtype*mwidth*i + mtype*j + mmtype] + 0.5);
					if (p>255)
						p = 255;
					s.val[mmtype] = p;
				}
				cvSet2D(img2, i, j, s);
			}
			cvNamedWindow("显示原图像", CV_WINDOW_AUTOSIZE);
			cvShowImage("显示原图像", img);
			cvNamedWindow("显示高斯滤波处理后的图像", CV_WINDOW_AUTOSIZE);
			cvShowImage("显示高斯滤波处理后的图像", img2);
			//double end = clock();
			//printf("time=%f", end - start);
			cvWaitKey(0);
			cvReleaseImage(&img);
			cvReleaseImage(&img2);
			cvDestroyWindow("显示原图像");
			cvDestroyWindow("显示高斯滤波处理后的图像");
			delete[] imageMat;
			delete[] imageMat2;
		
}

到此,高斯模糊处理完毕
 

  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值