Skip to content

Instantly share code, notes, and snippets.

@biovisualize
Last active March 12, 2019 09:33
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save biovisualize/c31c5eb3bf1c5a72bde9 to your computer and use it in GitHub Desktop.
Save biovisualize/c31c5eb3bf1c5a72bde9 to your computer and use it in GitHub Desktop.
Histogram Equalization

An histogram equalization is a way to enhance local contrasts in an image by using an histogram of its values. I explain the idea in this blog post Here I use d3.scale.quantile for bucketing, inspired by these nice algorithms explained here.

<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
canvas { width:50%; float: left}
</style>
</head>
<body>
<canvas id="imageOriginalCanvas"></canvas>
<canvas id="imageCanvas"></canvas>
<script>
var cnv = document.getElementById('imageCanvas');
var ctx = cnv.getContext('2d');
var cnvori = document.getElementById('imageOriginalCanvas');
var ctxori = cnvori.getContext('2d');
var colorScales = {
'linearBlackAndWhite': function(values){
return d3.scale.linear()
.domain(d3.extent(values))
.range(['#000', '#fff']);
},
'histogramEqualize': function(values){
var buckets = 100;
var quantiles = d3.scale.quantile()
.domain(values)
.range(d3.range(buckets))
.quantiles();
var stopCount = quantiles.length;
var linearScale = d3.scale.linear()
.domain([0, stopCount - 1])
.range([d3.rgb('rgb(0, 0, 0)'), d3.rgb('rgb(255, 255, 255)')]);
var grayScale = d3.range(stopCount).map(function(d){
return linearScale(d);
});
return d3.scale.linear().domain(quantiles).range(grayScale);
}
};
var img = new Image;
img.onload = function(){
cnvori.width = cnv.width = img.width;
cnvori.height = cnv.height = img.height;
ctx.drawImage(img, 0, 0, img.width, img.height);
ctxori.drawImage(img, 0, 0, img.width, img.height);
var imgData = ctx.getImageData(0, 0, img.width, img.height);
var rasterData = [];
for(j = 0; j < (imgData.data.length / 4); j++){
var brightness = d3.lab(d3.rgb(imgData.data[j * 4],
imgData.data[j * 4 + 1],
imgData.data[j * 4 + 2])).l;
rasterData.push(imgData.data[j * 4] === 0 ? null : brightness);
}
var scale = colorScales.histogramEqualize(rasterData);
for(j = 0; j < rasterData.length; j++){
var scaledColor = scale(rasterData[j]);
var color = d3.rgb(scaledColor);
imgData.data[j * 4] = color.r;
imgData.data[j * 4 + 1] = color.g;
imgData.data[j * 4 + 2] = color.b;
imgData.data[j * 4 + 3] = 255;
}
ctx.putImageData(imgData, 0, 0);
};
img.crossOrigin = '';
img.src = 'https://upload.wikimedia.org/wikipedia/commons/0/08/Unequalized_Hawkes_Bay_NZ.jpg';
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment