Skip to content

Instantly share code, notes, and snippets.

@danasilver
Last active March 4, 2016 03:10
Show Gist options
  • Save danasilver/de3dd56bca2614c3a977 to your computer and use it in GitHub Desktop.
Save danasilver/de3dd56bca2614c3a977 to your computer and use it in GitHub Desktop.
Sharpen
height: 504
license: MIT

Perform a [convolution](https://en.wikipedia.org/wiki/Kernel_(image_processing) using a sharpening kernel where the center weight (5) is the origin:

[
  [0, -1,  0],
  [-1, 5, -1],
  [0, -1,  0]
]

A convolution is performed by moving the kernel origin to each pixel of the base image, multiplying the each value of the kernel by its base image value relative to the origin, and summing the products to get the new value for that pixel.

Another familiar convolution is Gaussian blur.

<!doctype html>
<meta charset="utf-8">
<style>
body {
width: 960px;
height: 504px;
}
.pixel {
height: 5px;
width: 5px;
margin-right: 1px;
margin-bottom: 1px;
float: left;
}
</style>
<body>
<script src="https://d3js.org/d3.v3.min.js"></script>
<script>
var width = 960,
height = 504,
rows = 84,
columns = 160;
var pixels = d3.range(rows)
.map(function() {
return d3.range(columns).map(function() { return Math.random() * 255 | 0; });
});
var sharpen = [
[0, -1, 0],
[-1, 5, -1],
[0, -1, 0]
];
var convolved = false;
var divs = d3.select('body').selectAll('div')
.data(d3.merge(pixels));
divs.enter()
.append('div')
.attr('class', 'pixel')
.style('background-color', function(d) { return 'rgb(' + d + ',' + d + ',' + d + ')' });
setInterval(transition, 3000);
transition();
function update(data) {
divs
.data(data)
.transition()
.delay(function(d, i) {
return convolved ? (columns - (i % columns)) * 10 : (i % columns) * 10;
})
.duration(1000)
.style('background-color', function(d) { return 'rgb(' + d + ',' + d + ',' + d + ')' });
}
function transition() {
update(d3.merge(convolved ? pixels : convolve(pixels, sharpen)));
convolved = !convolved;
}
function convolve(pixels, kernel) {
var height = pixels.length,
width = pixels[0].length,
kernelHeight = kernel.length,
kernelWidth = kernel[0].length;
var output = d3.range(height)
.map(function() { return d3.range(width).map(function() { return 0; }); });
for (var y = 0; y < height; y++) {
for (var x = 0; x < width; x++) {
var accumulator = 0;
for (var kernelY = 0; kernelY < kernelHeight; kernelY++) {
for (var kernelX = 0; kernelX < kernelWidth; kernelX++) {
// kernel origin is in the center of the 2d array
var currentY = y + kernelY - Math.floor(kernelHeight / 2);
var currentX = x + kernelX - Math.floor(kernelWidth / 2);
if (currentY >= 0 && currentY < height &&
currentX >= 0 && currentX < width) {
var src = pixels[currentY][currentX];
var weight = kernel[kernelY][kernelX];
accumulator += src * weight;
}
}
}
output[y][x] = accumulator;
}
}
return output;
}
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment