Created
May 25, 2017 06:58
-
-
Save ntzyz/9b787564d3f17111695a2427d29c97bd to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!doctype html> | |
<html> | |
<head> | |
<title></title> | |
<meta charset="UTF-8" /> | |
</head> | |
<body> | |
<table> | |
<tr> | |
<td>sigma</td> | |
<td><input id="sigma" type="text" value="1.5" disabled/></td> | |
</tr> | |
<tr> | |
<td>radius</td> | |
<td><input id="radius" type="text" value="10"/></td> | |
</tr> | |
<tr> | |
<td></td> | |
<td><button onclick="GaussianBlur()">Start</button></td> | |
</tr> | |
</table> | |
<canvas style="border: 1px solid black;"></canvas> | |
<script> | |
let canvas = document.querySelector('canvas'); | |
let ctx = canvas.getContext('2d'); | |
let img = new Image(); | |
img.src = './2.png'; | |
img.onload = e => { | |
canvas.width = img.naturalWidth; | |
canvas.height = img.naturalHeight; | |
ctx.drawImage(img, 0, 0, img.naturalWidth, img.naturalHeight); | |
} | |
function G(u, v) { | |
let sigma = Number(document.querySelector('#sigma').value); | |
return (1 / (2 * Math.PI * Math.pow(sigma, 2))) * Math.pow(Math.E, -(u ** 2 + v ** 2) / (2 * sigma ** 2)); | |
} | |
function GaussianBlur() { | |
let src = ctx.getImageData(0, 0, canvas.width, canvas.height); | |
let radius = Number(document.querySelector('#radius').value); | |
let sigma = (radius - 1) / 6; | |
document.querySelector('#sigma').value = sigma; | |
// Construct matrix | |
let sum = 0; | |
let matrix = window.matrix = new Array(2 * radius + 1).fill(0).map(() => new Array(2 * radius + 1)); | |
for (let u = -radius; u <= radius; u++) { | |
for (let v = -radius; v <= radius; v++) { | |
matrix[radius + u][radius + v] = G(u, v); | |
sum += matrix[radius + u][radius + v]; | |
} | |
} | |
for (let u = -radius; u <= radius; u++) { | |
for (let v = -radius; v <= radius; ++v) { | |
matrix[radius + u][radius + v] /= sum; | |
} | |
} | |
let dest = ctx.getImageData(0, 0, canvas.width, canvas.height); | |
let setPixel = (x, y, r, g, b) => { | |
dest.data[(y * canvas.width + x) * 4 + 0] = r; | |
dest.data[(y * canvas.width + x) * 4 + 1] = g; | |
dest.data[(y * canvas.width + x) * 4 + 2] = b; | |
} | |
let getPixel = (x, y) => { | |
return [ | |
src.data[(y * canvas.width + x) * 4 + 0], | |
src.data[(y * canvas.width + x) * 4 + 1], | |
src.data[(y * canvas.width + x) * 4 + 2], | |
]; | |
} | |
for (let x = radius; x < canvas.width - radius; ++x) { | |
for (let y = radius; y <= canvas.height - radius; ++y) { | |
let r = 0, g = 0, b = 0; | |
for (let u = -radius; u <= radius; u++) { | |
for (let v = -radius; v <= radius; v++) { | |
let pixel = getPixel(x + u, y + v); | |
r += pixel[0] * matrix[radius + u][radius + v]; | |
g += pixel[1] * matrix[radius + u][radius + v]; | |
b += pixel[2] * matrix[radius + u][radius + v]; | |
} | |
} | |
setPixel(x, y, r, g, b); | |
} | |
} | |
ctx.putImageData(dest, 0, 0, 0, 0, canvas.width, canvas.height); | |
} | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment