效果

先上效果图

这里写图片描述

原理

高斯模糊的原理中,它是根据高斯曲线调节像素色值,它是有选择地模糊图像。说得直白一点,就是高斯模糊能够把某一点周围的像素色值按高斯曲线统计起来,采用数学上加权平均的计算方法得到这条曲线的色值,最后能够留下人物的轮廓,即曲线. 更加具体的解释请移步到 阮一峰的高斯模糊算法.

本篇blog主要讨论js的高斯函数及其应用.

采用了两种分别不同的函数来处里像素位点, 第一种是直接使用二种循环, 时间复杂度为O(xy(2r)^2). 另一种是采用一维公式分别对x, y进行循环处理, 时间复杂度为O(2xy(2r)).

代码

Document

window.onload = function(){

var img = document.getElementById("imgSource"),

canvas = document.getElementById('canvas'),

width = img.width,

height = img.height;

canvas.width = width;

canvas.height = height;

var context = canvas.getContext("2d");

context.drawImage(img, 0, 0);

var canvasData = context.getImageData(0, 0, canvas.width, canvas.height);

var tempData = gaussBlur1(canvasData, 20);

context.putImageData(tempData,0,0);

}

/**

* 此函数为二重循环

*/

function gaussBlur(imgData, radius, sigma) {

var pixes = imgData.data,

width = imgData.width,

height = imgData.height;

radius = radius || 5;

sigma = sigma || radius / 3;

var gaussEdge = radius * 2 + 1; // 高斯矩阵的边长

var gaussMatrix = [],

gaussSum = 0,

a = 1 / (2 * sigma * sigma * Math.PI),

b = -a * Math.PI;

for (var i=-radius; i<=radius; i++) {

for (var j=-radius; j<=radius; j++) {

var gxy = a * Math.exp((i * i + j * j) * b);

gaussMatrix.push(gxy);

gaussSum += gxy; // 得到高斯矩阵的和,用来归一化

}

}

var gaussNum = (radius + 1) * (radius + 1);

for (var i=0; i

gaussMatrix[i] = gaussMatrix[i] / gaussSum; // 除gaussSum是归一化

}

//console.log(gaussMatrix);

// 循环计算整个图像每个像素高斯处理之后的值

for (var x=0; x

for (var y=0; y

var r = 0,

g = 0,

b = 0;

//console.log(1);

// 计算每个点的高斯处理之后的值

for (var i=-radius; i<=radius; i++) {

// 处理边缘

var m = handleEdge(i, x, width);

for (var j=-radius; j<=radius; j++) {

// 处理边缘

var mm = handleEdge(j, y, height);

var currentPixId = (mm * width + m) * 4;

var jj = j + radius;

var ii = i + radius;

r += pixes[currentPixId] * gaussMatrix[jj * gaussEdge + ii];

g += pixes[currentPixId + 1] * gaussMatrix[jj * gaussEdge + ii];

b += pixes[currentPixId + 2] * gaussMatrix[jj * gaussEdge + ii];

}

}

var pixId = (y * width + x) * 4;

pixes[pixId] = ~~r;

pixes[pixId + 1] = ~~g;

pixes[pixId + 2] = ~~b;

}

}

imgData.data = pixes;

return imgData;

}

function handleEdge(i, x, w) {

var m = x + i;

if (m < 0) {

m = -m;

} else if (m >= w) {

m = w + i - x;

}

return m;

}

/**

* 此函数为分别循环

*/

