如何使用 image-js 和 JavaScript 规范化图像(直方图拉伸)?
How do you normalize an image (histogram stretching) using image-js and JavaScript?
我正在使用 image-js。
我查看了文档,但没有看到称为归一化或直方图拉伸的函数。但是我确实看到了一些直方图函数。我可以使用直方图函数对高度值的灰度 PNG 数组进行归一化吗?
图像数组是 0 - 255 范围内的高度值,黑色是最低高度,白色是最高。我正在使用此数组创建灰度高度图图像。
澄清一下:
归一化是指对图像颜色进行归一化,在本例中为灰度。喜欢这个项目,但使用 image-js https://www.npmjs.com/package/@jimp/plugin-normalize
这个 GIMP 文档中描述了我想要完成的规范化并在下面列出
来自 GIMP:8.10. Normalize
Normalize 命令缩放活动图层的亮度值,使最暗的点变黑,最亮的点变亮,而不改变其色调。对于暗淡或褪色的图像,这通常是一种“神奇修复”。 “标准化”适用于 RGB、灰度和索引图像的图层。
图像 normalization
也被称为 histogram stretching
选项 1
使用 D3.js
而不是 image-js 来完成这个任务,就像这个来源的代码
<!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>
选项 2
来自js-objectdetect you could write you own function using image-js, better explained in this answer
的8位单通道图像直方图均衡算法
/**
* Equalizes the histogram of an unsigned 1-channel image with values
* in range [0, 255]. Corresponds to the equalizeHist OpenCV function.
*
* @param {Array} src 1-channel source image
* @param {Array} [dst] 1-channel destination image. If omitted, the
* result is written to src (faster)
* @return {Array} Destination image
*/
equalizeHistogram = function(src, dst) {
var srcLength = src.length;
if (!dst) { dst = src; }
// Compute histogram and histogram sum:
var hist = new Float32Array(256);
var sum = 0;
for (var i = 0; i < srcLength; ++i) {
++hist[~~src[i]];
++sum;
}
// Compute integral histogram:
var prev = hist[0];
for (var i = 1; i < 256; ++i) {
prev = hist[i] += prev;
}
// Equalize image:
var norm = 255 / sum;
for (var i = 0; i < srcLength; ++i) {
dst[i] = hist[~~src[i]] * norm;
}
return dst;
}
我正在使用 image-js。
我查看了文档,但没有看到称为归一化或直方图拉伸的函数。但是我确实看到了一些直方图函数。我可以使用直方图函数对高度值的灰度 PNG 数组进行归一化吗?
图像数组是 0 - 255 范围内的高度值,黑色是最低高度,白色是最高。我正在使用此数组创建灰度高度图图像。
澄清一下:
归一化是指对图像颜色进行归一化,在本例中为灰度。喜欢这个项目,但使用 image-js https://www.npmjs.com/package/@jimp/plugin-normalize
这个 GIMP 文档中描述了我想要完成的规范化并在下面列出
来自 GIMP:8.10. Normalize
Normalize 命令缩放活动图层的亮度值,使最暗的点变黑,最亮的点变亮,而不改变其色调。对于暗淡或褪色的图像,这通常是一种“神奇修复”。 “标准化”适用于 RGB、灰度和索引图像的图层。
图像 normalization
也被称为 histogram stretching
选项 1
使用 D3.js
而不是 image-js 来完成这个任务,就像这个来源的代码
<!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>
选项 2
来自js-objectdetect you could write you own function using image-js, better explained in this answer
的8位单通道图像直方图均衡算法/**
* Equalizes the histogram of an unsigned 1-channel image with values
* in range [0, 255]. Corresponds to the equalizeHist OpenCV function.
*
* @param {Array} src 1-channel source image
* @param {Array} [dst] 1-channel destination image. If omitted, the
* result is written to src (faster)
* @return {Array} Destination image
*/
equalizeHistogram = function(src, dst) {
var srcLength = src.length;
if (!dst) { dst = src; }
// Compute histogram and histogram sum:
var hist = new Float32Array(256);
var sum = 0;
for (var i = 0; i < srcLength; ++i) {
++hist[~~src[i]];
++sum;
}
// Compute integral histogram:
var prev = hist[0];
for (var i = 1; i < 256; ++i) {
prev = hist[i] += prev;
}
// Equalize image:
var norm = 255 / sum;
for (var i = 0; i < srcLength; ++i) {
dst[i] = hist[~~src[i]] * norm;
}
return dst;
}