Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you normalize an image (histogram stretching) using image-js and JavaScript?

I am using image-js.

I have looked at the documentation and I do not see a function called normalize or histogram stretching. However I do see some histogram functions. Can I use the histogram functions to do a normalization on a grayscale PNG array of height values?

The image array is values of heights from range 0 - 255 black being lowest height white highest. I am using this array to create a grayscale heightmap image.

Clarify:

By normalize I mean normalizing an image colors in this case the grayscale. Like this project but using image-js https://www.npmjs.com/package/@jimp/plugin-normalize

The normalization I want to accomplished is described in this GIMP doc and listed below

From GIMP: 8.10. Normalize

The Normalize command scales the brightness values of the active layer so that the darkest point becomes black and the brightest point becomes as bright as possible, without altering its hue. This is often a “magic fix” for images that are dim or washed out. “Normalize” works on layers from RGB, Grayscale, and Indexed images.

like image 348
dan Avatar asked Oct 16 '21 13:10

dan


People also ask

What is histogram stretching in image processing?

Histogram stretching involves modifying the brightness (intensity) values of pixels in the image according to some mapping function that specifies an output pixel brightness value for each input pixel brightness value. For a grayscale digital image, this process is straightforward.

Do we have histogram and histogram stretching in color images?

A. For an RGB color space digital image, histogram stretching can be accomplished by converting the image to a hue, saturation, intensity (HSI) color space representation of the image and applying the brightness mapping operation to the intensity information alone.

What is histogram stretching?

Histogram stretching involves modifying the brightness (intensity) values of pixels in the image according to some mapping function that specifies an output pixel brightness value for each input pixel brightness value. For a grayscale digital image, this process is straightforward.

How do I adjust image contrast in a histogram?

To adjust image contrast, use the mouse cursor to translate the Black Level and White Level sliders while observing results appearing in both the image and histogram windows. Alternatively, the blue arrow buttons can be activated with the mouse to incrementally move the sliders, either to the right or left.

What is the importance of histogram in image processing?

Histograms of digital images provide a graphical representation of image contrast characteristics and are useful in evaluating contrast deficiencies such as low or high contrast, or inadequate dynamic range. Manipulation of the histogram can correct poor contrast and brightness to dramatically improve the quality of digital images.

What is manipulation of histogram?

Manipulation of the histogram can correct poor contrast and brightness to dramatically improve the quality of digital images. Histogram stretching involves modifying the brightness (intensity) values of pixels in the image according to some mapping function that specifies an output pixel brightness value for each input pixel brightness value.


1 Answers

Image normalization is called also histogram stretching

Option 1

Use D3.js instead of image-js for this task, like tis code from this source

<!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>

Option 2

From this histogram equalization algorithm for 8-bit single channel images taken from js-objectdetect you could write you own function using image-js, better explained in this answer

/**
* 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;
}
like image 179
Jabbar Avatar answered Oct 16 '22 20:10

Jabbar