function gaussBlur1(imgData,radius, sigma) {

var pixes = imgData.data;

var width = imgData.width;

var height = imgData.height;

var gaussMatrix = [],

gaussSum = 0,

x, y,

r, g, b, a,

i, j, k, len;

radius = Math.floor(radius) || 3;

sigma = sigma || radius / 3;

a = 1 / (Math.sqrt(2 * Math.PI) * sigma);

b = -1 / (2 * sigma * sigma);

//生成高斯矩阵

for (i = 0, x = -radius; x <= radius; x++, i++){

g = a * Math.exp(b * x * x);

gaussMatrix[i] = g;

gaussSum += g;

}

//归一化, 保证高斯矩阵的值在[0,1]之间

for (i = 0, len = gaussMatrix.length; i < len; i++) {

gaussMatrix[i] /= gaussSum;

}

//x 方向一维高斯运算

for (y = 0; y < height; y++) {

for (x = 0; x < width; x++) {

r = g = b = a = 0;

gaussSum = 0;

for(j = -radius; j <= radius; j++){

k = x + j;

if(k >= 0 && k < width){//确保 k 没超出 x 的范围

//r,g,b,a 四个一组

i = (y * width + k) * 4;

r += pixes[i] * gaussMatrix[j + radius];

g += pixes[i + 1] * gaussMatrix[j + radius];

b += pixes[i + 2] * gaussMatrix[j + radius];

// a += pixes[i + 3] * gaussMatrix[j];

gaussSum += gaussMatrix[j + radius];

}

}

i = (y * width + x) * 4;

// 除以 gaussSum 是为了消除处于边缘的像素, 高斯运算不足的问题

// console.log(gaussSum)

pixes[i] = r / gaussSum;

pixes[i + 1] = g / gaussSum;

pixes[i + 2] = b / gaussSum;

// pixes[i + 3] = a ;

}

}

//y 方向一维高斯运算

for (x = 0; x < width; x++) {

for (y = 0; y < height; y++) {

r = g = b = a = 0;

gaussSum = 0;

for(j = -radius; j <= radius; j++){

k = y + j;

if(k >= 0 && k < height){//确保 k 没超出 y 的范围

i = (k * width + x) * 4;

r += pixes[i] * gaussMatrix[j + radius];

g += pixes[i + 1] * gaussMatrix[j + radius];

b += pixes[i + 2] * gaussMatrix[j + radius];

// a += pixes[i + 3] * gaussMatrix[j];

gaussSum += gaussMatrix[j + radius];

}

}

i = (y * width + x) * 4;

pixes[i] = r / gaussSum;

pixes[i + 1] = g / gaussSum;

pixes[i + 2] = b / gaussSum;

// pixes[i] = r ;

// pixes[i + 1] = g ;

// pixes[i + 2] = b ;

// pixes[i + 3] = a ;

}

}

//end

imgData.data = pixes;

return imgData;

}

