高斯模糊算法

TT_123456789 2020-08-03 13:41:44 1563

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<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 sigmasigma);
filter[(i - 1)radius + j - 1] = pow(e, cifang) / (2 3.14159sigmasigma);
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[radiusradius];
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 sigmasigma);
filter[(i - 1)radius + j - 1] = pow(e, cifang) / (2 3.14159sigmasigma);
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[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[3
widthi+3j+m]=imagedata[3widthi+3j+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<2k+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=2j-my;
valuep=valuep+weight[nh
(2k+1)+nw]imagedata[typemxwidth+typemy+mtype];
}
newimage[type
iwidth+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

推荐阅读:

声明:本文内容由易百纳平台入驻作者撰写,文章观点仅代表作者本人,不代表易百纳立场。如有内容侵权或者其他问题,请联系本站进行删除。
红包 点赞 收藏 评论 打赏
评论
0个
内容存在敏感词
手气红包
    易百纳技术社区暂无数据
相关专栏
置顶时间设置
结束时间
删除原因
  • 广告/SPAM
  • 恶意灌水
  • 违规内容
  • 文不对题
  • 重复发帖
打赏作者
易百纳技术社区
TT_123456789
您的支持将鼓励我继续创作!
打赏金额:
¥1易百纳技术社区
¥5易百纳技术社区
¥10易百纳技术社区
¥50易百纳技术社区
¥100易百纳技术社区
支付方式:
微信支付
支付宝支付
易百纳技术社区微信支付
易百纳技术社区
打赏成功!

感谢您的打赏,如若您也想被打赏,可前往 发表专栏 哦~

举报反馈

举报类型

  • 内容涉黄/赌/毒
  • 内容侵权/抄袭
  • 政治相关
  • 涉嫌广告
  • 侮辱谩骂
  • 其他

详细说明

审核成功

发布时间设置
发布时间:
是否关联周任务-专栏模块

审核失败

失败原因
备注
拼手气红包 红包规则
祝福语
恭喜发财,大吉大利!
红包金额
红包最小金额不能低于5元
红包数量
红包数量范围10~50个
余额支付
当前余额:
可前往问答、专栏板块获取收益 去获取
取 消 确 定

小包子的红包

恭喜发财,大吉大利

已领取20/40,共1.6元 红包规则

    易百纳技术社区