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[radiusradius]; float sum = 0; float e = 2.71828; int i, j; for (i = 1; i
for (int j = 0; j<radius; j++) { filter[iradius + 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[radiusradius]; float sum = 0; float e = 2.71828; int i, j; for (i = 1; i
for (int j = 0; j<radius; j++) { filter[iradius + j] = filter[iradius + j] / sum; } } return filter; } float mgaussian(int height, int width, int k, float weight, float imagedata, int type) { float newimage = new float[heightwidthtype]; //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[3widthi+3j+m]=imagedata[3widthi+3j+m]; for(int mtype=0;mtype<type;mtype++) { float valuep=0; for(int nh=0;nh<2k+1;nh++) for(int nw=0;nw<2k+1;nw++) { //纵向是否超出范围 int mx=i+nh-k; if(mx<0||mx>height-1) mx=2i-mx; //判断横向是否超出范围 int my=j+nw-k; if(my<0||my>width-1) my=2j-my; valuep=valuep+weight[nh(2k+1)+nw]imagedata[typemxwidth+typemy+mtype]; } newimage[typeiwidth+typej+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;} 到此,高斯模糊处理完毕
原文链接:https://blog.csdn.net/yuanheng19930119/article/details/87972786
推荐阅读:
linux安装中文输入法 关闭内核串口调试信息 关于linux定时器和Hi3536的VDEC解码免责声明:文章内容来自互联网,本站不对其真实性负责,也不承担任何法律责任,如有侵权等情况,请与本站联系删除。
转载请注明出处:高斯模糊算法 https://www.yhzz.com.cn/a/15299.html