h5 高斯模糊_基于H5canvas和js的高斯模糊处理相关推荐

  1. 基于H5canvas和js的高斯模糊处理

    效果 先上效果图 原理 高斯模糊的原理中,它是根据高斯曲线调节像素色值,它是有选择地模糊图像.说得直白一点,就是高斯模糊能够把某一点周围的像素色值按高斯曲线统计起来,采用数学上加权平均的计算方法得到这 ...

  2. h5打印时如何控制打印区域(基于jquery.PrintArea.js实现)

    h5打印时如何控制打印区域(基于jquery.PrintArea.js实现) javaSript 的 window.print() 打印时打印范围不可控制,而jquery.PrintArea.js可以 ...

  3. css3情侣游戏,11个基于HTML/CSS/JS的情人节表白可爱小游戏、小动画【情人节主题征文】...

    情人节表白可爱小游戏.小动画 我要悄悄学习,做一个浪漫的程序员 1.小鹿亲嘴 2.变成小猫 3.爱心表白 4.爱心溢出 5.思念如马 6.霓虹灯爱心 7.3D旋转相册 8.用不同的语言说"爱 ...

  4. HTML5游戏_基于DOM平台跳跃小游戏开发_9.按键监听

    HTML5游戏_基于DOM平台跳跃小游戏开发 按键监听 视频讲解 HTML5游戏 效果图 本章知识点: 对象自定义名称属性,可以用变量来命名属性名称 //这段代码把多个属性(品牌, 型号, 排量)赋给 ...

  5. H5播放HLS之hls.min.js库

    H5播放HLS之hls.min.js库 视频推流 H播放HLS 视频推流 为了产生HLS视频,我们可以借助srs来实现rtmp推流并生成HLS流,具体详细使用可以参考我之前的文章,这里不再赘述. 我们 ...

  6. 物联网传感器_基于传感器的物联网预测性维护,为什么必须对机器进行数字信号处理...

    物联网传感器 The industrial plants consist of several types of assets. Sensor based IoT is employed for as ...

  7. Java微服务_医疗管理项目_基于若依快速开发框架

    一.项目简介 项目简介:尚医疗是专门为各大医院.门]诊提供的一款医疗管理平台.系统包含:系统 管理.药品进销存管理.看病就诊.收费管理.检查管理.数据统计等核心模块.通过尚医 疗系统可以快速方便的管理 ...

  8. c语言编写订货系统,学位论文_基于c语言的仓库订货系统的仿真.doc

    学位论文_基于c语言的仓库订货系统的仿真 本科毕业论文(设计.创作) 题目: 基于C语言的仓库订货系统的仿真 学生姓名: 学号: 所在系院: 信息与通信技术系 专业: 电子信息工程 入学时间: 201 ...

  9. arm linux考勤,定稿毕业论文_基于ARM与Linux的员工刷卡考勤系统喜欢就下吧(范文1)...

    <毕业论文_基于ARM与Linux的员工刷卡考勤系统.doc>由会员分享,可免费在线阅读全文,更多与<(定稿)毕业论文_基于ARM与Linux的员工刷卡考勤系统(喜欢就下吧)> ...

最新文章

  1. ArcGIS Server 10.1动态图层 以及Windows Phone/Silverlight客户端实现
  2. FD.io/VPP — QoS — Policer CLI
  3. auto register volatile 比较总结
  4. 【LeetCode】- Search Insert Position(查找插入的位置)
  5. 为什么有些xpath绝对路径拿不到数据_Python爬虫,登陆神器Selenium之xpath的使用
  6. boost::thread模块实现生产者消费者的测试程序
  7. 【01】视C++为一个语言联邦
  8. 华为p4用鸿蒙系统吗_华为mate40是鸿蒙系统吗
  9. Windows10+Ubuntu 18.04.2+ROS 安装笔记(SSD单硬盘)下
  10. oracle 获取一周七天,Oracle中求出本礼拜第一天和第七天的日期
  11. OCP-052考试题库汇总(60)-CUUG内部解答版
  12. 生活大爆炸之何为光速
  13. Power BI学习
  14. Java进阶-面向对象
  15. 利用XML文件以及集合方法设计简单超市管理系统的Java程序
  16. win10企业版2016长期服务版本认证过期怎么办?
  17. sd卡数据恢复源码android,SD卡数据恢复非常简单,想学的看过来!
  18. 阻止创建“迅雷下载“目录
  19. C++实现DLL注入的完整过程
  20. 区块链及以太坊入门介绍

热门文章

  1. JVM -- 垃圾回收;垃圾回收算法(三)
  2. 智能汽车计算机专业,20201230-申万宏源-计算机行业智联汽车系列深度之十四:华为智能汽车布局以及影响几何?.pdf...
  3. 极大似然估计(Maximum likelihood estimation,MLE):用样本估计总体参数
  4. Python解题 - CSDN周赛第32期 - 运输石油(三维背包)
  5. Python:日期和时间包datetime的用法
  6. 武汉大学计算机学院招博士目录
  7. Django之头像实时展示到input框、图片验证码、简单发邮件
  8. android 代码省电模式,我们将向您展示如何在Android8.0Oreo中自定义省电模式
  9. nginx配置解析流程
  10. 十六进制转十进制简洁C++代码