Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best RGB combination to convert image into Black and White "threshold"

I am required to build a simple application that converts a color image or a grayscale image into a black and white one, I was thinking looping through each pixel and checking the RGB values and if all of them are less than an specific value (lets say 20) redraw the pixel to black and if it is greater than that value, redraw the pixel to white. Something like this.

function blackWhite(context, canvas) {
    var imgData = context.getImageData(0, 0, canvas.width, canvas.height);
        var pixels  = imgData.data;
        for (var i = 0, n = pixels.length; i < n; i += 4) {
        if (pixels[i] <= 20 || pixels[i+1] <= 20 || pixels[i+2] <= 20){ 
              pixels[i  ] = 0;        // red
           pixels[i+1] = 0;        // green
           pixels[i+2] = 0;        // blue
        }else{
              pixels[i  ] = 255;        // red
           pixels[i+1] = 255;        // green
           pixels[i+2] = 255;        // blue
        }
    }
    //redraw the image in black & white
    context.putImageData(imgData, 0, 0);
  }

The big question is, what is the correct combination of Red, green and blue to define a pixel to be black, this taking into account that colors are perceived different by the human eye, as an example for our eyes it is more important the green color than the red and the blue, I’ve tried experimentally some values, but I don’t get close to a black and with image like the one you could get by digitalizing a sheet in an scanner as black and white.

Of course if there is a much faster way to do this, I will totally appreciate it.

like image 220
Oscar Muñoz Avatar asked Dec 14 '22 21:12

Oscar Muñoz


1 Answers

I believe what you're looking for is the relative luminance. While not the most advanced method of thresholding, it better follows the way humans perceive light, which is what I think you want.

https://en.wikipedia.org/wiki/Relative_luminance

From the wikipedia article the luminance can be calculated as follows:

let lum = .2126 * red + .7152 * green + .0722 * blue

This value will be some fraction of one so if you want to split it right in the middle use a threshold of .5

EDIT

The real issue comes with selecting the threshold. Not all images are lit the same way and a picture with more pixels with a low luminosity (i.e., more blacks) will benefit from a lower threshold. There's a couple techniques you can consider using such as analyzing the histogram of the image.

like image 115
Khauri Avatar answered Dec 21 '22 09:12

Khauri